package iace

import (
	"fmt"
	"sort"
	"strings"
)

// RenderCrossRefAppendix builds a Markdown appendix for a tech-file section
// that lists the international equivalents of the given norm IDs. It is
// intended to be appended to the "Applied Harmonised Standards" section so
// the same tech file is usable for CE + US/CN/JP market submissions.
//
// Output format:
//
//	## Anhang: Internationale Aequivalenzen / International Cross-Reference
//
//	Diese Tabelle ordnet die in dieser technischen Dokumentation angewandten
//	EU-Normen den Pendants in anderen Maerkten zu. Die Spalte "Relation" gibt
//	an, ob es sich um eine identische Uebernahme, eine teilweise Ueberdeckung
//	oder ein abgeloestes (superseded_by) Dokument handelt. Vor Nutzung im
//	jeweiligen Marktraum durch eine sachkundige Person verifizieren.
//
//	| EU Norm | Region | International Identifier | Relation | Confidence |
//	|---------|--------|--------------------------|----------|------------|
//	...
//
// If no norms have crossref entries, returns an empty string so the caller
// can skip the appendix entirely.
func RenderCrossRefAppendix(normIDs []string) string {
	rows := collectCrossRefRows(normIDs)
	if len(rows) == 0 {
		return ""
	}

	var b strings.Builder
	b.WriteString("\n\n## Anhang: Internationale Aequivalenzen / International Cross-Reference\n\n")
	b.WriteString("Diese Tabelle ordnet die in dieser technischen Dokumentation angewandten EU-Normen den Pendants in anderen Maerkten zu (DIN, ANSI/NFPA/UL/OSHA, GB, JIS u.a.). Die Spalte ")
	b.WriteString("**Relation** kennzeichnet `identical` (wortgleiche Uebernahme), `equivalent` (Kompatibilitaet auf Verfahrensebene), ")
	b.WriteString("`partial` (Teilueberdeckung — vor Nutzung pruefen), `supersedes`/`superseded_by` (Ablaufverhaeltnis). ")
	b.WriteString("Die Spalte **Confidence** drueckt die intern hinterlegte Verlaesslichkeit der Zuordnung aus. ")
	b.WriteString("Vor Verwendung in einem Drittmarkt durch eine sachkundige Person verifizieren.\n\n")
	b.WriteString("| EU Norm (verwendet) | Region | International Identifier | Relation | Confidence | Hinweis |\n")
	b.WriteString("|---------------------|--------|--------------------------|----------|------------|---------|\n")

	for _, row := range rows {
		note := row.Notes
		if note == "" {
			note = "—"
		}
		// Escape pipes in identifier and note for markdown table safety.
		fmt.Fprintf(&b,
			"| %s | %s | %s | %s | %s | %s |\n",
			escapeCell(row.SourceNorm),
			escapeCell(row.Region),
			escapeCell(row.Identifier),
			escapeCell(row.Relation),
			escapeCell(row.Confidence),
			escapeCell(note),
		)
	}

	b.WriteString("\n*Quelle: BreakPilot Cross-Reference Matrix. Keine Originalnormtexte reproduziert — nur Identifikatoren. Stand: Bezugsperiode der jeweiligen Norm-Bibliothek.*\n")
	return b.String()
}

// crossRefRow is a flattened row of the matrix used by the renderer.
type crossRefRow struct {
	SourceNorm string
	Region     string
	Identifier string
	Relation   string
	Confidence string
	Notes      string
}

// collectCrossRefRows expands the per-norm mapping list into a sorted slice
// of rows. Sort order: source norm ID first, then region in a canonical
// regional order so EU markets appear before non-EU.
func collectCrossRefRows(normIDs []string) []crossRefRow {
	regionRank := map[string]int{
		"EU-DIN":  0,
		"INTL-ISO": 1,
		"US-ANSI": 2,
		"US-NFPA": 3,
		"US-UL":   4,
		"US-OSHA": 5,
		"US-ASME": 6,
		"US-ASTM": 7,
		"US-SAE":  8,
		"US-NIOSH": 9,
		"US-FDA":  10,
		"US-EPA":  11,
		"US-NEMA": 12,
		"US-NSF":  13,
		"US-API":  14,
		"US-CPSC": 15,
		"US-AHRI": 16,
		"US-ASHRAE": 17,
		"US-FCC":  18,
		"US-DOT":  19,
		"US-MSHA": 20,
		"US-FM":   21,
		"US-AAR":  22,
		"US-ACI":  23,
		"US-ADA":  24,
		"US-AAMA": 25,
		"US-APA":  26,
		"US-APSP": 27,
		"US-EJMA": 28,
		"US-ICC":  29,
		"US-SMACNA": 30,
		"CN-GB":   40,
		"JP-JIS":  50,
	}

	seen := make(map[string]bool)
	var rows []crossRefRow
	for _, id := range normIDs {
		if seen[id] {
			continue
		}
		seen[id] = true
		cr := GetNormCrossRef(id)
		for _, m := range cr.Mappings {
			rows = append(rows, crossRefRow{
				SourceNorm: id,
				Region:     m.Region,
				Identifier: m.Identifier,
				Relation:   m.Relation,
				Confidence: m.Confidence,
				Notes:      m.Notes,
			})
		}
	}

	sort.SliceStable(rows, func(i, j int) bool {
		if rows[i].SourceNorm != rows[j].SourceNorm {
			return rows[i].SourceNorm < rows[j].SourceNorm
		}
		ri, ok := regionRank[rows[i].Region]
		if !ok {
			ri = 99
		}
		rj, ok := regionRank[rows[j].Region]
		if !ok {
			rj = 99
		}
		return ri < rj
	})
	return rows
}

// escapeCell escapes pipes and newlines so a Markdown table cell does not break.
func escapeCell(s string) string {
	s = strings.ReplaceAll(s, "|", "\\|")
	s = strings.ReplaceAll(s, "\n", " ")
	return s
}
