package ucca

// ============================================================================
// AI Act Decision Tree Engine
// ============================================================================
//
// Two-axis classification:
//   Axis 1 (Q1–Q7): High-Risk classification based on Annex III
//   Axis 2 (Q8–Q12): GPAI classification based on Art. 51–56
//
// Deterministic evaluation — no LLM involved.
//
// ============================================================================

// Question IDs
const (
	Q1  = "Q1"  // Uses AI?
	Q2  = "Q2"  // Biometric identification?
	Q3  = "Q3"  // Critical infrastructure?
	Q4  = "Q4"  // Education / employment / HR?
	Q5  = "Q5"  // Essential services (credit, insurance)?
	Q6  = "Q6"  // Law enforcement / migration / justice?
	Q7  = "Q7"  // Autonomous decisions with legal effect?
	Q8  = "Q8"  // Foundation Model / GPAI?
	Q9  = "Q9"  // Generates content (text, image, code, audio)?
	Q10 = "Q10" // Trained with >10^25 FLOP?
	Q11 = "Q11" // Model provided as API/service for third parties?
	Q12 = "Q12" // Significant EU market penetration?
)

// BuildDecisionTreeDefinition returns the full decision tree structure for the frontend
func BuildDecisionTreeDefinition() *DecisionTreeDefinition {
	return &DecisionTreeDefinition{
		ID:      "ai_act_two_axis",
		Name:    "AI Act Zwei-Achsen-Klassifikation",
		Version: "1.0.0",
		Questions: []DecisionTreeQuestion{
			// === Axis 1: High-Risk (Annex III) ===
			{
				ID:          Q1,
				Axis:        "high_risk",
				Question:    "Setzt Ihr System KI-Technologie ein?",
				Description: "KI im Sinne des AI Act umfasst maschinelles Lernen, logik- und wissensbasierte Ansätze sowie statistische Methoden, die für eine gegebene Reihe von Zielen Ergebnisse wie Inhalte, Vorhersagen, Empfehlungen oder Entscheidungen erzeugen.",
				ArticleRef:  "Art. 3 Nr. 1",
			},
			{
				ID:          Q2,
				Axis:        "high_risk",
				Question:    "Wird das System für biometrische Identifikation oder Kategorisierung natürlicher Personen verwendet?",
				Description: "Dazu zählen Gesichtserkennung, Stimmerkennung, Fingerabdruck-Analyse, Gangerkennung oder andere biometrische Merkmale zur Identifikation oder Kategorisierung.",
				ArticleRef:  "Anhang III Nr. 1",
				SkipIf:      Q1,
			},
			{
				ID:          Q3,
				Axis:        "high_risk",
				Question:    "Wird das System in kritischer Infrastruktur eingesetzt (Energie, Verkehr, Wasser, digitale Infrastruktur)?",
				Description: "Betrifft KI-Systeme als Sicherheitskomponenten in der Verwaltung und dem Betrieb kritischer digitaler Infrastruktur, des Straßenverkehrs oder der Wasser-, Gas-, Heizungs- oder Stromversorgung.",
				ArticleRef:  "Anhang III Nr. 2",
				SkipIf:      Q1,
			},
			{
				ID:          Q4,
				Axis:        "high_risk",
				Question:    "Betrifft das System Bildung, Beschäftigung oder Personalmanagement?",
				Description: "KI zur Festlegung des Zugangs zu Bildungseinrichtungen, Bewertung von Prüfungsleistungen, Bewerbungsauswahl, Beförderungsentscheidungen oder Überwachung von Arbeitnehmern.",
				ArticleRef:  "Anhang III Nr. 3–4",
				SkipIf:      Q1,
			},
			{
				ID:          Q5,
				Axis:        "high_risk",
				Question:    "Betrifft das System den Zugang zu wesentlichen Diensten (Kreditvergabe, Versicherung, öffentliche Leistungen)?",
				Description: "KI zur Bonitätsbewertung, Risikobewertung bei Versicherungen, Bewertung der Anspruchsberechtigung für öffentliche Unterstützungsleistungen oder Notdienste.",
				ArticleRef:  "Anhang III Nr. 5",
				SkipIf:      Q1,
			},
			{
				ID:          Q6,
				Axis:        "high_risk",
				Question:    "Wird das System in Strafverfolgung, Migration, Asyl oder Justiz eingesetzt?",
				Description: "KI für Lügendetektoren, Beweisbewertung, Rückfallprognose, Asylentscheidungen, Grenzkontrolle, Risikobewertung bei Migration oder Unterstützung der Rechtspflege.",
				ArticleRef:  "Anhang III Nr. 6–8",
				SkipIf:      Q1,
			},
			{
				ID:          Q7,
				Axis:        "high_risk",
				Question:    "Trifft das System autonome Entscheidungen mit rechtlicher Wirkung für natürliche Personen?",
				Description: "Entscheidungen, die Rechtsverhältnisse begründen, ändern oder aufheben, z.B. Kreditablehnungen, Kündigungen, Sozialleistungsentscheidungen — ohne menschliche Überprüfung im Einzelfall.",
				ArticleRef:  "Art. 22 DSGVO / Art. 14 AI Act",
				SkipIf:      Q1,
			},

			// === Axis 2: GPAI (Art. 51–56) ===
			{
				ID:          Q8,
				Axis:        "gpai",
				Question:    "Stellst du ein KI-Modell fuer Dritte bereit (API / Plattform / SDK), das fuer viele verschiedene Zwecke einsetzbar ist?",
				Description: "GPAI-Pflichten (Art. 51-56) gelten fuer den Modellanbieter, nicht den API-Nutzer. Wenn du nur eine API nutzt (z.B. OpenAI, Claude), bist du kein GPAI-Anbieter. GPAI-Anbieter ist, wer ein Modell trainiert/fine-tuned und Dritten zur Verfuegung stellt. Beispiele: GPT, Claude, LLaMA, Gemini, Stable Diffusion.",
				ArticleRef:  "Art. 3 Nr. 63 / Art. 51",
			},
			{
				ID:          Q9,
				Axis:        "gpai",
				Question:    "Kann das System Inhalte generieren (Text, Bild, Code, Audio, Video)?",
				Description: "Generative KI erzeugt neue Inhalte auf Basis von Eingaben — dazu zählen Chatbots, Bild-/Videogeneratoren, Code-Assistenten, Sprachsynthese und ähnliche Systeme.",
				ArticleRef:  "Art. 50 / Art. 52",
				SkipIf:      Q8,
			},
			{
				ID:          Q10,
				Axis:        "gpai",
				Question:    "Wurde das Modell mit mehr als 10²⁵ FLOP trainiert oder hat es gleichwertige Fähigkeiten?",
				Description: "GPAI-Modelle mit einem kumulativen Rechenaufwand von mehr als 10²⁵ Gleitkommaoperationen gelten als Modelle mit systemischem Risiko (Art. 51 Abs. 2).",
				ArticleRef:  "Art. 51 Abs. 2",
				SkipIf:      Q8,
			},
			{
				ID:          Q11,
				Axis:        "gpai",
				Question:    "Wird das Modell als API oder Service für Dritte bereitgestellt?",
				Description: "Stellen Sie das Modell anderen Unternehmen oder Entwicklern zur Nutzung bereit (API, SaaS, Plattform-Integration)?",
				ArticleRef:  "Art. 53",
				SkipIf:      Q8,
			},
			{
				ID:          Q12,
				Axis:        "gpai",
				Question:    "Hat das Modell eine signifikante Marktdurchdringung in der EU (>10.000 registrierte Geschäftsnutzer)?",
				Description: "Modelle mit hoher Marktdurchdringung können auch ohne 10²⁵ FLOP als systemisches Risiko eingestuft werden, wenn die EU-Kommission dies feststellt.",
				ArticleRef:  "Art. 51 Abs. 3",
				SkipIf:      Q8,
			},
		},
	}
}

