package handlers

import (
	"context"
	"net/http"

	"github.com/Fimeg/RedFlag/aggregator-server/internal/database/queries"
	"github.com/Fimeg/RedFlag/aggregator-server/internal/services"
	"github.com/Fimeg/RedFlag/aggregator-server/internal/version"
	"github.com/gin-gonic/gin"
)

// SystemHandler handles system-level operations
type SystemHandler struct {
	signingService    *services.SigningService
	signingKeyQueries *queries.SigningKeyQueries
}

// NewSystemHandler creates a new system handler
func NewSystemHandler(ss *services.SigningService, skq *queries.SigningKeyQueries) *SystemHandler {
	return &SystemHandler{
		signingService:    ss,
		signingKeyQueries: skq,
	}
}

// GetPublicKey returns the server's Ed25519 public key for signature verification.
// This allows agents to fetch the public key at runtime instead of embedding it at build time.
func (h *SystemHandler) GetPublicKey(c *gin.Context) {
	if h.signingService == nil || !h.signingService.IsEnabled() {
		c.JSON(http.StatusServiceUnavailable, gin.H{
			"error": "signing service not configured",
			"hint":  "Set REDFLAG_SIGNING_PRIVATE_KEY environment variable",
		})
		return
	}

	pubKeyHex := h.signingService.GetPublicKey()
	fingerprint := h.signingService.GetPublicKeyFingerprint()
	keyID := h.signingService.GetCurrentKeyID()

	// Try to get version from DB; fall back to 1 if unavailable
	version := 1
	if h.signingKeyQueries != nil {
		ctx := context.Background()
		if primaryKey, err := h.signingKeyQueries.GetPrimarySigningKey(ctx); err == nil {
			version = primaryKey.Version
		}
	}

	c.JSON(http.StatusOK, gin.H{
		"public_key":  pubKeyHex,
		"fingerprint": fingerprint,
		"algorithm":   "ed25519",
		"key_size":    32,
		"key_id":      keyID,
		"version":     version,
	})
}

// GetActivePublicKeys returns all currently active public keys for key-rotation-aware agents.
// This is a rate-limited public endpoint — no authentication required.
func (h *SystemHandler) GetActivePublicKeys(c *gin.Context) {
	if h.signingService == nil || !h.signingService.IsEnabled() {
		c.JSON(http.StatusServiceUnavailable, gin.H{
			"error": "signing service not configured",
		})
		return
	}

	ctx := c.Request.Context()
	activeKeys, err := h.signingService.GetAllActivePublicKeys(ctx)

	// Build response — always return at least the current key
	type keyEntry struct {
		KeyID     string `json:"key_id"`
		PublicKey string `json:"public_key"`
		IsPrimary bool   `json:"is_primary"`
		Version   int    `json:"version"`
		Algorithm string `json:"algorithm"`
	}

	if err != nil || len(activeKeys) == 0 {
		// Fall back to single-entry response with current key
		c.JSON(http.StatusOK, []keyEntry{
			{
				KeyID:     h.signingService.GetCurrentKeyID(),
				PublicKey: h.signingService.GetPublicKeyHex(),
				IsPrimary: true,
				Version:   1,
				Algorithm: "ed25519",
			},
		})
		return
	}

	entries := make([]keyEntry, 0, len(activeKeys))
	for _, k := range activeKeys {
		entries = append(entries, keyEntry{
			KeyID:     k.KeyID,
			PublicKey: k.PublicKey,
			IsPrimary: k.IsPrimary,
			Version:   k.Version,
			Algorithm: k.Algorithm,
		})
	}

	c.JSON(http.StatusOK, entries)
}

// GetSystemInfo returns general system information
func (h *SystemHandler) GetSystemInfo(c *gin.Context) {
	versions := version.GetCurrentVersions()
	c.JSON(http.StatusOK, gin.H{
		"version":              versions.AgentVersion,
		"latest_agent_version": versions.AgentVersion,
		"min_agent_version":    versions.MinAgentVersion,
		"name":                 "RedFlag Aggregator",
		"description":          "Self-hosted update management platform",
		"features": []string{
			"agent_management",
			"update_tracking",
			"command_execution",
			"ed25519_signing",
			"key_rotation",
		},
	})
}
