package handlers

import (
	"net/http"

	"github.com/breakpilot/ai-compliance-sdk/internal/ucca"
	"github.com/gin-gonic/gin"
	"github.com/google/uuid"
)

// RegistrationHandlers handles EU AI Database registration endpoints
type RegistrationHandlers struct {
	store     *ucca.RegistrationStore
	uccaStore *ucca.Store
}

// NewRegistrationHandlers creates new registration handlers
func NewRegistrationHandlers(store *ucca.RegistrationStore, uccaStore *ucca.Store) *RegistrationHandlers {
	return &RegistrationHandlers{store: store, uccaStore: uccaStore}
}

// Create creates a new registration
func (h *RegistrationHandlers) Create(c *gin.Context) {
	var reg ucca.AIRegistration
	if err := c.ShouldBindJSON(&reg); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request: " + err.Error()})
		return
	}

	tenantID, _ := uuid.Parse(c.GetHeader("X-Tenant-ID"))
	if tenantID == uuid.Nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "tenant ID required"})
		return
	}
	reg.TenantID = tenantID

	if reg.SystemName == "" {
		c.JSON(http.StatusBadRequest, gin.H{"error": "system_name required"})
		return
	}

	if err := h.store.Create(c.Request.Context(), &reg); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to create registration: " + err.Error()})
		return
	}

	c.JSON(http.StatusCreated, reg)
}

// List lists all registrations for the tenant
func (h *RegistrationHandlers) List(c *gin.Context) {
	tenantID, _ := uuid.Parse(c.GetHeader("X-Tenant-ID"))
	if tenantID == uuid.Nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "tenant ID required"})
		return
	}

	registrations, err := h.store.List(c.Request.Context(), tenantID)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to list registrations: " + err.Error()})
		return
	}
	if registrations == nil {
		registrations = []ucca.AIRegistration{}
	}

	c.JSON(http.StatusOK, gin.H{"registrations": registrations, "total": len(registrations)})
}

// Get returns a single registration
func (h *RegistrationHandlers) Get(c *gin.Context) {
	id, err := uuid.Parse(c.Param("id"))
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid ID"})
		return
	}

	reg, err := h.store.GetByID(c.Request.Context(), id)
	if err != nil {
		c.JSON(http.StatusNotFound, gin.H{"error": "Registration not found"})
		return
	}

	c.JSON(http.StatusOK, reg)
}

// Update updates a registration
func (h *RegistrationHandlers) Update(c *gin.Context) {
	id, err := uuid.Parse(c.Param("id"))
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid ID"})
		return
	}

	existing, err := h.store.GetByID(c.Request.Context(), id)
	if err != nil {
		c.JSON(http.StatusNotFound, gin.H{"error": "Registration not found"})
		return
	}

	var updates ucca.AIRegistration
	if err := c.ShouldBindJSON(&updates); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request: " + err.Error()})
		return
	}

	// Merge updates into existing
	updates.ID = existing.ID
	updates.TenantID = existing.TenantID
	updates.CreatedAt = existing.CreatedAt

	if err := h.store.Update(c.Request.Context(), &updates); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to update: " + err.Error()})
		return
	}

	c.JSON(http.StatusOK, updates)
}

// UpdateStatus changes the registration status
func (h *RegistrationHandlers) UpdateStatus(c *gin.Context) {
	id, err := uuid.Parse(c.Param("id"))
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid ID"})
		return
	}

	var body struct {
		Status      string `json:"status"`
		SubmittedBy string `json:"submitted_by"`
	}
	if err := c.ShouldBindJSON(&body); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request"})
		return
	}

	validStatuses := map[string]bool{
		"draft": true, "ready": true, "submitted": true,
		"registered": true, "update_required": true, "withdrawn": true,
	}
	if !validStatuses[body.Status] {
		c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid status. Valid: draft, ready, submitted, registered, update_required, withdrawn"})
		return
	}

	if err := h.store.UpdateStatus(c.Request.Context(), id, body.Status, body.SubmittedBy); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to update status: " + err.Error()})
		return
	}

	c.JSON(http.StatusOK, gin.H{"id": id, "status": body.Status})
}

// Prefill creates a registration pre-filled from a UCCA assessment
func (h *RegistrationHandlers) Prefill(c *gin.Context) {
	assessmentID, err := uuid.Parse(c.Param("assessment_id"))
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid assessment ID"})
		return
	}

	tenantID, _ := uuid.Parse(c.GetHeader("X-Tenant-ID"))
	if tenantID == uuid.Nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "tenant ID required"})
		return
	}

	// Load UCCA assessment
	assessment, err := h.uccaStore.GetAssessment(c.Request.Context(), assessmentID)
	if err != nil {
		c.JSON(http.StatusNotFound, gin.H{"error": "Assessment not found"})
		return
	}

	// Pre-fill registration from assessment intake
	intake := assessment.Intake

	reg := ucca.AIRegistration{
		TenantID:           tenantID,
		SystemName:         intake.Title,
		SystemDescription:  intake.UseCaseText,
		IntendedPurpose:    intake.UseCaseText,
		RiskClassification: string(assessment.RiskLevel),
		GPAIClassification: "none",
		RegistrationStatus: "draft",
		UCCAAssessmentID:   &assessmentID,
	}

	// Map domain to readable text
	if intake.Domain != "" {
		reg.IntendedPurpose = string(intake.Domain) + ": " + intake.UseCaseText
	}

	c.JSON(http.StatusOK, reg)
}

// Export generates the EU AI Database submission JSON
func (h *RegistrationHandlers) Export(c *gin.Context) {
	id, err := uuid.Parse(c.Param("id"))
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid ID"})
		return
	}

	reg, err := h.store.GetByID(c.Request.Context(), id)
	if err != nil {
		c.JSON(http.StatusNotFound, gin.H{"error": "Registration not found"})
		return
	}

	exportJSON := h.store.BuildExportJSON(reg)

	// Save export data to DB
	reg.ExportData = exportJSON
	h.store.Update(c.Request.Context(), reg)

	c.Header("Content-Type", "application/json")
	c.Header("Content-Disposition", "attachment; filename=eu_ai_registration_"+reg.SystemName+".json")
	c.Data(http.StatusOK, "application/json", exportJSON)
}
