// PARTIAL DEPRECATED — CRUD-Overlap mit Python backend-compliance
//
// Die folgenden CRUD-Endpoints sind deprecated, da Python (obligation_routes.py)
// nun als Primary fuer List/Create/Update/Delete dient:
//   - ListObligations, CreateObligation, GetObligation, UpdateObligation, DeleteObligation
//
// AKTIV bleiben (einzigartige AI-Features ohne Python-Aequivalent):
//   - AssessFromScope, RunGapAnalysis, ExportAssessment, ExportDirect
//   - ListAssessments, GetAssessment, UpdateAssessment
//   - TOM-Controls: ListTOMControls, MapTOMControls, GetTOMGapAnalysis
//   - GetObligationsByFramework, GetFrameworks
//
// Go-Routen werden NICHT entfernt (Abwaertskompatibilitaet), aber Frontend
// nutzt Python-Backend fuer alle CRUD-Operationen.
package handlers

import (
	"fmt"
	"net/http"
	"time"

	"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"
)

// ObligationsHandlers handles API requests for the generic obligations framework
type ObligationsHandlers struct {
	registry    *ucca.ObligationsRegistry
	store       *ucca.ObligationsStore // Optional: for persisting assessments
	tomIndex    *ucca.TOMControlIndex
	tomMapper   *ucca.TOMObligationMapper
	gapAnalyzer *ucca.TOMGapAnalyzer
}

// NewObligationsHandlers creates a new ObligationsHandlers instance
func NewObligationsHandlers() *ObligationsHandlers {
	h := &ObligationsHandlers{
		registry: ucca.NewObligationsRegistry(),
	}
	h.initTOM()
	return h
}

// NewObligationsHandlersWithStore creates a new ObligationsHandlers with a store
func NewObligationsHandlersWithStore(store *ucca.ObligationsStore) *ObligationsHandlers {
	h := &ObligationsHandlers{
		registry: ucca.NewObligationsRegistry(),
		store:    store,
	}
	h.initTOM()
	return h
}

// initTOM initializes TOM control index, mapper, and gap analyzer
func (h *ObligationsHandlers) initTOM() {
	tomIndex, err := ucca.LoadTOMControls()
	if err != nil {
		fmt.Printf("Warning: Could not load TOM controls: %v\n", err)
		return
	}
	h.tomIndex = tomIndex

	mapping, err := ucca.LoadV2TOMMapping()
	if err != nil {
		regs, err2 := ucca.LoadAllV2Regulations()
		if err2 == nil {
			var allObligations []ucca.V2Obligation
			for _, reg := range regs {
				allObligations = append(allObligations, reg.Obligations...)
			}
			h.tomMapper = ucca.NewTOMObligationMapperFromObligations(tomIndex, allObligations)
		}
	} else {
		h.tomMapper = ucca.NewTOMObligationMapper(tomIndex, mapping)
	}

	if h.tomMapper != nil {
		h.gapAnalyzer = ucca.NewTOMGapAnalyzer(h.tomMapper, tomIndex)
	}
}

// RegisterRoutes registers all obligations-related routes
func (h *ObligationsHandlers) RegisterRoutes(r *gin.RouterGroup) {
	obligations := r.Group("/obligations")
	{
		obligations.POST("/assess", h.AssessObligations)
		obligations.GET("/:assessmentId", h.GetAssessment)

		obligations.GET("/:assessmentId/by-regulation", h.GetByRegulation)
		obligations.GET("/:assessmentId/by-deadline", h.GetByDeadline)
		obligations.GET("/:assessmentId/by-responsible", h.GetByResponsible)

		obligations.POST("/export/memo", h.ExportMemo)
		obligations.POST("/export/direct", h.ExportMemoFromOverview)

		obligations.GET("/regulations", h.ListRegulations)
		obligations.GET("/regulations/:regulationId/decision-tree", h.GetDecisionTree)

		obligations.POST("/quick-check", h.QuickCheck)

		obligations.POST("/assess-from-scope", h.AssessFromScope)

		obligations.GET("/tom-controls/for-obligation/:obligationId", h.GetTOMControlsForObligation)
		obligations.POST("/gap-analysis", h.GapAnalysis)
		obligations.GET("/tom-controls/:controlId/obligations", h.GetObligationsForControl)
	}
}

