package ucca

import (
	"time"

	"github.com/google/uuid"
)

// ============================================================================
// Generic Obligations Framework
// ============================================================================
//
// This framework provides a regulation-agnostic way to derive and manage
// compliance obligations. Each regulation (DSGVO, NIS2, AI Act, etc.) is
// implemented as a separate module that conforms to the RegulationModule
// interface.
//
// Key principles:
//   - Deterministic: No LLM involvement in obligation derivation
//   - Transparent: Obligations are traceable to legal basis
//   - Composable: Regulations can be combined
//   - Auditable: Full traceability for compliance evidence
//
// ============================================================================

// ============================================================================
// Enums and Constants
// ============================================================================

// ObligationPriority represents the urgency of an obligation
type ObligationPriority string

const (
	PriorityCritical ObligationPriority = "critical"
	PriorityHigh     ObligationPriority = "high"
	PriorityMedium   ObligationPriority = "medium"
	PriorityLow      ObligationPriority = "low"
)

// ObligationCategory represents the type of obligation
type ObligationCategory string

const (
	CategoryMeldepflicht   ObligationCategory = "Meldepflicht"
	CategoryGovernance     ObligationCategory = "Governance"
	CategoryTechnical      ObligationCategory = "Technisch"
	CategoryOrganizational ObligationCategory = "Organisatorisch"
	CategoryDocumentation  ObligationCategory = "Dokumentation"
	CategoryTraining       ObligationCategory = "Schulung"
	CategoryAudit          ObligationCategory = "Audit"
	CategoryCompliance     ObligationCategory = "Compliance"
)

// ResponsibleRole represents who is responsible for an obligation
type ResponsibleRole string

const (
	RoleManagement          ResponsibleRole = "Geschäftsführung"
	RoleDSB                 ResponsibleRole = "Datenschutzbeauftragter"
	RoleCISO                ResponsibleRole = "CISO"
	RoleITLeitung           ResponsibleRole = "IT-Leitung"
	RoleCompliance          ResponsibleRole = "Compliance-Officer"
	RoleAIBeauftragter      ResponsibleRole = "KI-Beauftragter"
	RoleKIVerantwortlicher  ResponsibleRole = "KI-Verantwortlicher"
	RoleRiskManager         ResponsibleRole = "Risikomanager"
	RoleFachbereich         ResponsibleRole = "Fachbereichsleitung"
)

// DeadlineType represents the type of deadline
type DeadlineType string

const (
	DeadlineAbsolute DeadlineType = "absolute"
	DeadlineRelative DeadlineType = "relative"
	DeadlineRecurring DeadlineType = "recurring"
	DeadlineOnEvent  DeadlineType = "on_event"
)

// NIS2Classification represents NIS2 entity classification
type NIS2Classification string

const (
	NIS2NotAffected               NIS2Classification = "nicht_betroffen"
	NIS2ImportantEntity           NIS2Classification = "wichtige_einrichtung"
	NIS2EssentialEntity           NIS2Classification = "besonders_wichtige_einrichtung"
)

// ============================================================================
// Core Interfaces
// ============================================================================

// RegulationModule is the interface that all regulation modules must implement
type RegulationModule interface {
	// ID returns the unique identifier for this regulation (e.g., "nis2", "dsgvo")
	ID() string

	// Name returns the human-readable name (e.g., "NIS2-Richtlinie")
	Name() string

	// Description returns a brief description of the regulation
	Description() string

	// IsApplicable checks if this regulation applies to the given organization
	IsApplicable(facts *UnifiedFacts) bool

	// DeriveObligations derives all obligations based on the facts
	DeriveObligations(facts *UnifiedFacts) []Obligation

	// DeriveControls derives required controls based on the facts
	DeriveControls(facts *UnifiedFacts) []ObligationControl

	// GetDecisionTree returns the decision tree for this regulation (optional)
	GetDecisionTree() *DecisionTree

	// GetIncidentDeadlines returns incident reporting deadlines (optional)
	GetIncidentDeadlines(facts *UnifiedFacts) []IncidentDeadline

	// GetClassification returns the specific classification within this regulation
	GetClassification(facts *UnifiedFacts) string
}

// ============================================================================
// Core Data Structures
// ============================================================================

// LegalReference represents a reference to a specific legal provision
type LegalReference struct {
	Norm        string `json:"norm" yaml:"norm"`                                   // e.g., "Art. 28 DSGVO", "§ 33 BSIG-E"
	Article     string `json:"article,omitempty" yaml:"article,omitempty"`         // Article/paragraph number
	Title       string `json:"title,omitempty" yaml:"title,omitempty"`             // Title of the provision
	Description string `json:"description,omitempty" yaml:"description,omitempty"` // Brief description
	URL         string `json:"url,omitempty" yaml:"url,omitempty"`                 // Link to full text
}

