package funding

import (
	"time"

	"github.com/google/uuid"
)

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

// FundingProgram represents the type of funding program
type FundingProgram string

const (
	FundingProgramDigitalPakt1       FundingProgram = "DIGITALPAKT_1"
	FundingProgramDigitalPakt2       FundingProgram = "DIGITALPAKT_2"
	FundingProgramLandesfoerderung   FundingProgram = "LANDESFOERDERUNG"
	FundingProgramSchultraeger       FundingProgram = "SCHULTRAEGER"
	FundingProgramSonstige           FundingProgram = "SONSTIGE"
)

// ApplicationStatus represents the workflow status
type ApplicationStatus string

const (
	ApplicationStatusDraft      ApplicationStatus = "DRAFT"
	ApplicationStatusInProgress ApplicationStatus = "IN_PROGRESS"
	ApplicationStatusReview     ApplicationStatus = "REVIEW"
	ApplicationStatusSubmitted  ApplicationStatus = "SUBMITTED"
	ApplicationStatusApproved   ApplicationStatus = "APPROVED"
	ApplicationStatusRejected   ApplicationStatus = "REJECTED"
	ApplicationStatusArchived   ApplicationStatus = "ARCHIVED"
)

// FederalState represents German federal states
type FederalState string

const (
	FederalStateNI  FederalState = "NI"  // Niedersachsen
	FederalStateNRW FederalState = "NRW" // Nordrhein-Westfalen
	FederalStateBAY FederalState = "BAY" // Bayern
	FederalStateBW  FederalState = "BW"  // Baden-Wuerttemberg
	FederalStateHE  FederalState = "HE"  // Hessen
	FederalStateSN  FederalState = "SN"  // Sachsen
	FederalStateTH  FederalState = "TH"  // Thueringen
	FederalStateSA  FederalState = "SA"  // Sachsen-Anhalt
	FederalStateBB  FederalState = "BB"  // Brandenburg
	FederalStateMV  FederalState = "MV"  // Mecklenburg-Vorpommern
	FederalStateSH  FederalState = "SH"  // Schleswig-Holstein
	FederalStateHH  FederalState = "HH"  // Hamburg
	FederalStateHB  FederalState = "HB"  // Bremen
	FederalStateBE  FederalState = "BE"  // Berlin
	FederalStateSL  FederalState = "SL"  // Saarland
	FederalStateRP  FederalState = "RP"  // Rheinland-Pfalz
)

// SchoolType represents different school types
type SchoolType string

const (
	SchoolTypeGrundschule        SchoolType = "GRUNDSCHULE"
	SchoolTypeHauptschule        SchoolType = "HAUPTSCHULE"
	SchoolTypeRealschule         SchoolType = "REALSCHULE"
	SchoolTypeGymnasium          SchoolType = "GYMNASIUM"
	SchoolTypeGesamtschule       SchoolType = "GESAMTSCHULE"
	SchoolTypeOberschule         SchoolType = "OBERSCHULE"
	SchoolTypeFoerderschule      SchoolType = "FOERDERSCHULE"
	SchoolTypeBerufsschule       SchoolType = "BERUFSSCHULE"
	SchoolTypeBerufskolleg       SchoolType = "BERUFSKOLLEG"
	SchoolTypeFachoberschule     SchoolType = "FACHOBERSCHULE"
	SchoolTypeBerufliches        SchoolType = "BERUFLICHES_GYMNASIUM"
	SchoolTypeSonstige           SchoolType = "SONSTIGE"
)

// CarrierType represents the school carrier type
type CarrierType string

const (
	CarrierTypePublic    CarrierType = "PUBLIC"     // Oeffentlich
	CarrierTypePrivate   CarrierType = "PRIVATE"    // Privat
	CarrierTypeChurch    CarrierType = "CHURCH"     // Kirchlich
	CarrierTypeNonProfit CarrierType = "NON_PROFIT" // Gemeinnuetzig
)

// BudgetCategory represents categories for budget items
type BudgetCategory string

