package ucca

import "strings"

// CompanyProfileInput contains the regulatory-relevant subset of a company profile.
// Mirrors the Python CompanyProfileRequest schema for the fields that affect assessment.
type CompanyProfileInput struct {
	CompanyName         string   `json:"company_name,omitempty"`
	LegalForm           string   `json:"legal_form,omitempty"`
	Industry            string   `json:"industry,omitempty"`
	EmployeeCount       string   `json:"employee_count,omitempty"`      // "1-9", "10-49", "50-249", "250-999", "1000+"
	AnnualRevenue       string   `json:"annual_revenue,omitempty"`      // "< 2 Mio", "2-10 Mio", "10-50 Mio", "50+ Mio"
	HeadquartersCountry string   `json:"headquarters_country,omitempty"`
	IsDataController    bool     `json:"is_data_controller"`
	IsDataProcessor     bool     `json:"is_data_processor"`
	UsesAI              bool     `json:"uses_ai"`
	AIUseCases          []string `json:"ai_use_cases,omitempty"`
	DPOName             *string  `json:"dpo_name,omitempty"`
	SubjectToNIS2       bool     `json:"subject_to_nis2"`
	SubjectToAIAct      bool     `json:"subject_to_ai_act"`
	SubjectToISO27001   bool     `json:"subject_to_iso27001"`
}

// EnrichmentHint tells the frontend which missing company data would improve the assessment.
type EnrichmentHint struct {
	Field      string `json:"field"`
	Label      string `json:"label"`
	Impact     string `json:"impact"`
	Regulation string `json:"regulation"`
	Priority   string `json:"priority"` // "high", "medium", "low"
}

// CompanyContextSummary is a compact view of the company's regulatory position.
type CompanyContextSummary struct {
	SizeCategory   string `json:"size_category"`
	NIS2Applicable bool   `json:"nis2_applicable"`
	DPORequired    bool   `json:"dpo_required"`
	Sector         string `json:"sector"`
	Country        string `json:"country"`
}

// MapCompanyProfileToFacts converts a company profile to UnifiedFacts.
func MapCompanyProfileToFacts(profile *CompanyProfileInput) *UnifiedFacts {
	if profile == nil {
		return NewUnifiedFacts()
	}

	facts := NewUnifiedFacts()

	// Organization
	facts.Organization.Name = profile.CompanyName
	facts.Organization.LegalForm = profile.LegalForm
	facts.Organization.EmployeeCount = parseEmployeeRangeGo(profile.EmployeeCount)
	facts.Organization.AnnualRevenue = parseRevenueRangeGo(profile.AnnualRevenue)
	if profile.HeadquartersCountry != "" {
		facts.Organization.Country = profile.HeadquartersCountry
	}
	facts.Organization.EUMember = isEUCountry(profile.HeadquartersCountry)
	facts.Organization.CalculateSizeCategory()

	// Sector
	if profile.Industry != "" {
		facts.MapDomainToSector(mapIndustryToDomain(profile.Industry))
	}

	// Data Protection
	facts.DataProtection.IsController = profile.IsDataController
	facts.DataProtection.IsProcessor = profile.IsDataProcessor
	facts.DataProtection.ProcessesPersonalData = true // assumed for all compliance customers
	facts.DataProtection.OffersToEU = facts.Organization.EUMember

	// DPO requirement: BDSG §6 — ≥20 employees processing personal data in DE
	if facts.Organization.Country == "DE" && facts.Organization.EmployeeCount >= 20 && facts.DataProtection.ProcessesPersonalData {
		facts.DataProtection.RequiresDSBByLaw = true
	}

	// Personnel
	if profile.DPOName != nil && *profile.DPOName != "" {
		facts.Personnel.HasDPO = true
	}

	// AI Usage
	facts.AIUsage.UsesAI = profile.UsesAI
	if len(profile.AIUseCases) > 0 {
		facts.AIUsage.IsAIDeployer = true
	}

	// IT Security
	facts.ITSecurity.ISO27001Certified = profile.SubjectToISO27001

	// NIS2 flags
	if profile.SubjectToNIS2 {
		if facts.Sector.NIS2Classification == "" {
			facts.Sector.NIS2Classification = "wichtige_einrichtung"
		}
	}

	return facts
}