// Deadline represents when an obligation must be fulfilled
type Deadline struct {
	Type     DeadlineType `json:"type" yaml:"type"`                               // absolute, relative, recurring, on_event
	Date     *time.Time   `json:"date,omitempty" yaml:"date,omitempty"`           // For absolute deadlines
	Duration string       `json:"duration,omitempty" yaml:"duration,omitempty"`   // For relative: "18 Monate nach Inkrafttreten"
	Event    string       `json:"event,omitempty" yaml:"event,omitempty"`         // For on_event: "Bei Sicherheitsvorfall"
	Interval string       `json:"interval,omitempty" yaml:"interval,omitempty"`   // For recurring: "jährlich", "quartalsweise"
}

// SanctionInfo represents potential sanctions for non-compliance
type SanctionInfo struct {
	MaxFine           string `json:"max_fine,omitempty" yaml:"max_fine,omitempty"`                       // e.g., "10 Mio. EUR oder 2% Jahresumsatz"
	MinFine           string `json:"min_fine,omitempty" yaml:"min_fine,omitempty"`                       // Minimum fine if applicable
	PersonalLiability bool   `json:"personal_liability" yaml:"personal_liability"`                       // Can management be held personally liable?
	CriminalLiability bool   `json:"criminal_liability" yaml:"criminal_liability"`                       // Can lead to criminal charges?
	Description       string `json:"description,omitempty" yaml:"description,omitempty"`                 // Additional description
}

// EvidenceItem represents what constitutes evidence of compliance
type EvidenceItem struct {
	ID          string `json:"id,omitempty" yaml:"id,omitempty"`
	Name        string `json:"name" yaml:"name"`                                   // e.g., "Registrierungsbestätigung BSI"
	Description string `json:"description,omitempty" yaml:"description,omitempty"` // What this evidence should contain
	Format      string `json:"format,omitempty" yaml:"format,omitempty"`           // e.g., "PDF", "Screenshot", "Protokoll"
	Required    bool   `json:"required" yaml:"required"`                           // Is this evidence mandatory?
}

// Obligation represents a single regulatory obligation
type Obligation struct {
	ID              string             `json:"id" yaml:"id"`                             // e.g., "NIS2-OBL-001"
	RegulationID    string             `json:"regulation_id" yaml:"regulation_id"`       // e.g., "nis2"
	Title           string             `json:"title" yaml:"title"`                       // e.g., "BSI-Registrierung"
	Description     string             `json:"description" yaml:"description"`           // Detailed description
	LegalBasis      []LegalReference   `json:"legal_basis" yaml:"legal_basis"`           // Legal references
	Category        ObligationCategory `json:"category" yaml:"category"`                 // Type of obligation
	Responsible     ResponsibleRole    `json:"responsible" yaml:"responsible"`           // Who is responsible
	Deadline        *Deadline          `json:"deadline,omitempty" yaml:"deadline,omitempty"`
	Sanctions       *SanctionInfo      `json:"sanctions,omitempty" yaml:"sanctions,omitempty"`
	Evidence        []EvidenceItem     `json:"evidence,omitempty" yaml:"evidence,omitempty"`
	Priority        ObligationPriority `json:"priority" yaml:"priority"`
	Dependencies    []string           `json:"dependencies,omitempty" yaml:"dependencies,omitempty"` // IDs of prerequisite obligations
	ISO27001Mapping []string           `json:"iso27001_mapping,omitempty" yaml:"iso27001_mapping,omitempty"`
	SOC2Mapping     []string           `json:"soc2_mapping,omitempty" yaml:"soc2_mapping,omitempty"`
	AppliesWhen     string             `json:"applies_when,omitempty" yaml:"applies_when,omitempty"` // Condition expression

	// Implementation guidance
	HowToImplement   string   `json:"how_to_implement,omitempty" yaml:"how_to_implement,omitempty"`
	BreakpilotFeature string  `json:"breakpilot_feature,omitempty" yaml:"breakpilot_feature,omitempty"`
	ExternalResources []string `json:"external_resources,omitempty" yaml:"external_resources,omitempty"`
}

