package api

import (
	"net/http"
	"strconv"
	"strings"

	"github.com/gin-gonic/gin"

	"github.com/prism/proxy/internal/auth"
)

type createAPIKeyReq struct {
	Name string `json:"name"`
}

func (s *Server) listAPIKeys(c *gin.Context) {
	items, err := s.app.Store.ListAPIKeys(c.Request.Context())
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}
	c.JSON(http.StatusOK, gin.H{"items": items})
}

func (s *Server) createAPIKey(c *gin.Context) {
	var req createAPIKeyReq
	_ = c.ShouldBindJSON(&req)
	name := strings.TrimSpace(req.Name)
	if name == "" {
		name = "default"
	}

	raw, err := auth.GenerateAPIKey()
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	item, err := s.app.Store.CreateAPIKey(
		c.Request.Context(),
		name,
		auth.APIKeyDisplayPrefix(raw),
		auth.HashAPIKey(raw),
	)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}
	_ = s.app.Store.AddAuditLog(c.Request.Context(), "create", "api_key", name)

	c.JSON(http.StatusCreated, gin.H{
		"id":         item.ID,
		"name":       item.Name,
		"key":        raw,
		"key_prefix": item.KeyPrefix,
		"created_at": item.CreatedAt,
	})
}

func (s *Server) deleteAPIKey(c *gin.Context) {
	id, _ := strconv.ParseInt(c.Param("id"), 10, 64)
	if err := s.app.Store.DeleteAPIKey(c.Request.Context(), id); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}
	_ = s.app.Store.AddAuditLog(c.Request.Context(), "delete", "api_key", strconv.FormatInt(id, 10))
	c.JSON(http.StatusOK, gin.H{"ok": true})
}

func (s *Server) authorizeRequest(c *gin.Context, settings map[string]string) bool {
	if settings["auth_enabled"] != "true" {
		return true
	}

	ctx := c.Request.Context()
	if key := strings.TrimSpace(c.GetHeader("X-API-Key")); key != "" {
		if ok, _ := s.app.Store.VerifyAPIKey(ctx, auth.HashAPIKey(key)); ok {
			return true
		}
	}

	header := c.GetHeader("Authorization")
	if !strings.HasPrefix(header, "Bearer ") {
		return false
	}
	token := strings.TrimSpace(strings.TrimPrefix(header, "Bearer "))
	if token == "" {
		return false
	}
	if auth.IsAPIKeyFormat(token) {
		ok, _ := s.app.Store.VerifyAPIKey(ctx, auth.HashAPIKey(token))
		return ok
	}
	return verifyToken(settings["admin_password"], token)
}