// MergeCompanyFactsIntoIntakeFacts merges company-level facts with use-case-level facts.
// Company wins for: Organization, Sector, Personnel, Financial, ITSecurity, SupplyChain.
// Intake wins for: DataProtection details, AIUsage details, UCCAFacts.
func MergeCompanyFactsIntoIntakeFacts(companyFacts, intakeFacts *UnifiedFacts) *UnifiedFacts {
	if companyFacts == nil {
		return intakeFacts
	}
	if intakeFacts == nil {
		return companyFacts
	}

	merged := NewUnifiedFacts()

	// Company-level fields (from company profile)
	merged.Organization = companyFacts.Organization
	merged.Sector = companyFacts.Sector
	merged.Personnel = companyFacts.Personnel
	merged.Financial = companyFacts.Financial
	merged.ITSecurity = companyFacts.ITSecurity
	merged.SupplyChain = companyFacts.SupplyChain

	// Use-case-level fields (from intake)
	merged.DataProtection = intakeFacts.DataProtection
	merged.AIUsage = intakeFacts.AIUsage
	merged.UCCAFacts = intakeFacts.UCCAFacts

	// Preserve company-level data protection facts that intake doesn't override
	merged.DataProtection.IsController = companyFacts.DataProtection.IsController
	merged.DataProtection.IsProcessor = companyFacts.DataProtection.IsProcessor
	merged.DataProtection.RequiresDSBByLaw = companyFacts.DataProtection.RequiresDSBByLaw
	merged.DataProtection.OffersToEU = companyFacts.DataProtection.OffersToEU

	// Preserve company AI flags alongside intake AI flags
	if companyFacts.AIUsage.UsesAI {
		merged.AIUsage.UsesAI = true
	}

	return merged
}

// ComputeEnrichmentHints returns hints for fields that would improve the assessment.
func ComputeEnrichmentHints(profile *CompanyProfileInput) []EnrichmentHint {
	if profile == nil {
		return allCriticalHints()
	}

	var hints []EnrichmentHint

	if profile.EmployeeCount == "" {
		hints = append(hints, EnrichmentHint{
			Field: "employee_count", Label: "Mitarbeiterzahl",
			Impact: "NIS2-Schwellenwert (>=50 MA) und BDSG DPO-Pflicht (>=20 MA in DE) koennen nicht geprueft werden",
			Regulation: "NIS2, BDSG §6", Priority: "high",
		})
	}

	if profile.AnnualRevenue == "" {
		hints = append(hints, EnrichmentHint{
			Field: "annual_revenue", Label: "Jahresumsatz",
			Impact: "NIS2-Schwellenwert (>=10 Mio EUR) und KMU-Einstufung nicht pruefbar",
			Regulation: "NIS2, EU KMU-Definition", Priority: "high",
		})
	}

	if profile.Industry == "" {
		hints = append(hints, EnrichmentHint{
			Field: "industry", Label: "Branche",
			Impact: "NIS2 Annex I/II Sektor-Klassifikation und AI Act Hochrisiko-Sektoren nicht bestimmbar",
			Regulation: "NIS2, AI Act Annex III", Priority: "high",
		})
	}

	if profile.HeadquartersCountry == "" {
		hints = append(hints, EnrichmentHint{
			Field: "headquarters_country", Label: "Land des Hauptsitzes",
			Impact: "BDSG-spezifische Regeln (z.B. HR-Daten §26 BDSG) koennen nicht angewandt werden",
			Regulation: "BDSG", Priority: "medium",
		})
	}

	if profile.DPOName == nil || *profile.DPOName == "" {
		hints = append(hints, EnrichmentHint{
			Field: "dpo_name", Label: "Datenschutzbeauftragter",
			Impact: "DPO-Pflicht kann nicht gegen vorhandene Benennung abgeglichen werden",
			Regulation: "DSGVO Art. 37, BDSG §6", Priority: "medium",
		})
	}

	return hints
}