// ObligationControl represents a required control/measure
type ObligationControl struct {
	ID               string           `json:"id" yaml:"id"`
	RegulationID     string           `json:"regulation_id" yaml:"regulation_id"`
	Name             string           `json:"name" yaml:"name"`
	Description      string           `json:"description" yaml:"description"`
	Category         string           `json:"category" yaml:"category"`
	WhenApplicable   string           `json:"when_applicable,omitempty" yaml:"when_applicable,omitempty"`
	WhatToDo         string           `json:"what_to_do" yaml:"what_to_do"`
	HowToImplement   string           `json:"how_to_implement,omitempty" yaml:"how_to_implement,omitempty"`
	EvidenceNeeded   []EvidenceItem   `json:"evidence_needed,omitempty" yaml:"evidence_needed,omitempty"`
	ISO27001Mapping  []string         `json:"iso27001_mapping,omitempty" yaml:"iso27001_mapping,omitempty"`
	BreakpilotFeature string          `json:"breakpilot_feature,omitempty" yaml:"breakpilot_feature,omitempty"`
	Priority         ObligationPriority `json:"priority" yaml:"priority"`
}

// IncidentDeadline represents a deadline for incident reporting
type IncidentDeadline struct {
	RegulationID string           `json:"regulation_id" yaml:"regulation_id"`
	Phase        string           `json:"phase" yaml:"phase"`             // e.g., "Erstmeldung", "Zwischenbericht"
	Deadline     string           `json:"deadline" yaml:"deadline"`       // e.g., "24 Stunden", "72 Stunden"
	Content      string           `json:"content" yaml:"content"`         // What must be reported
	Recipient    string           `json:"recipient" yaml:"recipient"`     // e.g., "BSI", "Aufsichtsbehörde"
	LegalBasis   []LegalReference `json:"legal_basis" yaml:"legal_basis"`
	AppliesWhen  string           `json:"applies_when,omitempty" yaml:"applies_when,omitempty"`
}

// DecisionTree represents a decision tree for determining applicability
type DecisionTree struct {
	ID       string                  `json:"id" yaml:"id"`
	Name     string                  `json:"name" yaml:"name"`
	RootNode *DecisionNode           `json:"root_node" yaml:"root_node"`
	Metadata map[string]interface{}  `json:"metadata,omitempty" yaml:"metadata,omitempty"`
}

// DecisionNode represents a node in a decision tree
type DecisionNode struct {
	ID          string                 `json:"id" yaml:"id"`
	Question    string                 `json:"question,omitempty" yaml:"question,omitempty"`
	Condition   *ConditionDef          `json:"condition,omitempty" yaml:"condition,omitempty"`
	YesNode     *DecisionNode          `json:"yes_node,omitempty" yaml:"yes_node,omitempty"`
	NoNode      *DecisionNode          `json:"no_node,omitempty" yaml:"no_node,omitempty"`
	Result      string                 `json:"result,omitempty" yaml:"result,omitempty"` // Terminal node result
	Explanation string                 `json:"explanation,omitempty" yaml:"explanation,omitempty"`
}

// ============================================================================
// Output Structures
// ============================================================================

// ApplicableRegulation represents a regulation that applies to the organization
type ApplicableRegulation struct {
	ID              string `json:"id"`               // e.g., "nis2"
	Name            string `json:"name"`             // e.g., "NIS2-Richtlinie"
	Classification  string `json:"classification"`   // e.g., "wichtige_einrichtung"
	Reason          string `json:"reason"`           // Why this regulation applies
	ObligationCount int    `json:"obligation_count"` // Number of derived obligations
	ControlCount    int    `json:"control_count"`    // Number of required controls
}

// SanctionsSummary aggregates sanction risks across all applicable regulations
type SanctionsSummary struct {
	MaxFinancialRisk     string   `json:"max_financial_risk"`     // Highest potential fine
	PersonalLiabilityRisk bool    `json:"personal_liability_risk"` // Any personal liability?
	CriminalLiabilityRisk bool    `json:"criminal_liability_risk"` // Any criminal liability?
	AffectedRegulations   []string `json:"affected_regulations"`    // Which regulations have sanctions
	Summary               string   `json:"summary"`                 // Human-readable summary
}

// ExecutiveSummary provides a C-level overview
type ExecutiveSummary struct {
	TotalRegulations        int      `json:"total_regulations"`
	TotalObligations        int      `json:"total_obligations"`
	CriticalObligations     int      `json:"critical_obligations"`
	UpcomingDeadlines       int      `json:"upcoming_deadlines"`       // Deadlines within 30 days
	OverdueObligations      int      `json:"overdue_obligations"`      // Past deadline
	KeyRisks                []string `json:"key_risks"`
	RecommendedActions      []string `json:"recommended_actions"`
	ComplianceScore         int      `json:"compliance_score"`         // 0-100
	NextReviewDate          *time.Time `json:"next_review_date,omitempty"`
}

