/**
 * Zahlen, Geld, Datum und Dauer im deutschen Format. Aus dem alten Panel
 * übernommen (`de()`/`eur()`), damit App und Panel identisch formatieren.
 */

export function de(wert: number | null | undefined, nachkomma = 0): string {
  return Number(wert ?? 0).toLocaleString("de-DE", {
    minimumFractionDigits: nachkomma,
    maximumFractionDigits: nachkomma,
  })
}

export function eur(wert: number | null | undefined): string {
  return de(wert, 2)
}

/** Wie de(), aber „—" statt „0" wenn nichts bekannt ist. */
export function deOderStrich(wert: number | null | undefined, nachkomma = 0): string {
  return wert === null || wert === undefined ? "—" : de(wert, nachkomma)
}

/** Summe über eine Liste. */
export function summe<T>(liste: readonly T[], auswahl: (eintrag: T) => number): number {
  return liste.reduce((zwischenstand, eintrag) => zwischenstand + (auswahl(eintrag) || 0), 0)
}

/**
 * Durchschnittspreis je Liter — immer mengengewichtet (Summe Kosten geteilt
 * durch Summe Liter), nie als Mittel der Einzelpreise. Eine kleine Tankung zu
 * hohem Preis darf den Schnitt nicht so stark heben wie eine große.
 */
export function schnittpreis(
  liste: readonly { liters?: number | null; fuel_total_eur?: number | null }[],
): number {
  const liter = summe(liste, (t) => t.liters ?? 0)
  if (liter <= 0) return 0
  return summe(liste, (t) => t.fuel_total_eur ?? 0) / liter
}

const DATUM_KURZ = new Intl.DateTimeFormat("de-DE", {
  day: "2-digit",
  month: "2-digit",
  year: "numeric",
})

const DATUM_LANG = new Intl.DateTimeFormat("de-DE", {
  day: "numeric",
  month: "long",
  year: "numeric",
})

const UHRZEIT = new Intl.DateTimeFormat("de-DE", { hour: "2-digit", minute: "2-digit" })

const MONAT_JAHR = new Intl.DateTimeFormat("de-DE", { month: "long", year: "numeric" })

function alsDatum(wert: string | number | Date | null | undefined): Date | null {
  if (wert === null || wert === undefined || wert === "") return null
  const datum = wert instanceof Date ? wert : new Date(wert)
  return Number.isNaN(datum.getTime()) ? null : datum
}

export function datum(wert: string | number | Date | null | undefined): string {
  const d = alsDatum(wert)
  return d ? DATUM_KURZ.format(d) : "—"
}

export function datumLang(wert: string | number | Date | null | undefined): string {
  const d = alsDatum(wert)
  return d ? DATUM_LANG.format(d) : "—"
}

export function uhrzeit(wert: string | number | Date | null | undefined): string {
  const d = alsDatum(wert)
  return d ? UHRZEIT.format(d) : "—"
}

export function datumZeit(wert: string | number | Date | null | undefined): string {
  const d = alsDatum(wert)
  return d ? `${DATUM_KURZ.format(d)}, ${UHRZEIT.format(d)} Uhr` : "—"
}

export function monatJahr(wert: string | number | Date | null | undefined): string {
  const d = alsDatum(wert)
  return d ? MONAT_JAHR.format(d) : "—"
}

/** Dauer in Sekunden als „2 h 14 min" bzw. „14 min". */
export function dauer(sekunden: number | null | undefined): string {
  if (!sekunden || sekunden <= 0) return "—"
  const minutenGesamt = Math.round(sekunden / 60)
  const stunden = Math.floor(minutenGesamt / 60)
  const minuten = minutenGesamt % 60
  if (stunden === 0) return `${minuten} min`
  return `${stunden} h ${String(minuten).padStart(2, "0")} min`
}

/** ISO-Tagesdatum (YYYY-MM-DD) für Vergleiche und Eingabefelder. */
export function isoTag(wert: string | number | Date | null | undefined = new Date()): string {
  const d = alsDatum(wert)
  if (!d) return ""
  const versatz = d.getTimezoneOffset() * 60_000
  return new Date(d.getTime() - versatz).toISOString().slice(0, 10)
}
