// Abschnittsüberschriften, die ihr Ergebnis tragen (Spezifikation Kap. 24,
// Action-Title-Regel).
//
// Der Unterschied zwischen einer Kategorie und einer Aussage:
//
//   vorher   A1. Fertigungskosten-Deltas
//   nachher  A1. Fertigung — 25 → 31 Stationen · Δ +2,4727 EUR/Stück
//
// Nach der ersten Zeile weiss der Leser Bescheid. Vorher musste er
// hineinschauen, um zu erfahren, ob überhaupt etwas passiert ist.
//
// Warum das hier steht und nicht in jeder Komponente einzeln: Eine
// wiedererkennbare Oberfläche entsteht nicht dadurch, dass jeder Abschnitt für
// sich gut aussieht, sondern dadurch, dass alle dieselbe Sprache sprechen —
// dieselbe Reihenfolge, dieselben Trennzeichen, dieselbe Behandlung des
// Sonderfalls „nichts verändert". Achtzehn Abschnitte mit achtzehn eigenen
// Formulierungen sind achtzehn Gelegenheiten, es verschieden zu machen.
//
// Pure Funktionen, keine I/O.

import { formatNumberDe, scaleMoney } from './format-de'

/** Trennzeichen zwischen den Fakten einer Überschrift. */
const TRENNER = ' · '

/** Zwischen Titel und Fakten. */
const GEDANKENSTRICH = ' — '

export interface CountChange {
  from: number
  to: number
  /** Substantiv im Plural, wie es in der Überschrift steht. */
  nounDe: string
}

/**
 * Mengenänderung als Satzteil.
 *
 * Bleibt die Zahl gleich, steht sie einmal statt zweimal: „31 Stationen" sagt
 * dasselbe wie „31 → 31 Stationen", ohne eine Veränderung anzudeuten, die es
 * nicht gab.
 */
export function countPhrase(c: CountChange): string {
  const von = formatNumberDe(c.from, 0)
  const nach = formatNumberDe(c.to, 0)
  return c.from === c.to ? `${nach} ${c.nounDe}` : `${von} → ${nach} ${c.nounDe}`
}

export interface DeltaFact {
  value: number | null
  unit: string
  /** Nachkommastellen; Stückpreise tragen vier. */
  decimals?: number
}

/**
 * Delta als Satzteil, mit ausdrücklichem Vorzeichen.
 *
 * Ohne Vorzeichen liest sich eine Zahl in einer Überschrift wie ein Bestand,
 * nicht wie eine Veränderung — und die Richtung ist genau die Aussage.
 */
export function deltaPhrase(d: DeltaFact): string {
  if (d.value === null) return 'Δ nicht ermittelbar'
  const stellen = d.decimals ?? (d.unit === 'EUR_per_piece' ? 4 : 2)
  const { text, scaleDe } = scaleMoney(Math.abs(d.value), d.unit, stellen)
  const einheit = d.unit === 'EUR_per_piece' ? ' EUR/Stück' : d.unit === 'EUR' ? ' EUR' : ` ${d.unit}`
  const zusatz = scaleDe === '' ? '' : ` ${scaleDe}`
  return `Δ ${d.value >= 0 ? '+' : '−'}${text}${zusatz}${einheit}`
}

/**
 * Befundzahlen nach Schweregrad.
 *
 * Die Lage steht vor dem Aufklappen da: Wer „12 Befunde" liest, weiss nicht, ob
 * er hinsehen muss. Wer „12 Befunde · 4 hoch · 5 mittel" liest, schon.
 */
export function severityPhrase(counts: { high?: number; medium?: number; low?: number; info?: number }): string {
  const teile: string[] = []
  const gesamt = (counts.high ?? 0) + (counts.medium ?? 0) + (counts.low ?? 0) + (counts.info ?? 0)
  if (gesamt === 0) return 'keine Befunde'

  if (counts.high) teile.push(`${counts.high} hoch`)
  if (counts.medium) teile.push(`${counts.medium} mittel`)
  if (counts.low) teile.push(`${counts.low} niedrig`)
  if (counts.info) teile.push(`${counts.info} Hinweis`)
  return `${gesamt} Befunde (${teile.join(', ')})`
}

/**
 * Überschrift aus Nummer, Name und Fakten.
 *
 * Leere Fakten fallen weg statt als Lücke zu erscheinen. Bleibt nichts übrig,
 * steht der Abschnitt ohne Zusatz da — besser als ein Gedankenstrich, hinter
 * dem nichts kommt.
 */
export function actionTitle(labelDe: string, facts: ReadonlyArray<string | null | undefined>): string {
  const echte = facts.filter((f): f is string => typeof f === 'string' && f.length > 0)
  return echte.length === 0 ? labelDe : `${labelDe}${GEDANKENSTRICH}${echte.join(TRENNER)}`
}

/**
 * Der Sonderfall, den jeder Abschnitt braucht: nichts verändert.
 *
 * „Keine Abweichung" ist eine Aussage und muss genauso sichtbar sein wie eine
 * Abweichung — sonst sieht ein geprüfter Abschnitt aus wie ein vergessener.
 */
export function unchangedPhrase(nounDe: string): string {
  return `${nounDe} unverändert`
}