// AssessObligations assesses which obligations apply based on provided facts
// POST /sdk/v1/ucca/obligations/assess
func (h *ObligationsHandlers) AssessObligations(c *gin.Context) {
	tenantID := rbac.GetTenantID(c)
	if tenantID == uuid.Nil {
		c.JSON(http.StatusUnauthorized, gin.H{"error": "Tenant ID required"})
		return
	}

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

	if req.Facts == nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "Facts are required"})
		return
	}

	overview := h.registry.EvaluateAll(tenantID, req.Facts, req.OrganizationName)

	var warnings []string
	if len(overview.ApplicableRegulations) == 0 {
		warnings = append(warnings, "Keine der konfigurierten Regulierungen scheint anwendbar zu sein. Bitte prüfen Sie die eingegebenen Daten.")
	}
	if overview.ExecutiveSummary.OverdueObligations > 0 {
		warnings = append(warnings, "Es gibt überfällige Pflichten, die sofortige Aufmerksamkeit erfordern.")
	}

	if h.store != nil {
		assessment := &ucca.ObligationsAssessment{
			ID:               overview.ID,
			TenantID:         tenantID,
			OrganizationName: req.OrganizationName,
			Facts:            req.Facts,
			Overview:         overview,
			Status:           "completed",
			CreatedAt:        time.Now(),
			UpdatedAt:        time.Now(),
			CreatedBy:        rbac.GetUserID(c),
		}
		if err := h.store.CreateAssessment(c.Request.Context(), assessment); err != nil {
			c.Set("store_error", err.Error())
		}
	}

	c.JSON(http.StatusOK, ucca.ObligationsAssessResponse{
		Overview: overview,
		Warnings: warnings,
	})
}

// GetAssessment retrieves a stored assessment by ID
// GET /sdk/v1/ucca/obligations/:assessmentId
func (h *ObligationsHandlers) GetAssessment(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
	}

	c.JSON(http.StatusOK, assessment.Overview)
}

// QuickCheck performs a quick obligations check without persistence
// POST /sdk/v1/ucca/obligations/quick-check
func (h *ObligationsHandlers) QuickCheck(c *gin.Context) {
	var req struct {
		EmployeeCount          int      `json:"employee_count"`
		AnnualRevenue          float64  `json:"annual_revenue"`
		BalanceSheetTotal      float64  `json:"balance_sheet_total,omitempty"`
		Country                string   `json:"country"`
		PrimarySector          string   `json:"primary_sector"`
		SpecialServices        []string `json:"special_services,omitempty"`
		IsKRITIS               bool     `json:"is_kritis,omitempty"`
		ProcessesPersonalData  bool     `json:"processes_personal_data,omitempty"`
		UsesAI                 bool     `json:"uses_ai,omitempty"`
		IsFinancialInstitution bool     `json:"is_financial_institution,omitempty"`
	}

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

	facts := &ucca.UnifiedFacts{
		Organization: ucca.OrganizationFacts{
			EmployeeCount:     req.EmployeeCount,
			AnnualRevenue:     req.AnnualRevenue,
			BalanceSheetTotal: req.BalanceSheetTotal,
			Country:           req.Country,
			EUMember:          isEUCountry(req.Country),
		},
		Sector: ucca.SectorFacts{
			PrimarySector:          req.PrimarySector,
			SpecialServices:        req.SpecialServices,
			IsKRITIS:               req.IsKRITIS,
			KRITISThresholdMet:     req.IsKRITIS,
			IsFinancialInstitution: req.IsFinancialInstitution,
		},
		DataProtection: ucca.DataProtectionFacts{
			ProcessesPersonalData: req.ProcessesPersonalData,
		},
		AIUsage: ucca.AIUsageFacts{
			UsesAI: req.UsesAI,
		},
		Financial: ucca.FinancialFacts{
			IsRegulated: req.IsFinancialInstitution,
		},
	}

	tenantID := rbac.GetTenantID(c)
	if tenantID == uuid.Nil {
		tenantID = uuid.New()
	}

	overview := h.registry.EvaluateAll(tenantID, facts, "")

	c.JSON(http.StatusOK, gin.H{
		"applicable_regulations": overview.ApplicableRegulations,
		"total_obligations":      len(overview.Obligations),
		"critical_obligations":   overview.ExecutiveSummary.CriticalObligations,
		"sanctions_summary":      overview.SanctionsSummary,
		"executive_summary":      overview.ExecutiveSummary,
	})
}

// AssessFromScope assesses obligations from a ScopeDecision
// POST /sdk/v1/ucca/obligations/assess-from-scope
func (h *ObligationsHandlers) AssessFromScope(c *gin.Context) {
	tenantID := rbac.GetTenantID(c)
	if tenantID == uuid.Nil {
		tenantID = uuid.New()
	}

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

	facts := ucca.MapScopeToFacts(&scope)
	overview := h.registry.EvaluateAll(tenantID, facts, "")

	if h.tomMapper != nil {
		overview.TOMControlRequirements = h.tomMapper.DeriveControlsFromObligations(overview.Obligations)
	}

	var warnings []string
	if len(overview.ApplicableRegulations) == 0 {
		warnings = append(warnings, "Keine anwendbaren Regulierungen gefunden. Pruefen Sie die Scope-Angaben.")
	}

	c.JSON(http.StatusOK, ucca.ObligationsAssessResponse{
		Overview: overview,
		Warnings: warnings,
	})
}
