package training

import (
	"time"

	"github.com/google/uuid"
)

// ============================================================================
// Main Entities
// ============================================================================

// TrainingModule represents a compliance training module
type TrainingModule struct {
	ID              uuid.UUID      `json:"id"`
	TenantID        uuid.UUID      `json:"tenant_id"`
	AcademyCourseID *uuid.UUID     `json:"academy_course_id,omitempty"`
	ModuleCode      string         `json:"module_code"`
	Title           string         `json:"title"`
	Description     string         `json:"description,omitempty"`
	RegulationArea  RegulationArea `json:"regulation_area"`
	NIS2Relevant    bool           `json:"nis2_relevant"`
	ISOControls     []string       `json:"iso_controls"`       // JSONB
	FrequencyType   FrequencyType  `json:"frequency_type"`
	ValidityDays    int            `json:"validity_days"`
	RiskWeight      float64        `json:"risk_weight"`
	ContentType     string         `json:"content_type"`
	DurationMinutes int            `json:"duration_minutes"`
	PassThreshold   int            `json:"pass_threshold"`
	IsActive        bool           `json:"is_active"`
	SortOrder       int            `json:"sort_order"`
	CreatedAt       time.Time      `json:"created_at"`
	UpdatedAt       time.Time      `json:"updated_at"`
}

// TrainingMatrixEntry represents a role-to-module mapping in the CTM
type TrainingMatrixEntry struct {
	ID          uuid.UUID `json:"id"`
	TenantID    uuid.UUID `json:"tenant_id"`
	RoleCode    string    `json:"role_code"`
	ModuleID    uuid.UUID `json:"module_id"`
	IsMandatory bool      `json:"is_mandatory"`
	Priority    int       `json:"priority"`
	CreatedAt   time.Time `json:"created_at"`
	// Joined fields (optional, populated in queries)
	ModuleCode  string `json:"module_code,omitempty"`
	ModuleTitle string `json:"module_title,omitempty"`
}

// TrainingAssignment represents a user's training assignment
type TrainingAssignment struct {
	ID               uuid.UUID        `json:"id"`
	TenantID         uuid.UUID        `json:"tenant_id"`
	ModuleID         uuid.UUID        `json:"module_id"`
	UserID           uuid.UUID        `json:"user_id"`
	UserName         string           `json:"user_name"`
	UserEmail        string           `json:"user_email"`
	RoleCode         string           `json:"role_code,omitempty"`
	TriggerType      TriggerType      `json:"trigger_type"`
	TriggerEvent     string           `json:"trigger_event,omitempty"`
	Status           AssignmentStatus `json:"status"`
	ProgressPercent  int              `json:"progress_percent"`
	QuizScore        *float64         `json:"quiz_score,omitempty"`
	QuizPassed       *bool            `json:"quiz_passed,omitempty"`
	QuizAttempts     int              `json:"quiz_attempts"`
	StartedAt        *time.Time       `json:"started_at,omitempty"`
	CompletedAt      *time.Time       `json:"completed_at,omitempty"`
	Deadline         time.Time        `json:"deadline"`
	CertificateID    *uuid.UUID       `json:"certificate_id,omitempty"`
	EscalationLevel  int              `json:"escalation_level"`
	LastEscalationAt *time.Time       `json:"last_escalation_at,omitempty"`
	EnrollmentID     *uuid.UUID       `json:"enrollment_id,omitempty"`
	CreatedAt        time.Time        `json:"created_at"`
	UpdatedAt        time.Time        `json:"updated_at"`
	// Joined fields
	ModuleCode  string `json:"module_code,omitempty"`
	ModuleTitle string `json:"module_title,omitempty"`
}

// QuizQuestion represents a persistent quiz question for a module
type QuizQuestion struct {
	ID           uuid.UUID  `json:"id"`
	ModuleID     uuid.UUID  `json:"module_id"`
	Question     string     `json:"question"`
	Options      []string   `json:"options"`       // JSONB
	CorrectIndex int        `json:"correct_index"`
	Explanation  string     `json:"explanation,omitempty"`
	Difficulty   Difficulty `json:"difficulty"`
	IsActive     bool       `json:"is_active"`
	SortOrder    int        `json:"sort_order"`
	CreatedAt    time.Time  `json:"created_at"`
}

// QuizAttempt represents a single quiz attempt by a user
type QuizAttempt struct {
	ID              uuid.UUID    `json:"id"`
	AssignmentID    uuid.UUID    `json:"assignment_id"`
	UserID          uuid.UUID    `json:"user_id"`
	Answers         []QuizAnswer `json:"answers"`       // JSONB
	Score           float64      `json:"score"`
	Passed          bool         `json:"passed"`
	CorrectCount    int          `json:"correct_count"`
	TotalCount      int          `json:"total_count"`
	DurationSeconds *int         `json:"duration_seconds,omitempty"`
	AttemptedAt     time.Time    `json:"attempted_at"`
}

// QuizAnswer represents a single answer within a quiz attempt
type QuizAnswer struct {
	QuestionID    uuid.UUID `json:"question_id"`
	SelectedIndex int       `json:"selected_index"`
	Correct       bool      `json:"correct"`
}

// AuditLogEntry represents an entry in the training audit trail
type AuditLogEntry struct {
	ID         uuid.UUID              `json:"id"`
	TenantID   uuid.UUID              `json:"tenant_id"`
	UserID     *uuid.UUID             `json:"user_id,omitempty"`
	Action     AuditAction            `json:"action"`
	EntityType AuditEntityType        `json:"entity_type"`
	EntityID   *uuid.UUID             `json:"entity_id,omitempty"`
	Details    map[string]interface{} `json:"details"` // JSONB
	IPAddress  string                 `json:"ip_address,omitempty"`
	CreatedAt  time.Time              `json:"created_at"`
}

