package handlers

import (
	"net/http"

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

// ============================================================================
// CE x Compliance Crossover Engine
// ============================================================================

// GetComplianceTriggers handles GET /projects/:id/compliance-triggers.
// It analyses the project's hazards and component patterns to determine
// which DSGVO, AI Act, CRA, NIS2, and EU Data Act obligations are triggered.
// The response includes deduplicated triggers sorted by severity, plus boolean
// summary flags (dsfa_required, ai_act_relevant, cra_relevant, etc.).
func (h *IACEHandler) GetComplianceTriggers(c *gin.Context) {
	projectID, err := uuid.Parse(c.Param("id"))
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "invalid project ID"})
		return
	}

	// Verify project exists
	project, err := h.store.GetProject(c.Request.Context(), projectID)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}
	if project == nil {
		c.JSON(http.StatusNotFound, gin.H{"error": "project not found"})
		return
	}

	// Fetch all hazards for this project
	hazards, err := h.store.ListHazards(c.Request.Context(), projectID)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to load hazards: " + err.Error()})
		return
	}

	// Also run pattern matching with component tags to catch tag-based triggers.
	// Collect tags from the project's components (reuse the norms handler logic).
	componentTags := collectComponentTags(h, c, projectID)

	// Get all patterns from the pattern library
	allPatterns := iace.AllPatterns()

	// Additionally derive extra fired patterns by re-matching component tags
	// against the pattern engine. This ensures patterns that are not yet
	// applied as hazards still contribute their compliance triggers.
	engine := iace.NewPatternEngine()
	matchInput := iace.MatchInput{
		CustomTags: componentTags,
	}
	matchResult := engine.Match(matchInput)

	// Merge matched pattern IDs into a pseudo-hazard list so the crossover
	// engine picks them up. We create lightweight Hazard structs with the
	// pattern ID embedded in the Description field.
	mergedHazards := make([]iace.Hazard, len(hazards))
	copy(mergedHazards, hazards)
	for _, pm := range matchResult.MatchedPatterns {
		mergedHazards = append(mergedHazards, iace.Hazard{
			Name:        pm.PatternName,
			Description: "Pattern " + pm.PatternID,
			Category:    firstOrEmpty(pm.HazardCats),
		})
	}

	// Run the crossover engine
	summary := iace.GetProjectComplianceTriggers(mergedHazards, allPatterns)

	c.JSON(http.StatusOK, summary)
}

// GetComplianceFAQ handles GET /compliance-faq
// Returns CE × Compliance FAQ entries, optionally filtered by ?category=
func (h *IACEHandler) GetComplianceFAQ(c *gin.Context) {
	category := c.Query("category")
	all := iace.GetComplianceFAQ()

	if category != "" {
		var filtered []iace.ComplianceFAQEntry
		for _, f := range all {
			if f.Category == category {
				filtered = append(filtered, f)
			}
		}
		c.JSON(http.StatusOK, gin.H{"faq": filtered, "total": len(filtered)})
		return
	}

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

// firstOrEmpty returns the first element of a string slice or "".
func firstOrEmpty(ss []string) string {
	if len(ss) > 0 {
		return ss[0]
	}
	return ""
}
