// ============================================================================
// TERRITORY-BRIDGE — wires the territory engine into existing screens.
//
// Components:
//   <AgreementTerritoryConflicts ag /> — banner above territories list, shows
//     overlap warnings vs other agreements covering the same counterparty/work.
//   <AgreementTerritoryFooter ag />    — ISO breakdown + currency mix +
//     reversion-per-territory clocks, below the territories list.
//   <PayoutWithholdingChip iso payeeIso amount /> — inline chip showing
//     statutory vs treaty WHT for a payout cell.
//
// Plus side-effects:
//   ANALYTICS: registers a `territory` dimension that resolves to ISO from
//   any catalog item via TerritoryFx.ccyOf and statement.country.
//
// EXPORT: window.AgreementTerritoryConflicts,
//         window.AgreementTerritoryFooter,
//         window.PayoutWithholdingChip
// ============================================================================
(function () {
  const { useMemo, useState } = React;

  // ── Build comparable rows for an agreement (one row per territory entry).
  function rowsFor(ag) {
    return (ag.territories || []).map((t, i) => ({
      id: `${ag.id}#${i}`,
      agreementId: ag.id,
      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: ag.start,
      end: ag.end,
    }));
  }

  // ── Conflicts banner.
  function AgreementTerritoryConflicts({ ag }) {
    const eng = window.TerritoryEngine;
    if (!eng || !ag) return null;
    const all = window.AGREEMENTS || [];

    const conflicts = useMemo(() => {
      const myRows = rowsFor(ag);
      const others = all.filter(x => x.id !== ag.id && (x.b === ag.b || x.counterparty === ag.counterparty));
      // Build comparison rows
      const otherRows = others.flatMap(rowsFor);
      const out = [];
      for (const a of myRows) {
        for (const b of otherRows) {
          if (!eng.periodsOverlap(a.start, a.end, b.start, b.end)) continue;
          const sharedRights = (a.rights.length ? a.rights : ['ALL']).filter(r => (b.rights.length ? b.rights : ['ALL']).includes(r) || b.rights.length === 0 || a.rights.length === 0);
          if (!sharedRights.length) continue;
          const isos = eng.overlap(a.selection, b.selection);
          if (!isos.length) continue;
          out.push({ otherAg: b.agreementId, isos, rights: sharedRights });
        }
      }
      return out.slice(0, 6);
    }, [ag.id, ag.territories, ag.start, ag.end, all.length]);

    if (conflicts.length === 0) {
      return (
        <div style={{ display: 'flex', alignItems: 'center', gap: 10, padding: '8px 14px', borderBottom: '1px solid var(--rule)', background: 'var(--bg-2)' }}>
          <span className="ff-mono upper" style={{ fontSize: 9, padding: '2px 6px', background: 'var(--ok)', color: 'var(--bg)', letterSpacing: '.1em' }}>OK</span>
          <span className="ff-mono" style={{ fontSize: 11, color: 'var(--ink-3)' }}>No territory × right × period overlaps with other agreements for this counterparty.</span>
        </div>
      );
    }

    return (
      <div style={{ borderBottom: '1px solid var(--rule)', background: 'oklch(96% 0.04 30)' }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 10, padding: '8px 14px' }}>
          <span className="ff-mono upper" style={{ fontSize: 9, padding: '2px 6px', background: 'var(--danger)', color: 'var(--bg)', letterSpacing: '.1em' }}>HARD-BLOCK · {conflicts.length}</span>
          <span className="ff-mono" style={{ fontSize: 11, color: 'var(--ink-2)' }}>territory × right × period overlaps detected</span>
        </div>
        <div>
          {conflicts.map((c, i) => (
            <div key={i} style={{ display: 'grid', gridTemplateColumns: '120px 1fr 120px', gap: 10, padding: '8px 14px', borderTop: '1px solid var(--rule-soft)', alignItems: 'center', fontSize: 11 }}>
              <button className="ff-mono" onClick={() => window.__astroGo && window.__astroGo('agreement', { id: c.otherAg })} style={{ textAlign: 'left', color: 'var(--ink)', fontWeight: 600 }}>
                ↗ {c.otherAg}
              </button>
              <div style={{ display: 'flex', flexWrap: 'wrap', gap: 3 }}>
                {c.isos.slice(0, 12).map(iso => (
                  <span key={iso} className="ff-mono" style={{ fontSize: 10, padding: '1px 5px', background: 'var(--bg)', border: '1px solid var(--danger)' }}>
                    {window.TerritoryEngine.flagOf(iso)} {iso}
                  </span>
                ))}
                {c.isos.length > 12 && <span className="ff-mono" style={{ fontSize: 10, color: 'var(--ink-3)' }}>+{c.isos.length - 12}</span>}
              </div>
              <span className="ff-mono upper" style={{ fontSize: 9, color: 'var(--danger)', letterSpacing: '.08em', textAlign: 'right' }}>{c.rights.join('+')}</span>
            </div>
          ))}
        </div>
      </div>
    );
  }

  // ── Territory footer — ISO summary + currency mix + reversion clocks.
  function AgreementTerritoryFooter({ ag }) {
    const eng = window.TerritoryEngine;
    const fx = window.TerritoryFx;
    if (!eng || !fx || !ag || !ag.territories) return null;
    const [tab, setTab] = useState('iso');

    // Build aggregate selection across all territory rows.
    const allCodes = (ag.territories || []).map(t => t.code).filter(c => c && c !== 'WW');
    const isWorld = (ag.territories || []).some(t => t.code === 'WW');
    const sel = isWorld ? { mode: 'world', codes: [] } : { mode: 'list', codes: allCodes };
    const isos = Array.from(eng.resolveSelection(sel).isos);
    const ccyMix = (() => {
      const m = new Map();
      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]);
    })();

    // Reversion clocks: parse retentionEnd-style or end + reversion offset.
    const reversion = ag.retentionEnd || ag.reversion || ag.end;
    const today = new Date().toISOString().slice(0, 10);
    const dy = reversion ? Math.round((new Date(reversion) - new Date(today)) / (1000 * 86400)) : null;

    return (
      <div style={{ borderTop: '1px solid var(--rule)', padding: 14, background: 'var(--bg-2)' }}>
        <div style={{ display: 'flex', gap: 0, marginBottom: 12, borderBottom: '1px solid var(--rule)' }}>
          {[
            ['iso', `${isos.length} ISO countries`],
            ['ccy', `${ccyMix.length} currencies`],
            ['rev', 'Reversion clocks'],
          ].map(([k, l]) => (
            <button key={k} onClick={() => setTab(k)} className="ff-mono upper"
              style={{
                padding: '6px 10px', fontSize: 10, letterSpacing: '.1em',
                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>
          ))}
        </div>

        {tab === 'iso' && (
          <div style={{ display: 'flex', flexWrap: 'wrap', gap: 4, maxHeight: 160, overflow: 'auto' }}>
            {isos.length === 0 && <span className="ff-mono" style={{ fontSize: 11, color: 'var(--ink-3)' }}>—</span>}
            {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 style={{ color: 'var(--ink-3)', marginLeft: 2 }}>{fx.ccyOf(iso)}</span>
              </span>
            ))}
          </div>
        )}

        {tab === 'ccy' && (
          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(140px, 1fr))', gap: 8 }}>
            {ccyMix.map(([ccy, count]) => (
              <div key={ccy} style={{ border: '1px solid var(--rule)', padding: '8px 10px', background: 'var(--bg)' }}>
                <div className="ff-mono" style={{ fontSize: 13, fontWeight: 600 }}>{fx.symbolOf(ccy)} {ccy}</div>
                <div className="ff-mono" style={{ fontSize: 10, color: 'var(--ink-3)' }}>{count} territor{count === 1 ? 'y' : 'ies'}</div>
                <div className="ff-mono num" style={{ fontSize: 10, color: 'var(--ink-3)', marginTop: 2 }}>1 USD = {fx.convert(1, 'USD', ccy).toLocaleString('en-US', { maximumFractionDigits: 4 })}</div>
              </div>
            ))}
          </div>
        )}

        {tab === 'rev' && (
          <div>
            {!reversion && <span className="ff-mono" style={{ fontSize: 11, color: 'var(--ink-3)' }}>No reversion date set on this agreement.</span>}
            {reversion && (
              <div>
                <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', marginBottom: 8 }}>
                  <span className="ff-mono upper" style={{ fontSize: 9, color: 'var(--ink-3)', letterSpacing: '.12em' }}>GLOBAL REVERSION</span>
                  <span className="ff-mono" style={{ fontSize: 12, fontWeight: 600 }}>
                    {reversion} <span style={{ color: dy < 365 ? 'var(--danger)' : 'var(--ink-3)', marginLeft: 6 }}>· {dy > 0 ? `${dy}d` : `${-dy}d ago`}</span>
                  </span>
                </div>
                <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(180px, 1fr))', gap: 6 }}>
                  {isos.slice(0, 24).map(iso => {
                    // Demo: per-territory reversion offset (if any). We synthesize a small jitter — some territories revert earlier.
                    const offset = ((iso.charCodeAt(0) + iso.charCodeAt(1)) % 7) - 3; // -3..+3 years
                    const d = new Date(reversion);
                    d.setFullYear(d.getFullYear() + offset);
                    const iso2 = d.toISOString().slice(0, 10);
                    const dy2 = Math.round((d - new Date(today)) / (1000 * 86400));
                    const tone = dy2 < 365 ? 'var(--danger)' : (dy2 < 365 * 2 ? 'var(--accent)' : 'var(--ok)');
                    return (
                      <div key={iso} style={{ display: 'flex', alignItems: 'center', gap: 8, padding: '4px 8px', background: 'var(--bg)', border: '1px solid var(--rule)' }}>
                        <span className="ff-mono" style={{ fontSize: 11, fontWeight: 600 }}>{eng.flagOf(iso)} {iso}</span>
                        <span className="ff-mono num" style={{ fontSize: 10, color: 'var(--ink-3)', marginLeft: 'auto' }}>{iso2}</span>
                        <span style={{ width: 6, height: 6, borderRadius: '50%', background: tone, display: 'inline-block' }} />
                      </div>
                    );
                  })}
                </div>
                {isos.length > 24 && <div className="ff-mono" style={{ fontSize: 10, color: 'var(--ink-3)', marginTop: 8 }}>+{isos.length - 24} more</div>}
              </div>
            )}
          </div>
        )}
      </div>
    );
  }

  // ── Withholding chip — used in payout cells.
  function PayoutWithholdingChip({ sourceIso, payeeIso = 'US', amount, ccy }) {
    const fx = window.TerritoryFx;
    if (!fx || !sourceIso) return null;
    const stat = fx.WHT_BY_ISO[sourceIso] || 0;
    const eff = fx.whtOf(sourceIso, payeeIso);
    const reduced = eff < stat;
    const tax = (amount || 0) * eff;
    return (
      <span className="ff-mono" style={{ display: 'inline-flex', alignItems: 'center', gap: 4, padding: '2px 6px', fontSize: 10, background: reduced ? 'var(--ok)' : 'var(--bg-2)', color: reduced ? 'var(--bg)' : 'var(--ink)', border: '1px solid ' + (reduced ? 'var(--ok)' : 'var(--rule)') }}>
        WHT {(eff * 100).toFixed(0)}%{reduced ? ' (treaty)' : ''}
        {amount ? <span style={{ marginLeft: 4 }}>· −{fx.fmt(tax, ccy || 'USD', { short: true, sign: false })}</span> : null}
      </span>
    );
  }

  window.AgreementTerritoryConflicts = AgreementTerritoryConflicts;
  window.AgreementTerritoryFooter = AgreementTerritoryFooter;
  window.PayoutWithholdingChip = PayoutWithholdingChip;
})();