// EvaluateDecisionTree evaluates the answers and returns the combined result
func EvaluateDecisionTree(req *DecisionTreeEvalRequest) *DecisionTreeResult {
	result := &DecisionTreeResult{
		SystemName:        req.SystemName,
		SystemDescription: req.SystemDescription,
		Answers:           req.Answers,
	}

	// Evaluate Axis 1: High-Risk
	result.HighRiskResult = evaluateHighRiskAxis(req.Answers)

	// Evaluate Axis 2: GPAI
	result.GPAIResult = evaluateGPAIAxis(req.Answers)

	// Combine obligations and articles
	result.CombinedObligations = combineObligations(result.HighRiskResult, result.GPAIResult)
	result.ApplicableArticles = combineArticles(result.HighRiskResult, result.GPAIResult)

	return result
}

// evaluateHighRiskAxis determines the AI Act risk level from Q1–Q7
func evaluateHighRiskAxis(answers map[string]DecisionTreeAnswer) AIActRiskLevel {
	// Q1: Uses AI at all?
	if !answerIsYes(answers, Q1) {
		return AIActNotApplicable
	}

	// Q2–Q6: Annex III high-risk categories
	if answerIsYes(answers, Q2) || answerIsYes(answers, Q3) ||
		answerIsYes(answers, Q4) || answerIsYes(answers, Q5) ||
		answerIsYes(answers, Q6) {
		return AIActHighRisk
	}

	// Q7: Autonomous decisions with legal effect
	if answerIsYes(answers, Q7) {
		return AIActHighRisk
	}

	// AI is used but no high-risk category triggered
	return AIActMinimalRisk
}

