// ============================================================================
// ScreenTerritory — control center for multi-territory operations.
//
// Tabs:
//   01 EXPLORER    — picker playground + live ISO resolution + conflicts
//   02 BLOCS       — manage custom blocs (Tier 1, regional groupings)
//   03 FX          — multi-currency rates + reporting-currency toggle
//   04 WITHHOLDING — per-territory tax rates incl. treaty overrides
//   05 CONFLICTS   — scan all agreements for territory × right × period overlaps
//   06 COVERAGE    — choropleth of catalog earnings per territory
//
// EXPORT: window.ScreenTerritory
// ============================================================================
(function () {
  const { useState, useMemo, useEffect } = React;

  function ScreenTerritory({ go }) {
    const [tab, setTab] = useState('blocs');
    const tabs = [
      ['blocs', 'Custom blocs'],
      ['fx',   'FX rates'],
      ['wht',  'Withholding'],
    ];

    return (
      <div style={{ display: 'flex', flexDirection: 'column', gap: 0 }}>
        <header style={{ borderBottom: '1px solid var(--rule)', paddingBottom: 16, marginBottom: 20 }}>
          <div className="ff-mono" style={{ fontSize: 10, letterSpacing: 1.5, color: 'var(--ink-3)', textTransform: 'uppercase' }}>Tools · Territories</div>
          <h1 style={{ fontSize: 36, margin: '6px 0 4px', fontWeight: 400 }}>Territories &amp; FX</h1>
          <div style={{ color: 'var(--ink-2)', fontSize: 13, maxWidth: 720 }}>Configure custom blocs, reporting currency, and withholding overrides. Conflicts now appear inline on each agreement and in your Inbox; coverage lives in <a onClick={() => go && go('analytics', { tab: 'market' })} style={{ color: 'var(--ink)', cursor: 'pointer', textDecoration: 'underline', textDecorationStyle: 'dotted' }}>Analytics &rarr; Market</a>.</div>
        </header>
        <nav style={{ display: 'flex', gap: 0, borderBottom: '1px solid var(--rule)', marginBottom: 20 }}>
          {tabs.map(([k, l]) => (
            <button key={k} onClick={() => setTab(k)} className="ff-mono"
              style={{
                padding: '10px 16px', fontSize: 11, letterSpacing: 1, textTransform: 'uppercase',
                background: 'transparent', border: 'none',
                borderBottom: tab === k ? '2px solid var(--ink)' : '2px solid transparent',
                color: tab === k ? 'var(--ink)' : 'var(--ink-3)', cursor: 'pointer',
              }}>{l}</button>
          ))}
        </nav>
        {tab === 'blocs' && <BlocsTab />}
        {tab === 'fx'    && <FxTab />}
        {tab === 'wht'   && <WhtTab />}
      </div>
    );
  }

  // ── Tab 1: Explorer ─────────────────────────────────────────────────────
  function ExplorerTab() {
    const [sel, setSel] = useState({ mode: 'list', codes: ['EU', 'JP', 'US'], excludes: [] });
    const eng = window.TerritoryEngine;
    const { isos, label } = eng.resolveSelection(sel);
    const fx = window.TerritoryFx;

    return (
      <div style={{ display: 'grid', gridTemplateColumns: '1fr 380px', gap: 24 }}>
        <div>
          <div className="ff-mono upper" style={{ fontSize: 9, color: 'var(--ink-3)', letterSpacing: '.12em', marginBottom: 8 }}>SELECTION</div>
          {window.TerritoryPicker && <window.TerritoryPicker selection={sel} onChange={setSel} />}
        </div>
        <aside>
          <div className="ff-mono upper" style={{ fontSize: 9, color: 'var(--ink-3)', letterSpacing: '.12em', marginBottom: 8 }}>RESOLVED</div>
          <div style={{ border: '1px solid var(--rule)', padding: 14, background: 'var(--bg-2)' }}>
            <div style={{ fontSize: 13, marginBottom: 6 }}>{label}</div>
            <div className="ff-mono num" style={{ fontSize: 24, fontWeight: 600 }}>{isos.size} <span style={{ fontSize: 11, color: 'var(--ink-3)' }}>ISO countries</span></div>
            <div style={{ display: 'flex', flexWrap: 'wrap', gap: 4, marginTop: 12, maxHeight: 220, overflow: 'auto' }}>
              {Array.from(isos).sort().map(iso => (
                <span key={iso} className="ff-mono" style={{ fontSize: 10, padding: '2px 5px', background: 'var(--bg)', border: '1px solid var(--rule)' }}>
                  {eng.flagOf(iso)} {iso}
                </span>
              ))}
            </div>
          </div>
          <div className="ff-mono upper" style={{ fontSize: 9, color: 'var(--ink-3)', letterSpacing: '.12em', margin: '20px 0 8px' }}>JSON</div>
          <pre style={{ background: 'var(--bg-2)', border: '1px solid var(--rule)', padding: 10, fontSize: 10, fontFamily: 'IBM Plex Mono, monospace', overflow: 'auto' }}>{JSON.stringify(sel, null, 2)}</pre>
          <div className="ff-mono upper" style={{ fontSize: 9, color: 'var(--ink-3)', letterSpacing: '.12em', margin: '20px 0 8px' }}>CURRENCY MIX</div>
          <div>
            {currencyMix(isos).map(([ccy, count]) => (
              <div key={ccy} style={{ display: 'flex', justifyContent: 'space-between', padding: '4px 0', borderBottom: '1px solid var(--rule-soft)' }}>
                <span className="ff-mono" style={{ fontSize: 11 }}>{fx.symbolOf(ccy)} {ccy}</span>
                <span className="ff-mono num" style={{ fontSize: 11, color: 'var(--ink-3)' }}>{count} territory{count > 1 ? 'ies' : 'y'}</span>
              </div>
            ))}
          </div>
        </aside>
      </div>
    );
  }
  function currencyMix(isos) {
    const fx = window.TerritoryFx;
    const m = new Map();
    Array.from(isos).forEach(iso => {
      const ccy = fx.ccyOf(iso);
      m.set(ccy, (m.get(ccy) || 0) + 1);
    });
    return Array.from(m.entries()).sort((a, b) => b[1] - a[1]);
  }

  // ── Tab 2: Custom Blocs ─────────────────────────────────────────────────
  function BlocsTab() {
    const eng = window.TerritoryEngine;
    const [tick, setTick] = useState(0);
    const customs = Object.values(eng.customBlocs);
    const [draft, setDraft] = useState({ code: '', label: '', leaves: [] });
    const [sel, setSel] = useState({ mode: 'list', codes: [], excludes: [] });

    function save() {
      if (!draft.code || !draft.label) return;
      const isos = Array.from(eng.resolveSelection(sel).isos);
      eng.saveCustomBloc(draft.code.toUpperCase(), draft.label, isos);
      setDraft({ code: '', label: '', leaves: [] });
      setSel({ mode: 'list', codes: [], excludes: [] });
      setTick(t => t + 1);
    }
    function del(code) {
      eng.deleteCustomBloc(code);
      setTick(t => t + 1);
    }

    return (
      <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 24 }}>
        <div>
          <div className="ff-mono upper" style={{ fontSize: 9, color: 'var(--ink-3)', letterSpacing: '.12em', marginBottom: 8 }}>YOUR BLOCS · {customs.length}</div>
          {customs.length === 0 && (
            <div style={{ padding: 24, border: '1px dashed var(--rule)', textAlign: 'center', color: 'var(--ink-3)' }}>
              No custom blocs yet. Pre-fab blocs (EU, GSA, Nordics, ANZ, …) are always available.
            </div>
          )}
          {customs.map(b => (
            <div key={b.code} style={{ border: '1px solid var(--rule)', padding: 12, marginBottom: 10 }}>
              <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start' }}>
                <div>
                  <div className="ff-mono num" style={{ fontSize: 12, fontWeight: 600 }}>{b.code}</div>
                  <div style={{ fontSize: 14, fontWeight: 500 }}>{b.label}</div>
                </div>
                <button onClick={() => del(b.code)} className="ff-mono upper" style={{ fontSize: 9, padding: '2px 6px', color: 'var(--danger)', background: 'transparent', border: '1px solid var(--danger)' }}>delete</button>
              </div>
              <div style={{ display: 'flex', flexWrap: 'wrap', gap: 4, marginTop: 8 }}>
                {b.leaves.map(iso => (
                  <span key={iso} className="ff-mono" style={{ fontSize: 10, padding: '2px 5px', background: 'var(--bg-2)' }}>
                    {eng.flagOf(iso)} {iso}
                  </span>
                ))}
              </div>
            </div>
          ))}
        </div>
        <div>
          <div className="ff-mono upper" style={{ fontSize: 9, color: 'var(--ink-3)', letterSpacing: '.12em', marginBottom: 8 }}>NEW BLOC</div>
          <div style={{ display: 'grid', gridTemplateColumns: '120px 1fr', gap: 10, marginBottom: 12 }}>
            <input value={draft.code} onChange={e => setDraft({ ...draft, code: e.target.value.toUpperCase().slice(0, 12) })} placeholder="CODE" className="ff-mono"
              style={{ padding: '6px 10px', fontSize: 12, background: 'var(--bg)', border: '1px solid var(--rule)', boxSizing: 'border-box' }} />
            <input value={draft.label} onChange={e => setDraft({ ...draft, label: e.target.value })} placeholder="Display name (e.g. 'Tier 1 markets')"
              style={{ padding: '6px 10px', fontSize: 12, background: 'var(--bg)', border: '1px solid var(--rule)', boxSizing: 'border-box' }} />
          </div>
          {window.TerritoryPicker && <window.TerritoryPicker selection={sel} onChange={setSel} />}
          <button onClick={save} disabled={!draft.code || !draft.label || eng.resolveSelection(sel).isos.size === 0}
            className="ff-mono upper"
            style={{
              marginTop: 12, padding: '8px 14px', fontSize: 11, letterSpacing: '.12em',
              background: 'var(--ink)', color: 'var(--bg)', border: 'none',
              opacity: draft.code && draft.label && eng.resolveSelection(sel).isos.size > 0 ? 1 : 0.4,
              cursor: 'pointer',
            }}>+ Save bloc</button>
        </div>
      </div>
    );
  }

  // ── Tab 3: FX rates ─────────────────────────────────────────────────────
  function FxTab() {
    const fx = window.TerritoryFx;
    const [reportCcy, setReportCcy] = useState(localStorage.getItem('astro_report_ccy') || 'USD');
    useEffect(() => { try { localStorage.setItem('astro_report_ccy', reportCcy); } catch {} }, [reportCcy]);
    const ccys = Object.keys(fx.FX_USD).sort();

    return (
      <div>
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 16 }}>
          <div>
            <div className="ff-mono upper" style={{ fontSize: 9, color: 'var(--ink-3)', letterSpacing: '.12em', marginBottom: 4 }}>REPORTING CURRENCY</div>
            <select value={reportCcy} onChange={e => setReportCcy(e.target.value)}
              style={{ padding: '6px 10px', fontSize: 13, background: 'var(--bg)', border: '1px solid var(--rule)' }}>
              {ccys.map(c => <option key={c} value={c}>{fx.symbolOf(c)} {c}</option>)}
            </select>
          </div>
          <div className="ff-mono" style={{ fontSize: 11, color: 'var(--ink-3)' }}>
            {ccys.length} currencies · rates per USD as of period close
          </div>
        </div>

        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(160px, 1fr))', gap: 8 }}>
          {ccys.map(ccy => {
            const rate = fx.convert(1, reportCcy, ccy);
            return (
              <div key={ccy} style={{ border: '1px solid var(--rule)', padding: 10 }}>
                <div className="ff-mono upper" style={{ fontSize: 9, color: 'var(--ink-3)', letterSpacing: '.1em' }}>{fx.symbolOf(ccy)}{ccy}</div>
                <div className="ff-mono num" style={{ fontSize: 16, fontWeight: 600, marginTop: 2 }}>{rate.toLocaleString('en-US', { maximumFractionDigits: ccy === 'JPY' || ccy === 'KRW' || ccy === 'IDR' || ccy === 'VND' ? 1 : 4 })}</div>
                <div className="ff-mono" style={{ fontSize: 10, color: 'var(--ink-3)' }}>per 1 {reportCcy}</div>
              </div>
            );
          })}
        </div>

        <div className="ff-mono upper" style={{ fontSize: 9, color: 'var(--ink-3)', letterSpacing: '.12em', margin: '24px 0 8px' }}>WALLET MODE</div>
        <div style={{ border: '1px solid var(--rule)', padding: 14, background: 'var(--bg-2)' }}>
          <p style={{ fontSize: 12, color: 'var(--ink-2)', margin: 0, lineHeight: 1.5 }}>
            Statements arrive in the source currency and stay there until withdrawal — keeping you in control of FX timing.
            Reporting views consolidate into <span className="ff-mono">{reportCcy}</span> at period-close rates.
          </p>
        </div>
      </div>
    );
  }

  // ── Tab 4: Withholding ──────────────────────────────────────────────────
  function WhtTab() {
    const fx = window.TerritoryFx;
    const eng = window.TerritoryEngine;
    const [payee, setPayee] = useState('US');
    const isos = Object.keys(fx.WHT_BY_ISO).sort();

    return (
      <div>
        <div style={{ marginBottom: 16 }}>
          <div className="ff-mono upper" style={{ fontSize: 9, color: 'var(--ink-3)', letterSpacing: '.12em', marginBottom: 4 }}>PAYEE TAX RESIDENCE</div>
          <select value={payee} onChange={e => setPayee(e.target.value)}
            style={{ padding: '6px 10px', fontSize: 13, background: 'var(--bg)', border: '1px solid var(--rule)' }}>
            {['US', 'GB', 'IE', 'NL', 'DE', 'FR', 'JP', 'KR', 'AU', 'CA'].map(c => (
              <option key={c} value={c}>{eng.flagOf(c)} {c} · {eng.labelOf(c)}</option>
            ))}
          </select>
          <span className="ff-mono" style={{ fontSize: 11, color: 'var(--ink-3)', marginLeft: 16 }}>Treaty rates apply where bilateral conventions exist.</span>
        </div>

        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(180px, 1fr))', gap: 8 }}>
          {isos.map(iso => {
            const stat = fx.WHT_BY_ISO[iso];
            const eff = fx.whtOf(iso, payee);
            const reduced = eff < stat;
            return (
              <div key={iso} style={{ border: '1px solid ' + (reduced ? 'var(--ok)' : 'var(--rule)'), padding: 10 }}>
                <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline' }}>
                  <span className="ff-mono" style={{ fontSize: 12, fontWeight: 600 }}>{eng.flagOf(iso)} {iso}</span>
                  {reduced && <span className="ff-mono upper" style={{ fontSize: 8, padding: '1px 4px', background: 'var(--ok)', color: 'var(--bg)', letterSpacing: '.1em' }}>TREATY</span>}
                </div>
                <div className="ff-mono num" style={{ fontSize: 18, fontWeight: 600, marginTop: 4 }}>{(eff * 100).toFixed(0)}%</div>
                {reduced && <div className="ff-mono" style={{ fontSize: 10, color: 'var(--ink-3)' }}>statutory {(stat * 100).toFixed(0)}%</div>}
                <div className="ff-mono" style={{ fontSize: 9, color: 'var(--ink-3)', marginTop: 2 }}>{eng.labelOf(iso)}</div>
              </div>
            );
          })}
        </div>
      </div>
    );
  }

  // ── Tab 5: Conflicts ────────────────────────────────────────────────────
  function ConflictsTab({ go }) {
    const eng = window.TerritoryEngine;
    const agreements = window.AGREEMENTS || [];

    // Group by work / counterparty + scan for territory × right × period overlaps.
    const conflicts = useMemo(() => {
      // Build comparable rows from agreements
      const rows = agreements
        .filter(a => a.territories && a.territories.length)
        .flatMap(a => (a.territories || []).map((t, i) => ({
          id: `${a.id}#${i}`,
          agreementId: a.id,
          name: a.name,
          counterparty: a.b || a.counterparty,
          selection: { mode: t.code === 'WW' ? 'world' : 'list', codes: t.code === 'WW' ? [] : [t.code], excludes: t.excluded || [] },
          rights: (t.rights || '').split(/[+,/·]/).map(s => s.trim()).filter(Boolean),
          start: a.start, end: a.end,
        })));
      return eng.findConflicts(rows).slice(0, 50);
    }, [agreements]);

    return (
      <div>
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', marginBottom: 16 }}>
          <div className="ff-mono upper" style={{ fontSize: 10, letterSpacing: '.1em', color: 'var(--ink-3)' }}>{conflicts.length} conflicts found across {agreements.length} agreements</div>
          {conflicts.length === 0 && <span className="ff-mono" style={{ fontSize: 11, color: 'var(--ok)' }}>✓ no overlaps</span>}
        </div>

        {conflicts.length === 0 ? (
          <div style={{ padding: 36, border: '1px dashed var(--rule)', textAlign: 'center', color: 'var(--ink-3)' }}>
            No territory × right × period conflicts in the active catalog.
          </div>
        ) : (
          <div style={{ border: '1px solid var(--rule)' }}>
            <div className="ff-mono upper" style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1.5fr 0.8fr 100px', gap: 10, padding: '8px 12px', fontSize: 9, letterSpacing: '.12em', color: 'var(--ink-3)', borderBottom: '1px solid var(--rule)', background: 'var(--bg-2)' }}>
              <span>AGREEMENT A</span><span>AGREEMENT B</span><span>OVERLAP</span><span>RIGHTS</span><span style={{ textAlign: 'right' }}>SEVERITY</span>
            </div>
            {conflicts.map((c, i) => (
              <div key={i} style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1.5fr 0.8fr 100px', gap: 10, padding: '10px 12px', borderBottom: '1px solid var(--rule-soft)', alignItems: 'center', fontSize: 12 }}>
                <button onClick={() => go && go('agreement', { id: c.a.split('#')[0] })} className="ff-mono" style={{ textAlign: 'left', color: 'var(--ink)' }}>{c.a.split('#')[0]}</button>
                <button onClick={() => go && go('agreement', { id: c.b.split('#')[0] })} className="ff-mono" style={{ textAlign: 'left', color: 'var(--ink)' }}>{c.b.split('#')[0]}</button>
                <div>
                  <div className="ff-mono num" style={{ fontSize: 11, color: 'var(--ink-3)', marginBottom: 2 }}>{c.isos.length} ISO</div>
                  <div style={{ display: 'flex', flexWrap: 'wrap', gap: 3 }}>
                    {c.isos.slice(0, 8).map(iso => (
                      <span key={iso} className="ff-mono" style={{ fontSize: 10, padding: '1px 5px', background: 'var(--bg-2)' }}>{eng.flagOf(iso)} {iso}</span>
                    ))}
                    {c.isos.length > 8 && <span className="ff-mono" style={{ fontSize: 10, color: 'var(--ink-3)' }}>+{c.isos.length - 8}</span>}
                  </div>
                </div>
                <span className="ff-mono" style={{ fontSize: 10 }}>{c.rights.join('+')}</span>
                <span className="ff-mono upper" style={{ fontSize: 9, color: c.isos.length > 5 ? 'var(--danger)' : 'var(--accent)', textAlign: 'right' }}>{c.isos.length > 5 ? 'BLOCK' : 'WARN'}</span>
              </div>
            ))}
          </div>
        )}
      </div>
    );
  }

  // ── Tab 6: Coverage choropleth ───────────────────────────────────────────
  function CoverageTab() {
    const eng = window.TerritoryEngine;
    const fx = window.TerritoryFx;
    // Earnings per ISO from statements (synthesize if missing).
    const earnings = useMemo(() => coverageData(), []);
    const max = Math.max(1, ...Object.values(earnings));

    function color(v) {
      if (!v) return 'var(--bg)';
      const t = v / max;
      // 5-step ramp from --bg-2 to --ink
      if (t > 0.8) return 'var(--ink)';
      if (t > 0.6) return 'oklch(35% 0.02 240)';
      if (t > 0.4) return 'oklch(50% 0.02 240)';
      if (t > 0.2) return 'oklch(65% 0.02 240)';
      return 'oklch(80% 0.02 240)';
    }

    const top = Object.entries(earnings).sort((a, b) => b[1] - a[1]).slice(0, 12);

    return (
      <div style={{ display: 'grid', gridTemplateColumns: '1fr 320px', gap: 24 }}>
        <div>
          <div className="ff-mono upper" style={{ fontSize: 9, color: 'var(--ink-3)', letterSpacing: '.12em', marginBottom: 8 }}>EARNINGS BY TERRITORY · last 4 quarters</div>
          <div style={{ border: '1px solid var(--rule)', padding: 14, background: 'var(--bg-2)' }}>
            <Choropleth values={earnings} colorOf={color} />
          </div>
        </div>
        <aside>
          <div className="ff-mono upper" style={{ fontSize: 9, color: 'var(--ink-3)', letterSpacing: '.12em', marginBottom: 8 }}>TOP 12</div>
          {top.map(([iso, v]) => (
            <div key={iso} style={{ display: 'grid', gridTemplateColumns: '1fr auto', gap: 10, padding: '7px 0', borderBottom: '1px solid var(--rule-soft)' }}>
              <span className="ff-mono" style={{ fontSize: 12 }}>{eng.flagOf(iso)} {iso} <span style={{ color: 'var(--ink-3)', marginLeft: 4 }}>{eng.labelOf(iso)}</span></span>
              <span className="ff-mono num" style={{ fontSize: 12, fontWeight: 600, textAlign: 'right' }}>{fx.fmt(v, 'USD', { short: true })}</span>
            </div>
          ))}
        </aside>
      </div>
    );
  }

  // Synthesize earnings per ISO from statements / catalog.
  function coverageData() {
    const out = {};
    const stmts = (window.STATEMENTS || []);
    stmts.forEach(s => {
      const iso = (s.country || s.territory || '').slice(0, 2).toUpperCase();
      if (!iso) return;
      out[iso] = (out[iso] || 0) + (s.gross || s.amount || 0);
    });
    if (Object.keys(out).length < 5) {
      // Fallback synthetic
      const seed = ['US', 'GB', 'DE', 'FR', 'JP', 'AU', 'CA', 'BR', 'MX', 'NL', 'IT', 'ES', 'KR', 'IN', 'SE', 'NO', 'DK', 'PL', 'IE', 'SG'];
      seed.forEach((iso, i) => { out[iso] = (out[iso] || 0) + Math.round(180000 * Math.exp(-i * 0.18) + Math.random() * 20000); });
    }
    return out;
  }

  // ── Choropleth — same tile grid as TerritoryMap, value-shaded.
  function Choropleth({ values, colorOf }) {
    const eng = window.TerritoryEngine;
    const fx = window.TerritoryFx;
    const [hover, setHover] = useState(null);
    // Same grid as TerritoryMap.
    const GRID = window.__TM_GRID || ([
      'IS,GL,,,,,,,,,,,,,,,,,,,,RU,RU,RU',
      'NO,SE,FI,EE,LV,LT,BY,RU,RU,RU,MN,,,,,,,,,,,,,',
      'IE,GB,DK,NL,DE,PL,UA,MD,GE,AM,AZ,TM,UZ,KZ,KG,TJ,CN,KP,KR,JP,,,,',
      'PT,ES,FR,BE,LU,CH,AT,CZ,SK,HU,RO,BG,TR,IR,AF,PK,NP,BT,BD,MM,TW,HK,,',
      ',,MA,IT,SM,HR,SI,RS,BA,ME,AL,MK,GR,CY,SY,LB,IL,JO,IQ,SA,QA,AE,OM,YE',
      ',EH,DZ,TN,LY,EG,SD,ER,DJ,SO,ET,UG,KE,TZ,RW,BI,,IN,LK,MV,TH,VN,PH,',
      ',,MR,ML,NE,TD,CF,SS,,,,,,,,,,LA,KH,MY,SG,BN,ID,',
      ',,SN,GM,GN,BF,BJ,NG,CM,GA,CG,CD,AO,ZM,MW,MZ,ZW,BW,NA,MG,,,PG,',
      ',,,,GH,TG,,,,,,,,,,,,ZA,LS,SZ,,,,',
      ',,US,US,US,US,CA,CA,CA,,,,,,,,,,,AU,NZ,,,',
      'CU,BS,MX,GT,HN,SV,NI,CR,PA,CO,VE,GY,SR,BR,BR,BR,BR,,,,NC,FJ,,',
      ',,,EC,PE,BO,PY,CL,AR,UY,,,,,,,,,,,,,,',
    ]);
    const cols = 24;
    const cellW = 30, cellH = 26;
    return (
      <div style={{ position: 'relative' }}>
        <svg width={cols * cellW} height={GRID.length * cellH} style={{ display: 'block', maxWidth: '100%' }}>
          {GRID.map((row, y) => row.split(',').map((iso, x) => {
            if (!iso) return null;
            const v = values[iso] || 0;
            const fill = colorOf(v);
            return (
              <g key={`${x}-${y}-${iso}`} transform={`translate(${x * cellW}, ${y * cellH})`}
                 onMouseEnter={() => setHover({ iso, v })} onMouseLeave={() => setHover(null)}>
                <rect x={1} y={1} width={cellW - 2} height={cellH - 2} fill={fill} stroke="var(--rule)" strokeWidth={0.5} />
                <text x={cellW / 2} y={cellH / 2 + 4} textAnchor="middle" fontSize={9} fontFamily="IBM Plex Mono, monospace" fill={v ? 'var(--bg)' : 'var(--ink-3)'}>{iso}</text>
              </g>
            );
          }))}
        </svg>
        {hover && hover.iso && (
          <div style={{ position: 'absolute', bottom: 8, right: 12, padding: '6px 10px', background: 'var(--ink)', color: 'var(--bg)', fontSize: 11, fontFamily: 'IBM Plex Mono, monospace' }}>
            {eng.flagOf(hover.iso)} {hover.iso} · {eng.labelOf(hover.iso)} · {fx.fmt(hover.v, 'USD', { short: true })}
          </div>
        )}
      </div>
    );
  }

  window.ScreenTerritory = ScreenTerritory;
  window.Choropleth = Choropleth;
})();