const (
	BudgetCategoryNetwork      BudgetCategory = "NETWORK"      // Netzwerk/Verkabelung
	BudgetCategoryWLAN         BudgetCategory = "WLAN"         // WLAN-Infrastruktur
	BudgetCategoryDevices      BudgetCategory = "DEVICES"      // Endgeraete
	BudgetCategoryPresentation BudgetCategory = "PRESENTATION" // Praesentationstechnik
	BudgetCategorySoftware     BudgetCategory = "SOFTWARE"     // Software-Lizenzen
	BudgetCategoryServer       BudgetCategory = "SERVER"       // Server/Rechenzentrum
	BudgetCategoryServices     BudgetCategory = "SERVICES"     // Dienstleistungen
	BudgetCategoryTraining     BudgetCategory = "TRAINING"     // Schulungen
	BudgetCategorySonstige     BudgetCategory = "SONSTIGE"     // Sonstige
)

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

// FundingApplication represents a funding application
type FundingApplication struct {
	ID                uuid.UUID         `json:"id"`
	TenantID          uuid.UUID         `json:"tenant_id"`
	ApplicationNumber string            `json:"application_number"` // e.g., DP2-NI-2026-00123
	Title             string            `json:"title"`
	FundingProgram    FundingProgram    `json:"funding_program"`
	Status            ApplicationStatus `json:"status"`

	// Wizard State
	CurrentStep int                    `json:"current_step"`
	TotalSteps  int                    `json:"total_steps"`
	WizardData  map[string]interface{} `json:"wizard_data,omitempty"`

	// School Information
	SchoolProfile *SchoolProfile `json:"school_profile,omitempty"`

	// Project Information
	ProjectPlan *ProjectPlan     `json:"project_plan,omitempty"`
	Budget      *Budget          `json:"budget,omitempty"`
	Timeline    *ProjectTimeline `json:"timeline,omitempty"`

	// Financial Summary
	RequestedAmount float64  `json:"requested_amount"`
	OwnContribution float64  `json:"own_contribution"`
	ApprovedAmount  *float64 `json:"approved_amount,omitempty"`

	// Attachments
	Attachments []Attachment `json:"attachments,omitempty"`

	// Audit Trail
	CreatedAt   time.Time  `json:"created_at"`
	UpdatedAt   time.Time  `json:"updated_at"`
	SubmittedAt *time.Time `json:"submitted_at,omitempty"`
	CreatedBy   uuid.UUID  `json:"created_by"`
	UpdatedBy   uuid.UUID  `json:"updated_by"`
}

// SchoolProfile contains school information
type SchoolProfile struct {
	Name           string       `json:"name"`
	SchoolNumber   string       `json:"school_number"`   // Official school number
	Type           SchoolType   `json:"type"`
	FederalState   FederalState `json:"federal_state"`
	Address        Address      `json:"address"`
	ContactPerson  ContactPerson `json:"contact_person"`
	StudentCount   int          `json:"student_count"`
	TeacherCount   int          `json:"teacher_count"`
	ClassCount     int          `json:"class_count"`
	CarrierType    CarrierType  `json:"carrier_type"`
	CarrierName    string       `json:"carrier_name"`
	CarrierAddress *Address     `json:"carrier_address,omitempty"`
	Infrastructure *InfrastructureStatus `json:"infrastructure,omitempty"`
}

// Address represents a postal address
type Address struct {
	Street     string `json:"street"`
	HouseNo    string `json:"house_no"`
	PostalCode string `json:"postal_code"`
	City       string `json:"city"`
	Country    string `json:"country,omitempty"`
}

// ContactPerson represents a contact person
type ContactPerson struct {
	Salutation string `json:"salutation,omitempty"` // Herr/Frau
	Title      string `json:"title,omitempty"`      // Dr., Prof.
	FirstName  string `json:"first_name"`
	LastName   string `json:"last_name"`
	Position   string `json:"position,omitempty"` // Schulleitung, IT-Beauftragter
	Email      string `json:"email"`
	Phone      string `json:"phone,omitempty"`
}

// InfrastructureStatus describes current IT infrastructure
type InfrastructureStatus struct {
	HasWLAN           bool   `json:"has_wlan"`
	WLANCoverage      int    `json:"wlan_coverage"`       // Percentage 0-100
	HasStructuredCabling bool `json:"has_structured_cabling"`
	InternetBandwidth string `json:"internet_bandwidth"`  // e.g., "100 Mbit/s"
	DeviceCount       int    `json:"device_count"`        // Current devices
	HasServerRoom     bool   `json:"has_server_room"`
	Notes             string `json:"notes,omitempty"`
}

