package handler

import (
	"encoding/json"
	"net/http"

	"freeleaps.com/gitea-webhook-ambassador/internal/auth"
	"freeleaps.com/gitea-webhook-ambassador/internal/config"
	"freeleaps.com/gitea-webhook-ambassador/internal/database"
	"freeleaps.com/gitea-webhook-ambassador/internal/logger"
)

// AdminHandler handles administrative API endpoints
type AdminHandler struct {
	db     *database.DB
	config *config.Configuration
	auth   *auth.Middleware
}

// NewAdminHandler creates a new admin handler
func NewAdminHandler(db *database.DB, config *config.Configuration) *AdminHandler {
	return &AdminHandler{
		db:     db,
		config: config,
		auth:   auth.NewMiddleware(config.Server.SecretKey),
	}
}

// CreateAPIKeyRequest represents a request to create a new API key
type CreateAPIKeyRequest struct {
	Key         string `json:"key"`
	Description string `json:"description"`
}

// APIKeyResponse represents an API key response
type APIKeyResponse struct {
	ID          int64  `json:"id"`
	Key         string `json:"key"`
	Description string `json:"description"`
	CreatedAt   string `json:"created_at"`
	UpdatedAt   string `json:"updated_at"`
}

// verifyAuth verifies the JWT token in the request
func (h *AdminHandler) verifyAuth(r *http.Request) error {
	return h.auth.VerifyToken(r)
}

// HandleCreateAPIKey handles the creation of new API keys
func (h *AdminHandler) HandleCreateAPIKey(w http.ResponseWriter, r *http.Request) {
	// Verify JWT token
	if err := h.verifyAuth(r); err != nil {
		http.Error(w, "Unauthorized", http.StatusUnauthorized)
		return
	}

	// Parse request
	var req CreateAPIKeyRequest
	if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
		http.Error(w, "Invalid request body", http.StatusBadRequest)
		return
	}

	// Validate request
	if req.Key == "" {
		http.Error(w, "API key is required", http.StatusBadRequest)
		return
	}

	// Create API key
	apiKey := &database.APIKey{
		Key:         req.Key,
		Description: req.Description,
	}

	if err := h.db.CreateAPIKey(apiKey); err != nil {
		logger.Error("Failed to create API key: %v", err)
		http.Error(w, "Internal server error", http.StatusInternalServerError)
		return
	}

	// Return response
	response := APIKeyResponse{
		ID:          apiKey.ID,
		Key:         apiKey.Key,
		Description: apiKey.Description,
		CreatedAt:   apiKey.CreatedAt.Format("2006-01-02T15:04:05Z07:00"),
		UpdatedAt:   apiKey.UpdatedAt.Format("2006-01-02T15:04:05Z07:00"),
	}

	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(response)
}

// HandleDeleteAPIKey handles the deletion of API keys
func (h *AdminHandler) HandleDeleteAPIKey(w http.ResponseWriter, r *http.Request) {
	// Verify JWT token
	if err := h.verifyAuth(r); err != nil {
		http.Error(w, "Unauthorized", http.StatusUnauthorized)
		return
	}

	// Get key from URL
	key := r.URL.Query().Get("key")
	if key == "" {
		http.Error(w, "API key is required", http.StatusBadRequest)
		return
	}

	// Delete API key
	if err := h.db.DeleteAPIKey(key); err != nil {
		logger.Error("Failed to delete API key: %v", err)
		http.Error(w, "Internal server error", http.StatusInternalServerError)
		return
	}

	w.WriteHeader(http.StatusNoContent)
}

// HandleListAPIKeys handles listing all API keys
func (h *AdminHandler) HandleListAPIKeys(w http.ResponseWriter, r *http.Request) {
	// Verify JWT token
	if err := h.verifyAuth(r); err != nil {
		http.Error(w, "Unauthorized", http.StatusUnauthorized)
		return
	}

	// Get API keys
	apiKeys, err := h.db.GetAPIKeys()
	if err != nil {
		logger.Error("Failed to get API keys: %v", err)
		http.Error(w, "Internal server error", http.StatusInternalServerError)
		return
	}

	// Convert to response format
	response := make([]APIKeyResponse, len(apiKeys))
	for i, key := range apiKeys {
		response[i] = APIKeyResponse{
			ID:          key.ID,
			Key:         key.Key,
			Description: key.Description,
			CreatedAt:   key.CreatedAt.Format("2006-01-02T15:04:05Z07:00"),
			UpdatedAt:   key.UpdatedAt.Format("2006-01-02T15:04:05Z07:00"),
		}
	}

	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(response)
}
