// Shared display/parse helpers for the QAF comparison sections (KAR-840).
// Single source for the de-DE money formatter (was copy-pasted per chart)
// and the NaN-safe numeric input parser used by interactive fields.

export interface MoneyFormatOptions {
  /** signDisplay: 'exceptZero' — for delta displays. */
  signed?: boolean
}

/** de-DE currency formatter with a verbose fallback for unknown codes. */
export function moneyFormatter(currency: string | null, opts: MoneyFormatOptions = {}): (n: number) => string {
  const signDisplay = opts.signed ? ('exceptZero' as const) : ('auto' as const)
  try {
    const fmt = new Intl.NumberFormat('de-DE', {
      style: 'currency',
      currency: currency ?? 'EUR',
      maximumFractionDigits: 2,
      signDisplay,
    })
    return (n) => fmt.format(n)
  } catch {
    const fmt = new Intl.NumberFormat('de-DE', { maximumFractionDigits: 2, signDisplay })
    return (n) => `${fmt.format(n)}${currency ? ` ${currency}` : ''}`
  }
}

/**
 * Plain (non-currency) de-DE number formatter — 2 decimals, thousands
 * separator (KAR-950 item 5: profile-diff totals like `41.120135999999995`
 * are raw JS floats with no attached currency field, so `moneyFormatter`
 * doesn't apply; this is the same rounding/grouping discipline for a bare
 * number). `null`/`undefined` render as `'—'`, never `'NaN'`/`'null'`.
 */
export function numberFormatter(opts: MoneyFormatOptions = {}): (n: number | null | undefined) => string {
  const signDisplay = opts.signed ? ('exceptZero' as const) : ('auto' as const)
  const fmt = new Intl.NumberFormat('de-DE', { maximumFractionDigits: 2, minimumFractionDigits: 2, signDisplay })
  return (n) => (n === null || n === undefined ? '—' : fmt.format(n))
}

/**
 * Parse free-typed numeric input: a finite number, or null for empty /
 * in-progress / invalid text. Callers keep the raw text in local state and
 * only commit finite values — NaN can never reach a computation.
 */
export function parseNumericInput(raw: string): number | null {
  if (raw.trim() === '') return null
  const n = Number(raw)
  return Number.isFinite(n) ? n : null
}