// ModuleContent represents LLM-generated or manual content for a module
type ModuleContent struct {
	ID            uuid.UUID     `json:"id"`
	ModuleID      uuid.UUID     `json:"module_id"`
	Version       int           `json:"version"`
	ContentFormat ContentFormat `json:"content_format"`
	ContentBody   string        `json:"content_body"`
	Summary       string        `json:"summary,omitempty"`
	GeneratedBy   string        `json:"generated_by,omitempty"`
	LLMModel      string        `json:"llm_model,omitempty"`
	IsPublished   bool          `json:"is_published"`
	ReviewedBy    *uuid.UUID    `json:"reviewed_by,omitempty"`
	ReviewedAt    *time.Time    `json:"reviewed_at,omitempty"`
	CreatedAt     time.Time     `json:"created_at"`
	UpdatedAt     time.Time     `json:"updated_at"`
}

// TrainingStats contains aggregated training metrics
type TrainingStats struct {
	TotalModules      int     `json:"total_modules"`
	TotalAssignments  int     `json:"total_assignments"`
	CompletionRate    float64 `json:"completion_rate"`
	OverdueCount      int     `json:"overdue_count"`
	PendingCount      int     `json:"pending_count"`
	InProgressCount   int     `json:"in_progress_count"`
	CompletedCount    int     `json:"completed_count"`
	AvgQuizScore      float64 `json:"avg_quiz_score"`
	AvgCompletionDays float64 `json:"avg_completion_days"`
	UpcomingDeadlines int     `json:"upcoming_deadlines"` // within 7 days
}

// ComplianceGap represents a missing or overdue training requirement
type ComplianceGap struct {
	ModuleID       uuid.UUID      `json:"module_id"`
	ModuleCode     string         `json:"module_code"`
	ModuleTitle    string         `json:"module_title"`
	RegulationArea RegulationArea `json:"regulation_area"`
	RoleCode       string         `json:"role_code"`
	IsMandatory    bool           `json:"is_mandatory"`
	AssignmentID   *uuid.UUID     `json:"assignment_id,omitempty"`
	Status         string         `json:"status"` // "missing", "overdue", "expired"
	Deadline       *time.Time     `json:"deadline,omitempty"`
}

// EscalationResult represents the result of an escalation check
type EscalationResult struct {
	AssignmentID    uuid.UUID `json:"assignment_id"`
	UserID          uuid.UUID `json:"user_id"`
	UserName        string    `json:"user_name"`
	UserEmail       string    `json:"user_email"`
	ModuleTitle     string    `json:"module_title"`
	PreviousLevel   int       `json:"previous_level"`
	NewLevel        int       `json:"new_level"`
	DaysOverdue     int       `json:"days_overdue"`
	EscalationLabel string    `json:"escalation_label"`
}

// DeadlineInfo represents upcoming deadline information
type DeadlineInfo struct {
	AssignmentID uuid.UUID        `json:"assignment_id"`
	ModuleCode   string           `json:"module_code"`
	ModuleTitle  string           `json:"module_title"`
	UserID       uuid.UUID        `json:"user_id"`
	UserName     string           `json:"user_name"`
	Deadline     time.Time        `json:"deadline"`
	DaysLeft     int              `json:"days_left"`
	Status       AssignmentStatus `json:"status"`
}

// ============================================================================
// Filter Types
// ============================================================================

// ModuleFilters defines filters for listing modules
type ModuleFilters struct {
	RegulationArea RegulationArea
	FrequencyType  FrequencyType
	IsActive       *bool
	NIS2Relevant   *bool
	Search         string
	Limit          int
	Offset         int
}

// AssignmentFilters defines filters for listing assignments
type AssignmentFilters struct {
	ModuleID *uuid.UUID
	UserID   *uuid.UUID
	RoleCode string
	Status   AssignmentStatus
	Overdue  *bool
	Limit    int
	Offset   int
}

// AuditLogFilters defines filters for listing audit log entries
type AuditLogFilters struct {
	UserID     *uuid.UUID
	Action     AuditAction
	EntityType AuditEntityType
	Limit      int
	Offset     int
}

// CanonicalControlSummary is a lightweight view on canonical_controls for the training pipeline
type CanonicalControlSummary struct {
	ControlID      string   `json:"control_id"`
	Title          string   `json:"title"`
	Objective      string   `json:"objective"`
	Rationale      string   `json:"rationale"`
	Requirements   []string `json:"requirements"`
	Severity       string   `json:"severity"`
	Category       string   `json:"category"`
	TargetAudience string   `json:"target_audience"`
	Tags           []string `json:"tags"`
}

// CanonicalControlMeta provides aggregated metadata about canonical controls
type CanonicalControlMeta struct {
	Domains    []DomainCount   `json:"domains"`
	Categories []CategoryCount `json:"categories"`
	Audiences  []AudienceCount `json:"audiences"`
	Total      int             `json:"total"`
}

// DomainCount is a domain with its control count
type DomainCount struct {
	Domain string `json:"domain"`
	Count  int    `json:"count"`
}

// CategoryCount is a category with its control count
type CategoryCount struct {
	Category string `json:"category"`
	Count    int    `json:"count"`
}

// AudienceCount is a target audience with its control count
type AudienceCount struct {
	Audience string `json:"audience"`
	Count    int    `json:"count"`
}

// BulkResult holds the result of a bulk generation operation
type BulkResult struct {
	Generated int      `json:"generated"`
	Skipped   int      `json:"skipped"`
	Errors    []string `json:"errors"`
}