// ProjectPlan describes the project
type ProjectPlan struct {
	ProjectName       string `json:"project_name"`
	Summary           string `json:"summary"`           // Kurzbeschreibung
	Goals             string `json:"goals"`             // Projektziele
	DidacticConcept   string `json:"didactic_concept"`  // Paedagogisches Konzept
	MEPReference      string `json:"mep_reference,omitempty"` // Medienentwicklungsplan Bezug
	DataProtection    string `json:"data_protection"`   // Datenschutzkonzept
	MaintenancePlan   string `json:"maintenance_plan"`  // Wartungs-/Betriebskonzept
	TargetGroups      []string `json:"target_groups"`   // e.g., ["Schueler", "Lehrer"]
	SubjectsAffected  []string `json:"subjects_affected,omitempty"` // Betroffene Faecher
}

// Budget represents the financial plan
type Budget struct {
	TotalCost        float64      `json:"total_cost"`
	RequestedFunding float64      `json:"requested_funding"`
	OwnContribution  float64      `json:"own_contribution"`
	OtherFunding     float64      `json:"other_funding"`
	FundingRate      float64      `json:"funding_rate"` // 0.90 = 90%
	BudgetItems      []BudgetItem `json:"budget_items"`
	IsWithinLimits   bool         `json:"is_within_limits"`
	Justification    string       `json:"justification,omitempty"` // Begruendung
}

// BudgetItem represents a single budget line item
type BudgetItem struct {
	ID            uuid.UUID      `json:"id"`
	Position      int            `json:"position"`       // Order number
	Category      BudgetCategory `json:"category"`
	Description   string         `json:"description"`
	Manufacturer  string         `json:"manufacturer,omitempty"`
	ProductName   string         `json:"product_name,omitempty"`
	Quantity      int            `json:"quantity"`
	UnitPrice     float64        `json:"unit_price"`
	TotalPrice    float64        `json:"total_price"`
	IsFundable    bool           `json:"is_fundable"`    // Foerderfahig Ja/Nein
	FundingSource string         `json:"funding_source"` // digitalpakt, eigenanteil, sonstige
	Notes         string         `json:"notes,omitempty"`
}

// ProjectTimeline represents project schedule
type ProjectTimeline struct {
	PlannedStart time.Time   `json:"planned_start"`
	PlannedEnd   time.Time   `json:"planned_end"`
	Milestones   []Milestone `json:"milestones,omitempty"`
	ProjectPhase string      `json:"project_phase,omitempty"` // Current phase
}

// Milestone represents a project milestone
type Milestone struct {
	ID          uuid.UUID  `json:"id"`
	Title       string     `json:"title"`
	Description string     `json:"description,omitempty"`
	DueDate     time.Time  `json:"due_date"`
	CompletedAt *time.Time `json:"completed_at,omitempty"`
	Status      string     `json:"status"` // planned, in_progress, completed
}

// Attachment represents an uploaded file
type Attachment struct {
	ID           uuid.UUID `json:"id"`
	FileName     string    `json:"file_name"`
	FileType     string    `json:"file_type"` // pdf, docx, xlsx, jpg, png
	FileSize     int64     `json:"file_size"` // bytes
	Category     string    `json:"category"`  // angebot, mep, nachweis, sonstiges
	Description  string    `json:"description,omitempty"`
	StoragePath  string    `json:"-"` // Internal path, not exposed
	UploadedAt   time.Time `json:"uploaded_at"`
	UploadedBy   uuid.UUID `json:"uploaded_by"`
}

// ============================================================================
// Wizard Step Data
// ============================================================================

// WizardStep represents a single wizard step
type WizardStep struct {
	Number       int      `json:"number"`
	Title        string   `json:"title"`
	Description  string   `json:"description"`
	Fields       []string `json:"fields"`       // Field IDs for this step
	IsCompleted  bool     `json:"is_completed"`
	IsRequired   bool     `json:"is_required"`
	HelpContext  string   `json:"help_context"` // Context for LLM assistant
}

