package handlers

import (
	"net/http"

	"github.com/gin-gonic/gin"
	"github.com/google/uuid"

	"github.com/breakpilot/ai-compliance-sdk/internal/rbac"
	"github.com/breakpilot/ai-compliance-sdk/internal/ucca"
)

// GetByRegulation returns obligations grouped by regulation
// GET /sdk/v1/ucca/obligations/:assessmentId/by-regulation
func (h *ObligationsHandlers) GetByRegulation(c *gin.Context) {
	tenantID := rbac.GetTenantID(c)
	assessmentID := c.Param("assessmentId")

	if h.store == nil {
		c.JSON(http.StatusNotImplemented, gin.H{"error": "Persistence not configured"})
		return
	}

	id, err := uuid.Parse(assessmentID)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid assessment ID"})
		return
	}

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

	grouped := h.registry.GroupByRegulation(assessment.Overview.Obligations)

	c.JSON(http.StatusOK, ucca.ObligationsByRegulationResponse{
		Regulations: grouped,
	})
}

// GetByDeadline returns obligations grouped by deadline timeframe
// GET /sdk/v1/ucca/obligations/:assessmentId/by-deadline
func (h *ObligationsHandlers) GetByDeadline(c *gin.Context) {
	tenantID := rbac.GetTenantID(c)
	assessmentID := c.Param("assessmentId")

	if h.store == nil {
		c.JSON(http.StatusNotImplemented, gin.H{"error": "Persistence not configured"})
		return
	}

	id, err := uuid.Parse(assessmentID)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid assessment ID"})
		return
	}

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

	grouped := h.registry.GroupByDeadline(assessment.Overview.Obligations)

	c.JSON(http.StatusOK, grouped)
}

// GetByResponsible returns obligations grouped by responsible role
// GET /sdk/v1/ucca/obligations/:assessmentId/by-responsible
func (h *ObligationsHandlers) GetByResponsible(c *gin.Context) {
	tenantID := rbac.GetTenantID(c)
	assessmentID := c.Param("assessmentId")

	if h.store == nil {
		c.JSON(http.StatusNotImplemented, gin.H{"error": "Persistence not configured"})
		return
	}

	id, err := uuid.Parse(assessmentID)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid assessment ID"})
		return
	}

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

	grouped := h.registry.GroupByResponsible(assessment.Overview.Obligations)

	c.JSON(http.StatusOK, ucca.ObligationsByResponsibleResponse{
		ByRole: grouped,
	})
}

// ListRegulations returns all available regulation modules
// GET /sdk/v1/ucca/obligations/regulations
func (h *ObligationsHandlers) ListRegulations(c *gin.Context) {
	modules := h.registry.ListModules()

	c.JSON(http.StatusOK, ucca.AvailableRegulationsResponse{
		Regulations: modules,
	})
}

// GetDecisionTree returns the decision tree for a specific regulation
// GET /sdk/v1/ucca/obligations/regulations/:regulationId/decision-tree
func (h *ObligationsHandlers) GetDecisionTree(c *gin.Context) {
	regulationID := c.Param("regulationId")

	tree, err := h.registry.GetDecisionTree(regulationID)
	if err != nil {
		c.JSON(http.StatusNotFound, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusOK, tree)
}

// GetTOMControlsForObligation returns TOM controls linked to an obligation
// GET /sdk/v1/ucca/obligations/:id/tom-controls
func (h *ObligationsHandlers) GetTOMControlsForObligation(c *gin.Context) {
	obligationID := c.Param("obligationId")

	if h.tomMapper == nil {
		c.JSON(http.StatusNotImplemented, gin.H{"error": "TOM mapping not available"})
		return
	}

	controls := h.tomMapper.GetControlsForObligation(obligationID)
	controlIDs := h.tomMapper.GetControlIDsForObligation(obligationID)

	c.JSON(http.StatusOK, gin.H{
		"obligation_id": obligationID,
		"control_ids":   controlIDs,
		"controls":      controls,
		"count":         len(controls),
	})
}

// GapAnalysis performs a TOM control gap analysis
// POST /sdk/v1/ucca/obligations/gap-analysis
func (h *ObligationsHandlers) GapAnalysis(c *gin.Context) {
	if h.gapAnalyzer == nil {
		c.JSON(http.StatusNotImplemented, gin.H{"error": "Gap analysis not available"})
		return
	}

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

	result := h.gapAnalyzer.Analyze(&req)
	c.JSON(http.StatusOK, result)
}

// GetObligationsForControl returns obligations linked to a TOM control
// GET /sdk/v1/ucca/obligations/tom-controls/:controlId/obligations
func (h *ObligationsHandlers) GetObligationsForControl(c *gin.Context) {
	controlID := c.Param("controlId")

	if h.tomMapper == nil {
		c.JSON(http.StatusNotImplemented, gin.H{"error": "TOM mapping not available"})
		return
	}

	obligationIDs := h.tomMapper.GetObligationsForControl(controlID)

	var control *ucca.TOMControl
	if h.tomIndex != nil {
		control, _ = h.tomIndex.GetControl(controlID)
	}

	c.JSON(http.StatusOK, gin.H{
		"control_id":     controlID,
		"control":        control,
		"obligation_ids": obligationIDs,
		"count":          len(obligationIDs),
	})
}
