package iace

import (
	"fmt"
	"strings"
)

// ============================================================================
// Prompt builders
// ============================================================================

func buildUserPrompt(sctx *SectionGenerationContext, sectionType string) string {
	var b strings.Builder

	if sctx == nil || sctx.Project == nil {
		b.WriteString("## Maschine / System\n\n- Keine Projektdaten vorhanden.\n\n")
		return b.String()
	}

	// Machine info — always included
	b.WriteString("## Maschine / System\n\n")
	b.WriteString(fmt.Sprintf("- **Name:** %s\n", sctx.Project.MachineName))
	b.WriteString(fmt.Sprintf("- **Typ:** %s\n", sctx.Project.MachineType))
	b.WriteString(fmt.Sprintf("- **Hersteller:** %s\n", sctx.Project.Manufacturer))
	if sctx.Project.Description != "" {
		b.WriteString(fmt.Sprintf("- **Beschreibung:** %s\n", sctx.Project.Description))
	}
	if sctx.Project.CEMarkingTarget != "" {
		b.WriteString(fmt.Sprintf("- **CE-Kennzeichnungsziel:** %s\n", sctx.Project.CEMarkingTarget))
	}
	if sctx.Project.NarrativeText != "" {
		b.WriteString(fmt.Sprintf("\n**Projektbeschreibung:** %s\n", truncateForPrompt(sctx.Project.NarrativeText, 500)))
	}
	b.WriteString("\n")

	// Components — for most section types
	if len(sctx.Components) > 0 && needsComponents(sectionType) {
		b.WriteString("## Komponenten\n\n")
		for i, c := range sctx.Components {
			if i >= 20 {
				b.WriteString(fmt.Sprintf("... und %d weitere Komponenten\n", len(sctx.Components)-20))
				break
			}
			safety := ""
			if c.IsSafetyRelevant {
				safety = " [SICHERHEITSRELEVANT]"
			}
			networked := ""
			if c.IsNetworked {
				networked = " [VERNETZT]"
			}
			b.WriteString(fmt.Sprintf("- %s (Typ: %s)%s%s", c.Name, string(c.ComponentType), safety, networked))
			if c.Description != "" {
				b.WriteString(fmt.Sprintf(" — %s", truncateForPrompt(c.Description, 100)))
			}
			b.WriteString("\n")
		}
		b.WriteString("\n")
	}

	// Hazards + assessments — for risk-related sections
	if len(sctx.Hazards) > 0 && needsHazards(sectionType) {
		b.WriteString("## Gefaehrdungen und Risikobewertungen\n\n")
		for i, h := range sctx.Hazards {
			if i >= 30 {
				b.WriteString(fmt.Sprintf("... und %d weitere Gefaehrdungen\n", len(sctx.Hazards)-30))
				break
			}
			b.WriteString(fmt.Sprintf("### %s\n", h.Name))
			b.WriteString(fmt.Sprintf("- Kategorie: %s", h.Category))
			if h.SubCategory != "" {
				b.WriteString(fmt.Sprintf(" / %s", h.SubCategory))
			}
			b.WriteString("\n")
			if h.LifecyclePhase != "" {
				b.WriteString(fmt.Sprintf("- Lebenszyklusphase: %s\n", h.LifecyclePhase))
			}
			if h.Scenario != "" {
				b.WriteString(fmt.Sprintf("- Szenario: %s\n", truncateForPrompt(h.Scenario, 150)))
			}
			if h.PossibleHarm != "" {
				b.WriteString(fmt.Sprintf("- Moeglicher Schaden: %s\n", h.PossibleHarm))
			}
			if h.AffectedPerson != "" {
				b.WriteString(fmt.Sprintf("- Betroffene Person: %s\n", h.AffectedPerson))
			}
			b.WriteString(fmt.Sprintf("- Status: %s\n", string(h.Status)))

			// Latest assessment
			if assessments, ok := sctx.Assessments[h.ID]; ok && len(assessments) > 0 {
				a := assessments[len(assessments)-1] // latest
				b.WriteString(fmt.Sprintf("- Bewertung: S=%d E=%d P=%d → Risiko=%.1f (%s) %s\n",
					a.Severity, a.Exposure, a.Probability,
					a.ResidualRisk, string(a.RiskLevel),
					acceptableLabel(a.IsAcceptable)))
			}
			b.WriteString("\n")
		}
	}

	// Mitigations — for mitigation/verification sections
	if needsMitigations(sectionType) {
		designMeasures, protectiveMeasures, infoMeasures := groupMitigations(sctx)
		if len(designMeasures)+len(protectiveMeasures)+len(infoMeasures) > 0 {
			b.WriteString("## Risikomindernde Massnahmen (3-Stufen-Methode)\n\n")
			writeMitigationGroup(&b, "Stufe 1: Inhaerent sichere Konstruktion (Design)", designMeasures)
			writeMitigationGroup(&b, "Stufe 2: Technische Schutzmassnahmen (Protective)", protectiveMeasures)
			writeMitigationGroup(&b, "Stufe 3: Benutzerinformation (Information)", infoMeasures)
		}
	}

	// Classifications — for classification/standards sections
	if len(sctx.Classifications) > 0 && needsClassifications(sectionType) {
		b.WriteString("## Regulatorische Klassifizierungen\n\n")
		for _, c := range sctx.Classifications {
			b.WriteString(fmt.Sprintf("- **%s:** %s (Risiko: %s)\n",
				string(c.Regulation), c.ClassificationResult, string(c.RiskLevel)))
			if c.Reasoning != "" {
				b.WriteString(fmt.Sprintf("  Begruendung: %s\n", truncateForPrompt(c.Reasoning, 200)))
			}
		}
		b.WriteString("\n")
	}

	// Evidence — for evidence/verification sections
	if len(sctx.Evidence) > 0 && needsEvidence(sectionType) {
		b.WriteString("## Vorhandene Nachweise\n\n")
		for i, e := range sctx.Evidence {
			if i >= 30 {
				b.WriteString(fmt.Sprintf("... und %d weitere Nachweise\n", len(sctx.Evidence)-30))
				break
			}
			b.WriteString(fmt.Sprintf("- %s", e.FileName))
			if e.Description != "" {
				b.WriteString(fmt.Sprintf(" — %s", truncateForPrompt(e.Description, 100)))
			}
			b.WriteString("\n")
		}
		b.WriteString("\n")
	}

	// RAG context — if available
	if sctx.RAGContext != "" {
		b.WriteString("## Relevante Rechtsgrundlagen (RAG)\n\n")
		b.WriteString(sctx.RAGContext)
		b.WriteString("\n\n")
	}

	// Instruction
	b.WriteString("---\n\n")
	b.WriteString("Erstelle den Abschnitt basierend auf den obigen Daten. Schreibe auf Deutsch, verwende Markdown-Formatierung und beziehe dich auf die konkreten Projektdaten.\n")

	return b.String()
}

