// Deutsche Zahlenformate der V2-Anzeigeebene.
//
// Warum im Kern und nicht in der Komponente: Auch der Kern schreibt Text, den
// jemand liest — die Diagnosezeilen der Brücke zum Beispiel. Vor dieser Datei
// standen dort rohe Gleitkommazahlen („es bleibt ein Rest von
// 1.370000000000004"), weil die Formatierung nur in der Komponente lag und der
// Kern nicht dorthin greifen darf. Eine Stelle für beide löst das; die
// Richtung stimmt, weil Komponenten aus `lib/` importieren dürfen und nicht
// umgekehrt.
//
// Pure Funktionen, keine I/O.

/** Ab hier wird gekürzt: 77.406.000 EUR liest niemand als Zahl. */
const MILLION = 1_000_000
const MILLIARDE = 1_000_000_000

/** Einheiten, bei denen eine Kürzung auf Mio./Mrd. sinnvoll ist. */
const KUERZBAR = new Set(['EUR'])

function deutsch(value: number, decimals: number): string {
  return new Intl.NumberFormat('de-DE', {
    minimumFractionDigits: decimals,
    maximumFractionDigits: decimals,
  }).format(value)
}

/**
 * Zahl in deutscher Schreibweise.
 *
 * Ohne Einheit und ohne Kürzung — für Fliesstext, in dem ein Betrag vorkommt.
 */
export function formatNumberDe(value: number, decimals = 2): string {
  return deutsch(value, decimals)
}

export interface MoneyParts {
  /** Der Zahlenteil, bereits gekürzt. */
  text: string
  /** Der Zusatz hinter der Zahl, leer wenn nicht gekürzt wurde. */
  scaleDe: '' | 'Mio.' | 'Mrd.'
}

/**
 * Grosse Beträge kürzen.
 *
 * `77.406.000,00 EUR` zwingt zum Ziffernzählen; `77,41 Mio. EUR` nicht. Die
 * Kürzung greift nur bei Einheiten, bei denen Millionen überhaupt vorkommen —
 * ein Stückpreis in Mio. wäre eine Falschaussage über die Grössenordnung.
 *
 * Der Betrag wird für die Anzeige gerundet, nicht für die Rechnung: Summiert
 * wird im Kern (Invariante U-03).
 */
export function scaleMoney(value: number, unit: string, decimals = 2): MoneyParts {
  if (!KUERZBAR.has(unit)) return { text: deutsch(value, decimals), scaleDe: '' }

  const betrag = Math.abs(value)
  if (betrag >= MILLIARDE) return { text: deutsch(value / MILLIARDE, decimals), scaleDe: 'Mrd.' }
  if (betrag >= MILLION) return { text: deutsch(value / MILLION, decimals), scaleDe: 'Mio.' }
  return { text: deutsch(value, decimals), scaleDe: '' }
}
