// Theme helper — dark/light colors, buy/sell, utility formatters

function makeTheme(dark, buyColor) {
  const buy = buyColor === 'blue' ? '#2F80ED' : '#16C784';
  const sell = '#EA3943';
  return {
    dark,
    bg: dark ? '#0B0D10' : '#F2F2F7',
    bgElevated: dark ? '#14171C' : '#FFFFFF',
    bgCard: dark ? '#1A1D22' : '#FFFFFF',
    bgSubtle: dark ? '#0F1114' : '#EDEDF0',
    text: dark ? '#F5F6F8' : '#0B0D10',
    textSec: dark ? 'rgba(235,235,245,0.58)' : 'rgba(60,60,67,0.62)',
    textTer: dark ? 'rgba(235,235,245,0.3)' : 'rgba(60,60,67,0.3)',
    border: dark ? 'rgba(255,255,255,0.07)' : 'rgba(0,0,0,0.08)',
    borderStrong: dark ? 'rgba(255,255,255,0.12)' : 'rgba(0,0,0,0.12)',
    buy,
    sell,
    buyBg: dark ? 'rgba(22,199,132,0.14)' : 'rgba(22,199,132,0.12)',
    sellBg: dark ? 'rgba(234,57,67,0.14)' : 'rgba(234,57,67,0.10)',
    accent: dark ? '#5AC8FA' : '#007AFF',
    tabBarBg: dark ? 'rgba(20,23,28,0.85)' : 'rgba(255,255,255,0.85)',
  };
}

// ——— numeric runs are bidi-isolated (docs/i18n.md ID5) ———
//
// Each formatter below produces a run that must read left-to-right and keep
// its own sign, separators and symbol attached, whatever direction the text
// around it flows. In an RTL paragraph a leading "+"/"-" is a NEUTRAL at a run
// boundary and resolves to the PARAGRAPH direction — "-12.50" renders as
// "12.50-", which is a different number to the reader, not a cosmetic
// difference. "$" and "%" are European Terminators and drift the same way.
//
// bidiIsolate() (i18n.jsx) wraps the run in U+2068…U+2069 under RTL and is the
// identity function otherwise, so the four LTR locales render byte-identical
// output to F-i18n-1. It is reached through `window` because theme.jsx loads
// BEFORE i18n.jsx in both shells; by the time any of these runs at render time
// the export is in place, and the fallback keeps a formatter from throwing if
// that load order ever changes.
//
// splitPrice/splitPip return the PARTS of one price for the fractional-pip
// visual, which the caller renders as adjacent elements. Neither isolates its
// parts, and neither may: isolating each part separately would let the pieces
// reorder against each other. The isolate belongs on the element wrapping all
// of them, and the call sites carry `unicodeBidi: 'isolate'`.
//
// The corollary is a trap worth naming, because splitPrice fell into it: a
// splitter must compute from the RAW formatted number, never from fmtPrice().
// fmtPrice returns an ISOLATED run under RTL, so slicing its output counts the
// invisible U+2069 as a digit (shifting the big-pip emphasis one place) and
// tears the pair apart — leaving U+2068 in `big` and U+2069 in `small`, an
// unmatched initiator whose scope then runs to the end of the paragraph.
// splitPip was always right about this; splitPrice now matches it.
function iso(s) { return window.bidiIsolate ? window.bidiIsolate(s) : s; }

function fmtPrice(n, digits) {
  return iso(n.toLocaleString('en-US', { minimumFractionDigits: digits, maximumFractionDigits: digits }));
}

function fmtPct(n) {
  const s = n >= 0 ? '+' : '';
  return iso(s + n.toFixed(2) + '%');
}

function fmtMoney(n, dp = 2) {
  const s = n >= 0 ? '+' : '-';
  return iso(s + '$' + Math.abs(n).toLocaleString('en-US', { minimumFractionDigits: dp, maximumFractionDigits: dp }));
}

// Split a price into big/small parts for the "fractional pip" visual
function splitPrice(n, digits) {
  // Raw, NOT fmtPrice() — see the trap in the header comment above.
  const str = n.toLocaleString('en-US', { minimumFractionDigits: digits, maximumFractionDigits: digits });
  // big part = integer + first (digits-1) decimals, small = last decimal
  if (digits === 0) return { big: str, small: '' };
  const [intPart, decPart] = str.split('.');
  const smallN = Math.max(1, Math.min(2, digits)); // last 1-2 digits are "big pip" emphasized
  const emphasize = decPart.slice(-smallN);
  const rest = decPart.slice(0, decPart.length - smallN);
  return { big: intPart + (rest ? '.' + rest : '.'), small: emphasize };
}

// 3-part price split driven by pipDigits (ui_pip_size) vs digits (tick_size):
//   base price · significant pips (2 digits) · fractional pip (sub-pip ticks)
//   e.g. EURUSD 1.07833  →  { base: "1.07", pips: "83", frac: "3" }
function splitPip(value, digits, pipDigits) {
  if (pipDigits == null) pipDigits = digits;
  const fixed = value.toFixed(digits);
  const dot = fixed.indexOf('.');
  const intRaw = dot === -1 ? fixed : fixed.slice(0, dot);
  const dec = dot === -1 ? '' : fixed.slice(dot + 1);
  const intp = Number(intRaw).toLocaleString('en-US'); // thousands separators
  const fracCount = Math.max(0, digits - pipDigits);       // sub-pip (tick) digits
  const pipBlockEnd = dec.length - fracCount;
  const frac = fracCount > 0 ? dec.slice(pipBlockEnd) : '';
  const sigCount = Math.min(2, pipBlockEnd);                // up to 2 significant pip digits
  const pips = dec.slice(pipBlockEnd - sigCount, pipBlockEnd);
  const baseDec = dec.slice(0, pipBlockEnd - sigCount);
  const base = intp + (dec.length ? '.' : '') + baseDec;
  return { base, pips, frac };
}

Object.assign(window, { makeTheme, fmtPrice, fmtPct, fmtMoney, splitPrice, splitPip });
