package main

import (
	"errors"
	"net/http"
	"strings"

	"fn-registry/functions/infra"
)

// POST /api/mcp-tokens {name}
//
// Mints a new MCP token for the current user. The plaintext token is returned
// ONLY in this response — there is no way to retrieve it again.
func handleCreateMCPToken(db *DB) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		userID, _ := infra.UserIDFromContext(r.Context(), userCtxKey)
		if userID == "" {
			infra.HTTPErrorResponse(w, infra.HTTPError{Status: http.StatusUnauthorized, Code: "unauthorized", Message: "login required"})
			return
		}
		var body struct {
			Name string `json:"name"`
		}
		if err := infra.HTTPParseBody(r, &body, maxBodyBytes); err != nil {
			badRequest(w, err.Error())
			return
		}
		name := strings.TrimSpace(body.Name)
		if name == "" {
			name = "default"
		}
		plaintext, tok, err := db.MintMCPToken(userID, name)
		if err != nil {
			serverError(w, err)
			return
		}
		infra.HTTPJSONResponse(w, http.StatusCreated, map[string]any{
			"id":         tok.ID,
			"name":       tok.Name,
			"created_at": tok.CreatedAt,
			"token":      plaintext,
		})
	}
}

// GET /api/mcp-tokens
func handleListMCPTokens(db *DB) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		userID, _ := infra.UserIDFromContext(r.Context(), userCtxKey)
		if userID == "" {
			infra.HTTPErrorResponse(w, infra.HTTPError{Status: http.StatusUnauthorized, Code: "unauthorized", Message: "login required"})
			return
		}
		tokens, err := db.ListMCPTokens(userID)
		if err != nil {
			serverError(w, err)
			return
		}
		infra.HTTPJSONResponse(w, http.StatusOK, tokens)
	}
}

// DELETE /api/mcp-tokens/{id}
func handleRevokeMCPToken(db *DB) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		userID, _ := infra.UserIDFromContext(r.Context(), userCtxKey)
		if userID == "" {
			infra.HTTPErrorResponse(w, infra.HTTPError{Status: http.StatusUnauthorized, Code: "unauthorized", Message: "login required"})
			return
		}
		id := r.PathValue("id")
		if err := db.RevokeMCPToken(userID, id); err != nil {
			if errors.Is(err, errMCPTokenNotFound) {
				notFound(w, "token not found")
				return
			}
			serverError(w, err)
			return
		}
		w.WriteHeader(http.StatusNoContent)
	}
}
