// ============================================================================
// TERRITORY-FX — multi-currency engine.
//
// Two coexisting modes:
//   1. NATIVE WALLETS — keep income in its source currency, convert on payout.
//      Each territory has a primary currency; statements arrive in that
//      currency and stay there until withdrawn.
//   2. REPORTING-CURRENCY — every income is converted at the statement-period
//      rate to a single reporting currency (default USD). Useful for
//      consolidated views and KPIs.
//
// User can toggle, and individual screens can override (analytics shows
// reporting; statement detail shows native; treasury shows both).
//
// FX rates are loaded from REF.currencies if available, else a small built-in
// table. Period rates are interpolated month-by-month.
//
// Withholding rates per territory live here too — used in payout math.
//
// EXPORT: window.TerritoryFx
// ============================================================================
(function () {
  // ── Default FX rates (USD = 1.0) — illustrative.
  const FX_USD = {
    USD: 1.000,
    EUR: 1.085,
    GBP: 1.270,
    JPY: 0.0066,
    KRW: 0.00073,
    CNY: 0.139,
    HKD: 0.128,
    AUD: 0.660,
    NZD: 0.605,
    CAD: 0.730,
    MXN: 0.054,
    BRL: 0.195,
    ARS: 0.00104,
    CLP: 0.00103,
    COP: 0.00024,
    PEN: 0.265,
    INR: 0.0119,
    SGD: 0.745,
    THB: 0.0285,
    IDR: 0.0000625,
    MYR: 0.215,
    PHP: 0.0173,
    VND: 0.0000402,
    ZAR: 0.054,
    TRY: 0.029,
    AED: 0.272,
    SAR: 0.267,
    ILS: 0.275,
    EGP: 0.0203,
    NOK: 0.092,
    SEK: 0.094,
    DKK: 0.146,
    CHF: 1.115,
    PLN: 0.250,
    CZK: 0.043,
    HUF: 0.00271,
    RON: 0.218,
    RUB: 0.0103,
    UAH: 0.0240,
  };

  // ── Country → currency map (primary).
  const CCY_BY_ISO = {
    US:'USD', PR:'USD',
    CA:'CAD', MX:'MXN', GL:'DKK', BM:'USD',
    BR:'BRL', AR:'ARS', CL:'CLP', CO:'COP', PE:'PEN', VE:'USD', EC:'USD', UY:'USD', PY:'USD', BO:'USD', GT:'USD', HN:'USD', SV:'USD', NI:'USD', CR:'USD', PA:'USD', DO:'USD', CU:'USD', HT:'USD',
    GB:'GBP', IE:'EUR',
    FR:'EUR', DE:'EUR', BE:'EUR', NL:'EUR', LU:'EUR', AT:'EUR', ES:'EUR', IT:'EUR', PT:'EUR', GR:'EUR', MT:'EUR', CY:'EUR', SI:'EUR', SK:'EUR', EE:'EUR', LV:'EUR', LT:'EUR', FI:'EUR', HR:'EUR',
    CH:'CHF', LI:'CHF', NO:'NOK', SE:'SEK', DK:'DKK', IS:'EUR',
    PL:'PLN', CZ:'CZK', HU:'HUF', RO:'RON', BG:'EUR',
    RU:'RUB', UA:'UAH', BY:'EUR', MD:'EUR',
    JP:'JPY', KR:'KRW', KP:'KRW', CN:'CNY', TW:'USD', HK:'HKD', MO:'USD', MN:'USD',
    ID:'IDR', MY:'MYR', SG:'SGD', TH:'THB', VN:'VND', PH:'PHP', MM:'USD', KH:'USD', LA:'USD', BN:'USD', TL:'USD',
    IN:'INR', PK:'USD', BD:'USD', LK:'USD', NP:'USD', BT:'USD', MV:'USD', AF:'USD',
    IL:'ILS', SA:'SAR', AE:'AED', QA:'USD', KW:'USD', BH:'USD', OM:'USD', YE:'USD', JO:'USD', LB:'USD', SY:'USD', IQ:'USD', IR:'USD', TR:'TRY',
    AU:'AUD', NZ:'NZD',
    ZA:'ZAR', NG:'USD', KE:'USD', EG:'EGP', MA:'USD', GH:'USD',
  };

  // ── Withholding-tax rates (royalty income, illustrative).
  const WHT_BY_ISO = {
    US:0.30, GB:0.00, IE:0.20, DE:0.15, FR:0.10, IT:0.30, ES:0.19, NL:0.00, LU:0.00,
    JP:0.20, KR:0.22, CN:0.10, TW:0.20, HK:0.00, SG:0.10,
    AU:0.30, NZ:0.10, CA:0.10, MX:0.25,
    BR:0.15, AR:0.31, CL:0.30, CO:0.20, PE:0.30,
    IN:0.10, RU:0.20, ZA:0.15, IL:0.25,
    SE:0.00, NO:0.00, DK:0.00, FI:0.30, CH:0.00, AT:0.20, BE:0.30, PT:0.25, GR:0.20,
    PL:0.20, CZ:0.15, HU:0.15, RO:0.16,
    AE:0.00, SA:0.15, EG:0.20, TR:0.20,
  };

  // ── Treaty overrides (US payee, common cases). Keyed `${source}->${payee}`.
  // Override the source country's WHT when payee is in a treaty country.
  const TREATY_RATES = {
    'JP->US': 0.10, 'JP->GB': 0.10, 'JP->NL': 0.0, 'JP->IE': 0.10,
    'GB->US': 0.0,
    'DE->US': 0.0, 'DE->GB': 0.05,
    'FR->US': 0.0, 'FR->GB': 0.0,
    'IN->US': 0.15, 'IN->NL': 0.10,
    'BR->US': 0.15,
    'AU->US': 0.05,
    'KR->US': 0.10, 'KR->NL': 0.10,
    'CN->US': 0.10,
  };

  // ── Lookups.
  function ccyOf(iso) {
    return CCY_BY_ISO[iso] || 'USD';
  }
  function whtOf(sourceIso, payeeIso) {
    if (payeeIso) {
      const treaty = TREATY_RATES[`${sourceIso}->${payeeIso}`];
      if (treaty != null) return treaty;
    }
    return WHT_BY_ISO[sourceIso] != null ? WHT_BY_ISO[sourceIso] : 0;
  }

  // ── FX conversion.
  function fxToUsd(ccy, period) {
    // (period ignored — we'd interpolate from a rates table)
    return FX_USD[ccy] != null ? FX_USD[ccy] : 1;
  }
  function convert(amount, fromCcy, toCcy, period) {
    if (!amount) return 0;
    if (fromCcy === toCcy) return amount;
    const usd = amount * fxToUsd(fromCcy, period);
    if (toCcy === 'USD') return usd;
    const rate = fxToUsd(toCcy, period);
    return rate ? usd / rate : 0;
  }

  // ── Format money.
  function fmt(amount, ccy, opts) {
    const o = Object.assign({ short: false, sign: true }, opts || {});
    const sym = symbolOf(ccy);
    const negative = amount < 0;
    const abs = Math.abs(amount);
    let body;
    if (o.short && abs >= 1_000_000) body = (abs / 1_000_000).toFixed(2) + 'M';
    else if (o.short && abs >= 1_000) body = (abs / 1_000).toFixed(1) + 'K';
    else body = abs.toLocaleString('en-US', { maximumFractionDigits: ccy === 'JPY' || ccy === 'KRW' || ccy === 'IDR' || ccy === 'VND' ? 0 : 2, minimumFractionDigits: 0 });
    return (negative && o.sign ? '−' : '') + sym + body;
  }
  function symbolOf(ccy) {
    return { USD:'$', EUR:'€', GBP:'£', JPY:'¥', CNY:'¥', KRW:'₩', INR:'₹', AUD:'A$', NZD:'NZ$', CAD:'C$', MXN:'MX$', BRL:'R$', CHF:'Fr', SEK:'kr', NOK:'kr', DKK:'kr', PLN:'zł', RUB:'₽', TRY:'₺', ILS:'₪', AED:'AED ', SAR:'SAR ' }[ccy] || (ccy + ' ');
  }

  // ── Wallets — a thin map, persistable. Keyed by currency.
  function makeWallet() {
    return { ccy: 'USD', balances: {} }; // balances: { USD: 12345, EUR: 980, ... }
  }
  function depositWallet(w, amount, ccy) {
    w.balances[ccy] = (w.balances[ccy] || 0) + amount;
    return w;
  }
  function totalInReportingCcy(w, reportCcy) {
    let total = 0;
    Object.entries(w.balances).forEach(([ccy, amt]) => {
      total += convert(amt, ccy, reportCcy);
    });
    return total;
  }

  // ── Public API.
  window.TerritoryFx = {
    FX_USD, CCY_BY_ISO, WHT_BY_ISO, TREATY_RATES,
    ccyOf, whtOf, fxToUsd, convert, fmt, symbolOf,
    makeWallet, depositWallet, totalInReportingCcy,
  };
})();