// BuildCompanyContext creates a summary of the company's regulatory position.
func BuildCompanyContext(profile *CompanyProfileInput) *CompanyContextSummary {
	if profile == nil {
		return nil
	}
	facts := MapCompanyProfileToFacts(profile)
	return &CompanyContextSummary{
		SizeCategory:   facts.Organization.SizeCategory,
		NIS2Applicable: facts.Organization.MeetsNIS2SizeThreshold() || profile.SubjectToNIS2,
		DPORequired:    facts.DataProtection.RequiresDSBByLaw,
		Sector:         facts.Sector.PrimarySector,
		Country:        facts.Organization.Country,
	}
}

func allCriticalHints() []EnrichmentHint {
	return []EnrichmentHint{
		{Field: "employee_count", Label: "Mitarbeiterzahl", Impact: "NIS2/BDSG DPO nicht pruefbar", Regulation: "NIS2, BDSG", Priority: "high"},
		{Field: "annual_revenue", Label: "Jahresumsatz", Impact: "NIS2/KMU nicht pruefbar", Regulation: "NIS2", Priority: "high"},
		{Field: "industry", Label: "Branche", Impact: "Sektor-Klassifikation nicht moeglich", Regulation: "NIS2, AI Act", Priority: "high"},
		{Field: "headquarters_country", Label: "Land", Impact: "BDSG-Regeln nicht anwendbar", Regulation: "BDSG", Priority: "medium"},
	}
}

// --- Parsers (matching TypeScript parseEmployeeRange/parseRevenueRange) ---

func parseEmployeeRangeGo(r string) int {
	switch r {
	case "1-9":
		return 5
	case "10-49":
		return 30
	case "50-249":
		return 150
	case "250-999":
		return 625
	case "1000+":
		return 1500
	default:
		return 0
	}
}

func parseRevenueRangeGo(r string) float64 {
	switch r {
	case "< 2 Mio":
		return 1_000_000
	case "2-10 Mio":
		return 6_000_000
	case "10-50 Mio":
		return 30_000_000
	case "50+ Mio":
		return 75_000_000
	default:
		return 0
	}
}

func isEUCountry(code string) bool {
	eu := map[string]bool{
		"DE": true, "AT": true, "FR": true, "IT": true, "ES": true, "NL": true,
		"BE": true, "LU": true, "IE": true, "PT": true, "GR": true, "FI": true,
		"SE": true, "DK": true, "PL": true, "CZ": true, "SK": true, "HU": true,
		"RO": true, "BG": true, "HR": true, "SI": true, "LT": true, "LV": true,
		"EE": true, "CY": true, "MT": true,
	}
	return eu[strings.ToUpper(code)]
}

func mapIndustryToDomain(industry string) string {
	lower := strings.ToLower(industry)
	switch {
	case strings.Contains(lower, "gesundheit") || strings.Contains(lower, "health") || strings.Contains(lower, "pharma"):
		return "healthcare"
	case strings.Contains(lower, "finanz") || strings.Contains(lower, "bank") || strings.Contains(lower, "versicherung"):
		return "finance"
	case strings.Contains(lower, "bildung") || strings.Contains(lower, "schule") || strings.Contains(lower, "universit"):
		return "education"
	case strings.Contains(lower, "energie") || strings.Contains(lower, "energy"):
		return "energy"
	case strings.Contains(lower, "logistik") || strings.Contains(lower, "transport"):
		return "logistics"
	case strings.Contains(lower, "it") || strings.Contains(lower, "software") || strings.Contains(lower, "tech"):
		return "it_services"
	default:
		return lower
	}
}
