/**
 * Pengar (i18n-spec §20): minor units + ISO 4217, aldrig floating point för lagring.
 * Historiska priser behåller originalvaluta; omräkning märks alltid som omräknad.
 *
 * M1 GENOMFÖRD: alla pengakolumner lagras som *_minor (heltal) och hushållet bär
 * currency_code (ISO 4217). Denna modul är den gemensamma modellen för visning/aritmetik.
 */

export interface Money {
  /** Minsta enhet: öre, cent, pence … */
  amountMinor: number;
  /** ISO 4217, t.ex. "SEK", "EUR", "USD". */
  currency: string;
}

/** Valutor med annat antal decimaler än 2 (ISO 4217). */
const MINOR_DIGITS: Record<string, number> = { ISK: 0, JPY: 0, KWD: 3 };

export function minorDigits(currency: string): number {
  return MINOR_DIGITS[currency.toUpperCase()] ?? 2;
}

export function toMinor(amount: number, currency: string): number {
  return Math.round(amount * 10 ** minorDigits(currency));
}

export function fromMinor(money: Money): number {
  return money.amountMinor / 10 ** minorDigits(money.currency);
}

export function money(amountMinor: number, currency: string): Money {
  if (!Number.isInteger(amountMinor)) {
    throw new Error(`amountMinor måste vara ett heltal, fick ${amountMinor}`);
  }
  return { amountMinor, currency: currency.toUpperCase() };
}

export function addMoney(a: Money, b: Money): Money {
  if (a.currency !== b.currency) {
    throw new Error(`Kan inte addera ${a.currency} och ${b.currency} utan växelkurs`);
  }
  return { amountMinor: a.amountMinor + b.amountMinor, currency: a.currency };
}

/** Locale-medveten formattering via Intl (finns i Node, Hermes/RN och webbläsare). */
export function formatMoney(value: Money, languageTag: string): string {
  try {
    return new Intl.NumberFormat(languageTag, {
      style: "currency",
      currency: value.currency,
    }).format(fromMinor(value));
  } catch {
    return `${fromMinor(value)} ${value.currency}`;
  }
}