// ============================================================================
// Section type → data requirements
// ============================================================================

func needsComponents(sectionType string) bool {
	switch sectionType {
	case SectionGeneralDescription, SectionDesignSpecifications, SectionComponentList,
		SectionEssentialRequirements, SectionAIModelDescription, SectionAIIntendedPurpose,
		SectionClassificationReport, SectionInstructionsForUse:
		return true
	}
	return false
}

func needsHazards(sectionType string) bool {
	switch sectionType {
	case SectionRiskAssessmentReport, SectionHazardLogCombined, SectionEssentialRequirements,
		SectionMitigationReport, SectionVerificationReport, SectionTestReports,
		SectionAIRiskManagement, SectionInstructionsForUse, SectionMonitoringPlan:
		return true
	}
	return false
}

func needsMitigations(sectionType string) bool {
	switch sectionType {
	case SectionRiskAssessmentReport, SectionMitigationReport, SectionVerificationReport,
		SectionTestReports, SectionEssentialRequirements, SectionAIRiskManagement,
		SectionAIHumanOversight, SectionInstructionsForUse:
		return true
	}
	return false
}

func needsClassifications(sectionType string) bool {
	switch sectionType {
	case SectionClassificationReport, SectionEssentialRequirements, SectionStandardsApplied,
		SectionDeclarationConformity, SectionAIIntendedPurpose, SectionAIRiskManagement,
		SectionGeneralDescription:
		return true
	}
	return false
}

func needsEvidence(sectionType string) bool {
	switch sectionType {
	case SectionEvidenceIndex, SectionVerificationReport, SectionTestReports,
		SectionMitigationReport:
		return true
	}
	return false
}

// ============================================================================
// Mitigation grouping helpers
// ============================================================================

func groupMitigations(sctx *SectionGenerationContext) (design, protective, info []Mitigation) {
	for _, mits := range sctx.Mitigations {
		for _, m := range mits {
			switch m.ReductionType {
			case ReductionTypeDesign:
				design = append(design, m)
			case ReductionTypeProtective:
				protective = append(protective, m)
			case ReductionTypeInformation:
				info = append(info, m)
			}
		}
	}
	return
}

func writeMitigationGroup(b *strings.Builder, title string, measures []Mitigation) {
	if len(measures) == 0 {
		return
	}
	b.WriteString(fmt.Sprintf("### %s\n\n", title))
	for i, m := range measures {
		if i >= 20 {
			b.WriteString(fmt.Sprintf("... und %d weitere Massnahmen\n", len(measures)-20))
			break
		}
		b.WriteString(fmt.Sprintf("- **%s** [%s]", m.Name, string(m.Status)))
		if m.VerificationMethod != "" {
			b.WriteString(fmt.Sprintf(" — Verifikation: %s", string(m.VerificationMethod)))
			if m.VerificationResult != "" {
				b.WriteString(fmt.Sprintf(" (%s)", m.VerificationResult))
			}
		}
		b.WriteString("\n")
		if m.Description != "" {
			b.WriteString(fmt.Sprintf("  %s\n", truncateForPrompt(m.Description, 150)))
		}
	}
	b.WriteString("\n")
}