// evaluateGPAIAxis determines the GPAI classification from Q8–Q12
func evaluateGPAIAxis(answers map[string]DecisionTreeAnswer) GPAIClassification {
	gpai := GPAIClassification{
		Category:           GPAICategoryNone,
		ApplicableArticles: []string{},
		Obligations:        []string{},
	}

	// Q8: Is GPAI?
	if !answerIsYes(answers, Q8) {
		return gpai
	}

	gpai.IsGPAI = true
	gpai.Category = GPAICategoryStandard
	gpai.ApplicableArticles = append(gpai.ApplicableArticles, "Art. 51", "Art. 53")
	gpai.Obligations = append(gpai.Obligations,
		"Technische Dokumentation erstellen (Art. 53 Abs. 1a)",
		"Informationen für nachgelagerte Anbieter bereitstellen (Art. 53 Abs. 1b)",
		"Urheberrechtsrichtlinie einhalten (Art. 53 Abs. 1c)",
		"Trainingsdaten-Zusammenfassung veröffentlichen (Art. 53 Abs. 1d)",
	)

	// Q9: Generative AI — adds transparency obligations
	if answerIsYes(answers, Q9) {
		gpai.ApplicableArticles = append(gpai.ApplicableArticles, "Art. 50")
		gpai.Obligations = append(gpai.Obligations,
			"KI-generierte Inhalte kennzeichnen (Art. 50 Abs. 2)",
			"Maschinenlesbare Kennzeichnung synthetischer Inhalte (Art. 50 Abs. 2)",
		)
	}

	// Q10: Systemic risk threshold (>10^25 FLOP)
	if answerIsYes(answers, Q10) {
		gpai.IsSystemicRisk = true
		gpai.Category = GPAICategorySystemic
		gpai.ApplicableArticles = append(gpai.ApplicableArticles, "Art. 55")
		gpai.Obligations = append(gpai.Obligations,
			"Modellbewertung nach Stand der Technik durchführen (Art. 55 Abs. 1a)",
			"Systemische Risiken bewerten und mindern (Art. 55 Abs. 1b)",
			"Schwerwiegende Vorfälle melden (Art. 55 Abs. 1c)",
			"Angemessenes Cybersicherheitsniveau gewährleisten (Art. 55 Abs. 1d)",
		)
	}

	// Q11: API/Service provider — additional downstream obligations
	if answerIsYes(answers, Q11) {
		gpai.Obligations = append(gpai.Obligations,
			"Downstream-Informationspflichten erfüllen (Art. 53 Abs. 1b)",
		)
	}

	// Q12: Significant market penetration — potential systemic risk
	if answerIsYes(answers, Q12) && !gpai.IsSystemicRisk {
		// EU Commission can designate as systemic risk
		gpai.ApplicableArticles = append(gpai.ApplicableArticles, "Art. 51 Abs. 3")
		gpai.Obligations = append(gpai.Obligations,
			"Achtung: EU-Kommission kann GPAI mit hoher Marktdurchdringung als systemisches Risiko einstufen (Art. 51 Abs. 3)",
		)
	}

	return gpai
}

// combineObligations merges obligations from both axes
func combineObligations(highRisk AIActRiskLevel, gpai GPAIClassification) []string {
	var obligations []string

	// High-Risk obligations
	switch highRisk {
	case AIActHighRisk:
		obligations = append(obligations,
			"Risikomanagementsystem einrichten (Art. 9)",
			"Daten-Governance sicherstellen (Art. 10)",
			"Technische Dokumentation erstellen (Art. 11)",
			"Protokollierungsfunktion implementieren (Art. 12)",
			"Transparenz und Nutzerinformation (Art. 13)",
			"Menschliche Aufsicht ermöglichen (Art. 14)",
			"Genauigkeit, Robustheit und Cybersicherheit (Art. 15)",
			"EU-Datenbank-Registrierung (Art. 49)",
		)
	case AIActMinimalRisk:
		obligations = append(obligations,
			"Freiwillige Verhaltenskodizes empfohlen (Art. 95)",
		)
	case AIActNotApplicable:
		// No obligations
	}

	// GPAI obligations
	obligations = append(obligations, gpai.Obligations...)

	// Universal obligation for all AI users
	if highRisk != AIActNotApplicable {
		obligations = append(obligations,
			"KI-Kompetenz sicherstellen (Art. 4)",
			"Verbotene Praktiken vermeiden (Art. 5)",
		)
	}

	return obligations
}

// combineArticles merges applicable articles from both axes
func combineArticles(highRisk AIActRiskLevel, gpai GPAIClassification) []string {
	articles := map[string]bool{}

	// Universal
	if highRisk != AIActNotApplicable {
		articles["Art. 4"] = true
		articles["Art. 5"] = true
	}

	// High-Risk
	switch highRisk {
	case AIActHighRisk:
		for _, a := range []string{"Art. 9", "Art. 10", "Art. 11", "Art. 12", "Art. 13", "Art. 14", "Art. 15", "Art. 26", "Art. 49"} {
			articles[a] = true
		}
	case AIActMinimalRisk:
		articles["Art. 95"] = true
	}

	// GPAI
	for _, a := range gpai.ApplicableArticles {
		articles[a] = true
	}

	var result []string
	for a := range articles {
		result = append(result, a)
	}
	return result
}

// answerIsYes checks if a question was answered with "yes" (true)
func answerIsYes(answers map[string]DecisionTreeAnswer, questionID string) bool {
	a, ok := answers[questionID]
	if !ok {
		return false
	}
	return a.Value
}
