// currency.jsx — client mirror of server/sales/currency.js (browser global, no bundler).
//
// Single source of money formatting for every screen. Replaces the ~12 per-screen
// helpers that hardcoded "SAR"/"ر.س". Reads the operator's default currency + manual
// exchange rates from the live store (window.DATA.SETTINGS) at call time, so a record
// that carries its own `currency` is shown in that currency, and bare totals fall back
// to the global default. Honest: convert() returns null when no rate is configured —
// callers then show grouped-by-currency totals, never a fabricated number.

const MC_SUPPORTED = ["SAR", "USD", "EUR", "CAD", "AED"];
const MC_DEFAULT = "SAR";
const MC_META = {
  SAR: { code: "SAR", en: "SAR", ar: "ر.س", nameEn: "Saudi Riyal", nameAr: "ريال سعودي" },
  USD: { code: "USD", en: "USD", ar: "دولار", nameEn: "US Dollar", nameAr: "دولار أمريكي" },
  EUR: { code: "EUR", en: "EUR", ar: "يورو", nameEn: "Euro", nameAr: "يورو" },
  CAD: { code: "CAD", en: "CAD", ar: "دولار كندي", nameEn: "Canadian Dollar", nameAr: "دولار كندي" },
  AED: { code: "AED", en: "AED", ar: "درهم", nameEn: "UAE Dirham", nameAr: "درهم إماراتي" },
};

function mcNum(v) { const n = Number(v); return isFinite(n) ? n : 0; }
function mcNormalize(code) { const c = String(code || "").trim().toUpperCase(); return MC_SUPPORTED.includes(c) ? c : MC_DEFAULT; }
function mcSettings() { return (window.DATA && window.DATA.SETTINGS) || {}; }
function mcDefaultCurrency() { return mcNormalize(mcSettings().companyDefaultCurrency); }
function mcCompanyCurrency() { const s = mcSettings(); return mcNormalize(s.companyCurrency || s.companyDefaultCurrency); }
function mcRates() { const r = mcSettings().exchangeRates; return (r && typeof r === "object") ? r : {}; }
function mcRateToBase(code, rates) {
  const c = mcNormalize(code);
  if (c === "SAR") return 1;
  const r = rates && rates[c];
  return (typeof r === "number" && isFinite(r) && r > 0) ? r : null;
}
function mcConvert(amount, from, to, rates) {
  rates = rates || mcRates();
  const f = mcNormalize(from), t = mcNormalize(to), a = mcNum(amount);
  if (f === t) return a;
  const rf = mcRateToBase(f, rates), rt = mcRateToBase(t, rates);
  if (rf == null || rt == null) return null;
  return (a * rf) / rt;
}
function mcGroupByCurrency(records, amountFn, currencyFn) {
  const out = {};
  (Array.isArray(records) ? records : []).forEach((r) => {
    if (!r) return;
    const cur = mcNormalize(typeof currencyFn === "function" ? currencyFn(r) : r.currency);
    const amt = mcNum(typeof amountFn === "function" ? amountFn(r) : r.amount);
    out[cur] = (out[cur] || 0) + amt;
  });
  Object.keys(out).forEach((k) => { out[k] = Math.round(out[k]); });
  return out;
}
function mcSumSafe(records, amountFn, currencyFn, opts) {
  opts = opts || {};
  const byCurrency = mcGroupByCurrency(records, amountFn, currencyFn);
  const currencies = Object.keys(byCurrency);
  const target = mcNormalize(opts.targetCurrency || mcDefaultCurrency());
  const rates = opts.rates || mcRates();
  if (currencies.length === 0) return { total: 0, currency: target, mixed: false, converted: false, byCurrency, currencies };
  if (currencies.length === 1) return { total: byCurrency[currencies[0]], currency: currencies[0], mixed: false, converted: false, byCurrency, currencies };
  let total = 0, ok = true;
  for (const c of currencies) { const v = mcConvert(byCurrency[c], c, target, rates); if (v == null) { ok = false; break; } total += v; }
  if (ok) return { total: Math.round(total), currency: target, mixed: true, converted: true, byCurrency, currencies };
  return { total: null, currency: target, mixed: true, converted: false, byCurrency, currencies };
}

// THE formatter every screen calls. amount rounded; currency defaults to the operator
// default; lang "ar" → "10,000 ر.س" (SAR) / "10,000 USD" (others), else "SAR 10,000".
function fmtCurrency(amount, currency, lang) {
  const cur = mcNormalize(currency || mcDefaultCurrency());
  const n = Math.round(mcNum(amount)).toLocaleString("en-US");
  const meta = MC_META[cur];
  return lang === "ar" ? `${n} ${meta.ar}` : `${meta.en} ${n}`;
}
// Compact form for dashboard cards (e.g. "SAR 1.2M") so larger non-SAR numbers don't overflow.
function fmtCurrencyCompact(amount, currency, lang) {
  const cur = mcNormalize(currency || mcDefaultCurrency());
  const meta = MC_META[cur];
  const v = Math.round(mcNum(amount));
  const abs = Math.abs(v);
  let short;
  if (abs >= 1e6) short = (v / 1e6).toFixed(v % 1e6 === 0 ? 0 : 1) + "M";
  else if (abs >= 1e3) short = (v / 1e3).toFixed(v % 1e3 === 0 ? 0 : 1) + "K";
  else short = String(v);
  return lang === "ar" ? `${short} ${meta.ar}` : `${meta.en} ${short}`;
}
function currencyLabel(currency, lang) { const m = MC_META[mcNormalize(currency)]; return lang === "ar" ? m.ar : m.en; }

window.MaxabCurrency = {
  SUPPORTED: MC_SUPPORTED, DEFAULT: MC_DEFAULT, META: MC_META,
  normalize: mcNormalize, defaultCurrency: mcDefaultCurrency, companyCurrency: mcCompanyCurrency,
  rates: mcRates, convert: mcConvert, groupByCurrency: mcGroupByCurrency, sumSafe: mcSumSafe,
  format: fmtCurrency, formatCompact: fmtCurrencyCompact, label: currencyLabel,
};
// Convenience globals every screen can call directly (top-level decls are global at runtime).
window.fmtCurrency = fmtCurrency;
window.fmtCurrencyCompact = fmtCurrencyCompact;
window.currencyLabel = currencyLabel;
