package api

import (
	"net/http"

	"git.fabledsword.com/bvandeusen/minstrel/internal/apierror"
	"git.fabledsword.com/bvandeusen/minstrel/internal/audit"
	"git.fabledsword.com/bvandeusen/minstrel/internal/auth"
	"git.fabledsword.com/bvandeusen/minstrel/internal/db/dbq"
)

type apiTokenResp struct {
	APIToken string `json:"api_token"`
}

// handleGetMyAPIToken implements GET /api/me/api-token.
func (h *handlers) handleGetMyAPIToken(w http.ResponseWriter, r *http.Request) {
	user, ok := requireUser(w, r)
	if !ok {
		return
	}
	q := dbq.New(h.pool)
	current, err := q.GetUserByID(r.Context(), user.ID)
	if err != nil {
		h.logger.Error("get api token: lookup failed", "err", err)
		writeErr(w, apierror.Internal(err))
		return
	}
	writeJSON(w, http.StatusOK, apiTokenResp{APIToken: current.ApiToken})
}

// handleRegenerateMyAPIToken implements POST /api/me/api-token.
func (h *handlers) handleRegenerateMyAPIToken(w http.ResponseWriter, r *http.Request) {
	user, ok := requireUser(w, r)
	if !ok {
		return
	}
	newToken, err := auth.MintSessionToken()
	if err != nil {
		h.logger.Error("regenerate api token: mint failed", "err", err)
		writeErr(w, apierror.Internal(err))
		return
	}
	q := dbq.New(h.pool)
	updated, err := q.RegenerateApiToken(r.Context(), dbq.RegenerateApiTokenParams{
		ID:       user.ID,
		ApiToken: newToken,
	})
	if err != nil {
		h.logger.Error("regenerate api token: update failed", "err", err)
		writeErr(w, apierror.Internal(err))
		return
	}

	audit.WriteOrLog(r.Context(), h.pool, h.logger, user.ID, user.ID, audit.ActionTokenRegenerate, nil)

	writeJSON(w, http.StatusOK, apiTokenResp{APIToken: updated.ApiToken})
}
