package maximizer

import (
	"strings"

	"github.com/breakpilot/ai-compliance-sdk/internal/ucca"
)

// MapIntakeToDimensions converts a UseCaseIntake to a normalized DimensionConfig.
// Highest sensitivity wins for multi-value fields.
func MapIntakeToDimensions(intake *ucca.UseCaseIntake) *DimensionConfig {
	config := &DimensionConfig{
		AutomationLevel:      mapAutomation(intake.Automation),
		DecisionBinding:      deriveBinding(intake),
		DecisionImpact:       deriveImpact(intake),
		Domain:               mapDomain(intake.Domain),
		DataType:             deriveDataType(intake.DataTypes),
		HumanInLoop:          deriveHIL(intake.Automation),
		Explainability:       ExplainBasic, // default
		RiskClassification:   RiskMinimal,  // will be set by evaluator
		LegalBasis:           LegalContract, // default
		TransparencyRequired: false,
		LoggingRequired:      false,
		ModelType:            deriveModelType(intake.ModelUsage),
		DeploymentScope:      deriveScope(intake),
	}
	return config
}

// MapDimensionsToIntake converts a DimensionConfig back to a UseCaseIntake,
// preserving unchanged fields from the original intake.
func MapDimensionsToIntake(config *DimensionConfig, original *ucca.UseCaseIntake) *ucca.UseCaseIntake {
	result := *original // shallow copy

	// Map automation level
	switch config.AutomationLevel {
	case AutoNone:
		result.Automation = ucca.AutomationAssistive
	case AutoAssistive:
		result.Automation = ucca.AutomationAssistive
	case AutoPartial:
		result.Automation = ucca.AutomationSemiAutomated
	case AutoFull:
		result.Automation = ucca.AutomationFullyAutomated
	}

	// Map data type back
	result.DataTypes = mapDataTypeBack(config.DataType, original.DataTypes)

	// Map domain back
	result.Domain = mapDomainBack(config.Domain, original.Domain)

	return &result
}

func mapAutomation(a ucca.AutomationLevel) AutomationLevel {
	switch a {
	case ucca.AutomationAssistive:
		return AutoAssistive
	case ucca.AutomationSemiAutomated:
		return AutoPartial
	case ucca.AutomationFullyAutomated:
		return AutoFull
	default:
		return AutoNone
	}
}

func deriveBinding(intake *ucca.UseCaseIntake) DecisionBinding {
	if intake.Outputs.LegalEffects || intake.Outputs.AccessDecisions {
		if intake.Automation == ucca.AutomationFullyAutomated {
			return BindingFullyBinding
		}
		return BindingHumanReview
	}
	return BindingNonBinding
}

func deriveImpact(intake *ucca.UseCaseIntake) DecisionImpact {
	if intake.Outputs.LegalEffects || intake.Outputs.AccessDecisions {
		return ImpactHigh
	}
	if intake.Outputs.RankingsOrScores || intake.Purpose.EvaluationScoring || intake.Purpose.DecisionMaking {
		return ImpactMedium
	}
	return ImpactLow
}

func mapDomain(d ucca.Domain) DomainCategory {
	switch d {
	case "hr", "human_resources":
		return DomainHR
	case "finance", "banking", "insurance", "investment":
		return DomainFinance
	case "education", "school", "university":
		return DomainEducation
	case "health", "healthcare", "medical":
		return DomainHealth
	case "marketing", "advertising":
		return DomainMarketing
	default:
		return DomainGeneral
	}
}

func deriveDataType(dt ucca.DataTypes) DataTypeSensitivity {
	// Highest sensitivity wins
	if dt.BiometricData {
		return DataBiometric
	}
	if dt.Article9Data {
		return DataSensitive
	}
	if dt.PersonalData || dt.EmployeeData || dt.CustomerData ||
		dt.FinancialData || dt.MinorData || dt.LocationData ||
		dt.Images || dt.Audio {
		return DataPersonal
	}
	return DataNonPersonal
}

func deriveHIL(a ucca.AutomationLevel) HumanInLoopLevel {
	switch a {
	case ucca.AutomationAssistive:
		return HILRequired
	case ucca.AutomationSemiAutomated:
		return HILOptional
	case ucca.AutomationFullyAutomated:
		return HILNone
	default:
		return HILRequired
	}
}

func deriveModelType(mu ucca.ModelUsage) ModelType {
	if mu.RAG && !mu.Training && !mu.Finetune {
		return ModelRuleBased
	}
	if mu.Training || mu.Finetune {
		return ModelBlackboxLLM
	}
	return ModelStatistical
}

func deriveScope(intake *ucca.UseCaseIntake) DeploymentScope {
	if intake.Purpose.PublicService || intake.Outputs.DataExport {
		return ScopePublic
	}
	if intake.Purpose.CustomerSupport || intake.Purpose.Marketing {
		return ScopeExternal
	}
	return ScopeInternal
}

func mapDataTypeBack(dt DataTypeSensitivity, original ucca.DataTypes) ucca.DataTypes {
	result := original
	switch dt {
	case DataNonPersonal:
		result.PersonalData = false
		result.Article9Data = false
		result.BiometricData = false
	case DataPersonal:
		result.PersonalData = true
		result.Article9Data = false
		result.BiometricData = false
	case DataSensitive:
		result.PersonalData = true
		result.Article9Data = true
		result.BiometricData = false
	case DataBiometric:
		result.PersonalData = true
		result.Article9Data = true
		result.BiometricData = true
	}
	return result
}

// EnrichDimensionsFromProfile adjusts dimensions based on company profile data.
func EnrichDimensionsFromProfile(config *DimensionConfig, profile *ucca.CompanyProfileInput) {
	if profile == nil {
		return
	}

	// Domain override from company industry (if config still generic)
	if config.Domain == DomainGeneral && profile.Industry != "" {
		lower := strings.ToLower(profile.Industry)
		switch {
		case strings.Contains(lower, "gesundheit") || strings.Contains(lower, "health"):
			config.Domain = DomainHealth
		case strings.Contains(lower, "finanz") || strings.Contains(lower, "bank") || strings.Contains(lower, "versicherung"):
			config.Domain = DomainFinance
		case strings.Contains(lower, "bildung") || strings.Contains(lower, "schule"):
			config.Domain = DomainEducation
		case strings.Contains(lower, "personal") || strings.Contains(lower, "hr"):
			config.Domain = DomainHR
		case strings.Contains(lower, "marketing"):
			config.Domain = DomainMarketing
		}
	}

	// NIS2/AI-Act regulatory flags
	if profile.SubjectToNIS2 {
		config.LoggingRequired = true
	}
	if profile.SubjectToAIAct {
		config.TransparencyRequired = true
	}
}

func mapDomainBack(dc DomainCategory, original ucca.Domain) ucca.Domain {
	switch dc {
	case DomainHR:
		return "hr"
	case DomainFinance:
		return "finance"
	case DomainEducation:
		return "education"
	case DomainHealth:
		return "health"
	case DomainMarketing:
		return "marketing"
	default:
		return original
	}
}