// WizardProgress tracks wizard completion
type WizardProgress struct {
	CurrentStep     int                    `json:"current_step"`
	TotalSteps      int                    `json:"total_steps"`
	CompletedSteps  []int                  `json:"completed_steps"`
	StepValidation  map[int][]string       `json:"step_validation,omitempty"`  // Errors per step
	FormData        map[string]interface{} `json:"form_data"`
	LastSavedAt     time.Time              `json:"last_saved_at"`
}

// ============================================================================
// BreakPilot Presets
// ============================================================================

// ProductPreset represents a BreakPilot product preset
type ProductPreset struct {
	ID           string        `json:"id"`
	Name         string        `json:"name"`
	Description  string        `json:"description"`
	BudgetItems  []BudgetItem  `json:"budget_items"`
	AutoFill     map[string]interface{} `json:"auto_fill"`
	DataProtection string      `json:"data_protection"`
}

// ============================================================================
// Export Structures
// ============================================================================

// ExportDocument represents a generated document
type ExportDocument struct {
	Type         string    `json:"type"`          // antragsschreiben, kostenplan, datenschutz
	Format       string    `json:"format"`        // pdf, docx, xlsx
	FileName     string    `json:"file_name"`
	GeneratedAt  time.Time `json:"generated_at"`
	ContentHash  string    `json:"content_hash"`
	StoragePath  string    `json:"-"`
}

// ExportBundle represents a ZIP bundle of all documents
type ExportBundle struct {
	ID           uuid.UUID        `json:"id"`
	ApplicationID uuid.UUID       `json:"application_id"`
	Documents    []ExportDocument `json:"documents"`
	GeneratedAt  time.Time        `json:"generated_at"`
	DownloadURL  string           `json:"download_url"`
	ExpiresAt    time.Time        `json:"expires_at"`
}

// ============================================================================
// LLM Assistant
// ============================================================================

// AssistantMessage represents a chat message with the assistant
type AssistantMessage struct {
	Role    string `json:"role"`    // user, assistant, system
	Content string `json:"content"`
	Step    int    `json:"step,omitempty"` // Current wizard step
}

// AssistantRequest for asking questions
type AssistantRequest struct {
	ApplicationID uuid.UUID          `json:"application_id"`
	Question      string             `json:"question"`
	CurrentStep   int                `json:"current_step"`
	Context       map[string]interface{} `json:"context,omitempty"`
	History       []AssistantMessage `json:"history,omitempty"`
}

// AssistantResponse from the assistant
type AssistantResponse struct {
	Answer     string            `json:"answer"`
	Suggestions []string         `json:"suggestions,omitempty"`
	References []string          `json:"references,omitempty"` // Links to help resources
	FormFills  map[string]interface{} `json:"form_fills,omitempty"` // Suggested form values
}

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

// CreateApplicationRequest for creating a new application
type CreateApplicationRequest struct {
	Title          string         `json:"title"`
	FundingProgram FundingProgram `json:"funding_program"`
	FederalState   FederalState   `json:"federal_state"`
	PresetID       string         `json:"preset_id,omitempty"` // Optional BreakPilot preset
}

// UpdateApplicationRequest for updating an application
type UpdateApplicationRequest struct {
	Title       *string                `json:"title,omitempty"`
	WizardData  map[string]interface{} `json:"wizard_data,omitempty"`
	CurrentStep *int                   `json:"current_step,omitempty"`
}

// SaveWizardStepRequest for saving a wizard step
type SaveWizardStepRequest struct {
	Step     int                    `json:"step"`
	Data     map[string]interface{} `json:"data"`
	Complete bool                   `json:"complete"` // Mark step as complete
}

// ApplicationListResponse for list endpoints
type ApplicationListResponse struct {
	Applications []FundingApplication `json:"applications"`
	Total        int                  `json:"total"`
	Page         int                  `json:"page"`
	PageSize     int                  `json:"page_size"`
}

// ExportRequest for export endpoints
type ExportRequest struct {
	Format    string   `json:"format"`    // zip, pdf, docx
	Documents []string `json:"documents"` // Which documents to include
	Language  string   `json:"language"`  // de, en
}