// ManagementObligationsOverview is the main output structure for C-Level
type ManagementObligationsOverview struct {
	// Metadata
	ID               uuid.UUID  `json:"id"`
	TenantID         uuid.UUID  `json:"tenant_id"`
	OrganizationName string     `json:"organization_name"`
	AssessmentID     string     `json:"assessment_id,omitempty"`
	AssessmentDate   time.Time  `json:"assessment_date"`
	CreatedAt        time.Time  `json:"created_at"`
	UpdatedAt        time.Time  `json:"updated_at"`

	// Input facts summary
	FactsSummary    map[string]interface{} `json:"facts_summary,omitempty"`

	// Which regulations apply
	ApplicableRegulations []ApplicableRegulation `json:"applicable_regulations"`

	// All derived obligations (aggregated from all regulations)
	Obligations []Obligation `json:"obligations"`

	// All required controls
	RequiredControls []ObligationControl `json:"required_controls"`

	// Incident reporting deadlines
	IncidentDeadlines []IncidentDeadline `json:"incident_deadlines,omitempty"`

	// Aggregated sanction risks
	SanctionsSummary SanctionsSummary `json:"sanctions_summary"`

	// Executive summary for C-Level
	ExecutiveSummary ExecutiveSummary `json:"executive_summary"`

	// TOM Control Requirements (derived from obligations, v2)
	TOMControlRequirements []TOMControlRequirement `json:"tom_control_requirements,omitempty"`
}

// ============================================================================
// API Request/Response Types
// ============================================================================

// ObligationsAssessRequest is the API request for assessing obligations
type ObligationsAssessRequest struct {
	Facts            *UnifiedFacts `json:"facts"`
	OrganizationName string        `json:"organization_name,omitempty"`
}

// ObligationsAssessResponse is the API response for obligations assessment
type ObligationsAssessResponse struct {
	Overview *ManagementObligationsOverview `json:"overview"`
	Warnings []string                       `json:"warnings,omitempty"`
}

// ObligationsByRegulationResponse groups obligations by regulation
type ObligationsByRegulationResponse struct {
	Regulations map[string][]Obligation `json:"regulations"` // regulation_id -> obligations
}

// ObligationsByDeadlineResponse sorts obligations by deadline
type ObligationsByDeadlineResponse struct {
	Overdue       []Obligation `json:"overdue"`
	ThisWeek      []Obligation `json:"this_week"`
	ThisMonth     []Obligation `json:"this_month"`
	NextQuarter   []Obligation `json:"next_quarter"`
	Later         []Obligation `json:"later"`
	NoDeadline    []Obligation `json:"no_deadline"`
}

// ObligationsByResponsibleResponse groups obligations by responsible role
type ObligationsByResponsibleResponse struct {
	ByRole map[ResponsibleRole][]Obligation `json:"by_role"`
}

// AvailableRegulationsResponse lists all available regulation modules
type AvailableRegulationsResponse struct {
	Regulations []RegulationInfo `json:"regulations"`
}

// RegulationInfo provides info about a regulation module
type RegulationInfo struct {
	ID           string `json:"id"`
	Name         string `json:"name"`
	Description  string `json:"description"`
	Country      string `json:"country,omitempty"`      // e.g., "DE", "EU"
	EffectiveDate string `json:"effective_date,omitempty"`
}

// ExportMemoRequest is the request for exporting a C-Level memo
type ExportMemoRequest struct {
	AssessmentID string `json:"assessment_id"`
	Format       string `json:"format"` // "markdown" or "pdf"
	Language     string `json:"language,omitempty"` // "de" or "en", default "de"
}

// ExportMemoResponse contains the exported memo
type ExportMemoResponse struct {
	Content      string `json:"content"`       // Markdown or base64-encoded PDF
	ContentType  string `json:"content_type"`  // "text/markdown" or "application/pdf"
	Filename     string `json:"filename"`
	GeneratedAt  time.Time `json:"generated_at"`
}

// ============================================================================
// Database Entity for Persistence
// ============================================================================

// ObligationsAssessment represents a stored obligations assessment
type ObligationsAssessment struct {
	ID                    uuid.UUID                      `json:"id"`
	TenantID              uuid.UUID                      `json:"tenant_id"`
	OrganizationName      string                         `json:"organization_name"`
	Facts                 *UnifiedFacts                  `json:"facts"`
	Overview              *ManagementObligationsOverview `json:"overview"`
	Status                string                         `json:"status"` // "draft", "completed"
	CreatedAt             time.Time                      `json:"created_at"`
	UpdatedAt             time.Time                      `json:"updated_at"`
	CreatedBy             uuid.UUID                      `json:"created_by"`
}
