// ============================================================================
// AGREEMENT-COUNTERPARTY — deal-history rollup per counterparty
//
// Click any counterparty name (party "a" or "b" on an agreement) and see:
//
//   • All agreements with this counterparty (active + historical)
//   • Total advance value · advance paid vs unrecouped
//   • Earliest / most recent deal · gap analysis
//   • Aggregated works coverage (de-duplicated by work id)
//   • Aggregated territory coverage
//   • Average term length · auto-renew rate · litigation history
//   • Pending signatures across all deals
//   • Quick links into each individual agreement
//
// EXPORT: window.ScreenAgreementCounterparty — main screen (open with payload {name})
//          window.AgCounterpartyChip          — clickable chip used inline
// ============================================================================
(function () {
  const { useMemo, useState } = React;

  function findAgreementsByCounterparty(name) {
    const ags = window.AGREEMENTS || [];
    const norm = s => String(s || '').trim().toLowerCase();
    const target = norm(name);
    return ags.filter(a => norm(a.a) === target || norm(a.b) === target);
  }

  function summarize(name, ags) {
    if (!ags.length) return null;
    const today = new Date();
    const totalAdvance = ags.reduce((s, a) => s + (parseAdvance(a.value) || 0), 0);
    const advancePaid = ags.reduce((s, a) => s + (a.advanceSchedule || []).filter(x => x.paid).reduce((ss, x) => ss + (x.amount || 0), 0), 0);
    const advanceTotal = ags.reduce((s, a) => s + (a.advanceSchedule || []).reduce((ss, x) => ss + (x.amount || 0), 0), 0);
    const works = new Map();
    ags.forEach(a => (a.works || []).forEach(w => works.set(w.id, w)));
    const territories = new Set();
    ags.forEach(a => (a.territories || []).forEach(t => territories.add(t.label || t.code)));
    if (!territories.size) ags.forEach(a => a.territory && territories.add(a.territory));
    const earliest = ags.map(a => a.start).filter(Boolean).sort()[0];
    const latest = ags.map(a => a.start).filter(Boolean).sort().slice(-1)[0];
    const active = ags.filter(a => ['active', 'live'].includes(a.status));
    const expiring = ags.filter(a => a.status === 'expiring');
    const ended = ags.filter(a => a.status === 'ended' || a.status === 'expired' || a.status === 'terminated');
    const pendingSig = ags.filter(a => (a.signatures || []).some(s => !s.verified) || a.status === 'pending');
    const autoRenewCount = ags.filter(a => a.autoRenew).length;
    const avgTermYears = (() => {
      const yrs = ags.map(a => {
        const m = String(a.term || '').match(/(\d+)y/);
        return m ? parseInt(m[1], 10) : null;
      }).filter(Boolean);
      return yrs.length ? (yrs.reduce((s, y) => s + y, 0) / yrs.length).toFixed(1) : '—';
    })();
    return {
      name, count: ags.length, totalAdvance, advancePaid, advanceTotal,
      worksCount: works.size, territoriesCount: territories.size, territoriesList: Array.from(territories).slice(0, 8),
      earliest, latest, active: active.length, expiring: expiring.length, ended: ended.length,
      pendingSig: pendingSig.length, autoRenewRate: ags.length ? Math.round(100 * autoRenewCount / ags.length) : 0,
      avgTermYears,
    };
  }

  function parseAdvance(v) {
    if (!v) return 0;
    const m = String(v).match(/\$?([\d.]+)\s*([KMm])?/);
    if (!m) return 0;
    const num = parseFloat(m[1]);
    const u = (m[2] || '').toLowerCase();
    return num * (u === 'm' ? 1e6 : u === 'k' ? 1e3 : 1);
  }
  function fmtUSD(n) {
    if (!n) return '—';
    if (n >= 1e6) return '$' + (n / 1e6).toFixed(2) + 'M';
    if (n >= 1e3) return '$' + (n / 1e3).toFixed(0) + 'K';
    return '$' + n.toFixed(0);
  }
  function fmtDate(d) { return d || '—'; }

  // ── Chip component ─────────────────────────────────────────────────────
  function AgCounterpartyChip({ name, go, kind }) {
    if (!name) return null;
    return (
      <button onClick={(e) => { e.stopPropagation(); go && go('agreement-counterparty', { name }); }}
        title={`Open ${name} deal history`} className="ff-mono"
        style={{ display: 'inline-flex', alignItems: 'center', gap: 4, padding: '2px 6px', fontSize: 10, background: 'transparent', border: '1px dashed var(--rule)', cursor: 'pointer', letterSpacing: '.02em', color: 'var(--ink)' }}>
        <span style={{ width: 5, height: 5, background: kind === 'publisher' ? 'var(--ink)' : 'var(--accent)' }} />
        {name}
        <span style={{ color: 'var(--ink-3)' }}>↗</span>
      </button>
    );
  }

  // ── Main screen ────────────────────────────────────────────────────────
  function ScreenAgreementCounterparty({ go, payload }) {
    const name = (payload && payload.name) || '';
    const ags = useMemo(() => findAgreementsByCounterparty(name), [name]);
    const sum = useMemo(() => summarize(name, ags), [name, ags]);
    const [view, setView] = useState('all'); // all | active | expiring | ended | pending

    if (!name) {
      return <div style={{ padding: 32, textAlign: 'center', color: 'var(--ink-3)' }}>No counterparty specified.</div>;
    }
    if (!sum) {
      return (
        <div>
          <BackBar go={go} />
          <h1 className="heading-swap ff-display" style={{ fontSize: 'clamp(36px,4.5vw,56px)', fontWeight: 700, margin: '0 0 8px' }}>{name}</h1>
          <div style={{ color: 'var(--ink-3)', marginBottom: 24 }}>No agreements found with this counterparty.</div>
        </div>
      );
    }

    const filtered = ags.filter(a => {
      if (view === 'all') return true;
      if (view === 'active') return ['active', 'live'].includes(a.status);
      if (view === 'expiring') return a.status === 'expiring';
      if (view === 'ended') return ['ended', 'expired', 'terminated'].includes(a.status);
      if (view === 'pending') return a.status === 'pending' || (a.signatures || []).some(s => !s.verified);
      return true;
    });

    return (
      <div>
        <BackBar go={go} />

        {/* Hero */}
        <div style={{ display: 'grid', gridTemplateColumns: '1fr auto', gap: 24, alignItems: 'flex-end', marginBottom: 18 }}>
          <div>
            <div className="ff-mono upper" style={{ fontSize: 10, color: 'var(--ink-3)', letterSpacing: '.12em', marginBottom: 8 }}>
              COUNTERPARTY · {sum.count} AGREEMENT{sum.count === 1 ? '' : 'S'}
            </div>
            <h1 className="heading-swap ff-display" style={{ fontSize: 'clamp(36px,4.5vw,64px)', fontWeight: 700, letterSpacing: '-0.04em', lineHeight: .95, margin: 0 }}>
              {name}
            </h1>
            <div style={{ color: 'var(--ink-3)', marginTop: 14, fontSize: 14 }}>
              Relationship since {fmtDate(sum.earliest)} · last deal signed {fmtDate(sum.latest)} · avg term {sum.avgTermYears}y · auto-renew rate {sum.autoRenewRate}%
            </div>
          </div>
          <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap' }}>
            <button onClick={() => window.toast && window.toast(`Counterparty profile · ${name} · pinned`)} className="ff-mono upper"
              style={{ padding: '10px 16px', fontSize: 11, letterSpacing: '.08em', background: 'var(--ink)', color: 'var(--bg)', border: 0, cursor: 'pointer', fontWeight: 600 }}>
              PIN PROFILE
            </button>
            <button onClick={() => window.toast && window.toast(`Statement bundle export queued · ${name}`)} className="ff-mono upper"
              style={{ padding: '10px 16px', fontSize: 11, letterSpacing: '.08em', background: 'transparent', border: '1px solid var(--rule)', cursor: 'pointer' }}>
              EXPORT BUNDLE
            </button>
          </div>
        </div>

        {/* KPI strip */}
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(6, 1fr)', borderTop: '1px solid var(--rule)', borderBottom: '1px solid var(--rule)' }}>
          {[
            ['DEALS · TOTAL', sum.count, ''],
            ['ACTIVE', sum.active, sum.expiring ? `${sum.expiring} expiring` : ''],
            ['ADVANCE · TOTAL', fmtUSD(sum.totalAdvance), sum.advancePaid ? `${fmtUSD(sum.advancePaid)} paid` : ''],
            ['UNRECOUPED', fmtUSD(Math.max(0, sum.advancePaid - 0)), 'see waterfall'],
            ['WORKS COVERED', sum.worksCount, ''],
            ['TERRITORIES', sum.territoriesCount, sum.territoriesList.slice(0, 2).join(' · ')],
          ].map(([l, v, sub]) => (
            <div key={l} style={{ padding: '20px 18px', borderRight: '1px solid var(--rule-soft)' }}>
              <div className="ff-mono upper" style={{ fontSize: 9, color: 'var(--ink-3)', letterSpacing: '.12em' }}>{l}</div>
              <div className="ff-mono" style={{ fontSize: 22, marginTop: 6, fontWeight: 500 }}>{v}</div>
              {sub && <div className="ff-mono upper" style={{ fontSize: 9, color: 'var(--ink-3)', letterSpacing: '.1em', marginTop: 4 }}>{sub}</div>}
            </div>
          ))}
        </div>

        {/* Timeline */}
        <CounterpartyTimeline ags={ags} />

        {/* Filter chips */}
        <div style={{ display: 'flex', gap: 0, borderTop: '1px solid var(--rule)', borderBottom: '1px solid var(--rule)', marginTop: 28 }}>
          {[
            ['ALL', 'all', sum.count],
            ['ACTIVE', 'active', sum.active],
            ['EXPIRING', 'expiring', sum.expiring],
            ['ENDED', 'ended', sum.ended],
            ['PENDING SIG', 'pending', sum.pendingSig],
          ].map(([l, k, n]) => (
            <button key={k} onClick={() => setView(k)} className="ff-mono upper"
              style={{ padding: '14px 20px', fontSize: 10, letterSpacing: '.12em', background: view === k ? 'var(--bg-2)' : 'transparent', border: 0, borderBottom: view === k ? '3px solid var(--ink)' : '3px solid transparent', cursor: 'pointer' }}>
              {l} <span style={{ color: 'var(--ink-3)', marginLeft: 6 }}>{n}</span>
            </button>
          ))}
        </div>

        {/* Agreements table */}
        <table style={{ width: '100%', borderCollapse: 'collapse', borderBottom: '1px solid var(--rule)' }}>
          <thead style={{ background: 'var(--bg-2)' }}>
            <tr>
              {['ID', 'KIND', 'COUNTERPARTY ROLE', 'TERM', 'TERRITORY', 'STATUS', 'ADVANCE', 'WORKS'].map(h => (
                <th key={h} className="ff-mono upper" style={{ padding: '10px 12px', textAlign: 'left', fontSize: 9, color: 'var(--ink-3)', letterSpacing: '.12em', borderBottom: '1px solid var(--rule)' }}>{h}</th>
              ))}
            </tr>
          </thead>
          <tbody>
            {filtered.length === 0 ? (
              <tr><td colSpan={8} style={{ padding: 32, textAlign: 'center', color: 'var(--ink-3)' }}>No agreements in this filter.</td></tr>
            ) : filtered.map(a => {
              const role = String(a.a || '').trim().toLowerCase() === name.toLowerCase() ? 'a→b (sender)' : 'b→a (recipient)';
              return (
                <tr key={a.id} onClick={() => go && go('agreement', a)} style={{ borderBottom: '1px solid var(--rule-soft)', cursor: 'pointer' }}>
                  <td style={{ padding: '10px 12px', fontFamily: 'IBM Plex Mono, monospace', fontSize: 11 }}>{a.id}</td>
                  <td style={{ padding: '10px 12px', fontSize: 12 }}>{a.kind}</td>
                  <td style={{ padding: '10px 12px', fontFamily: 'IBM Plex Mono, monospace', fontSize: 10, color: 'var(--ink-3)' }}>{role}</td>
                  <td style={{ padding: '10px 12px', fontFamily: 'IBM Plex Mono, monospace', fontSize: 11 }}>{a.start} → {a.end || '—'}</td>
                  <td style={{ padding: '10px 12px', fontSize: 12 }}>{a.territory || ((a.territories || [])[0] || {}).label || '—'}</td>
                  <td style={{ padding: '10px 12px' }}>
                    <span className="ff-mono upper" style={{ fontSize: 9, padding: '3px 7px', background: statusBg(a.status), color: '#fff', letterSpacing: '.1em' }}>
                      {a.status}
                    </span>
                  </td>
                  <td style={{ padding: '10px 12px', fontFamily: 'IBM Plex Mono, monospace', fontSize: 11 }}>{a.value || '—'}</td>
                  <td style={{ padding: '10px 12px', fontFamily: 'IBM Plex Mono, monospace', fontSize: 11, textAlign: 'right' }}>{(a.works || []).length}</td>
                </tr>
              );
            })}
          </tbody>
        </table>

        {/* Aggregated works */}
        <AggregatedWorks ags={ags} go={go} />
      </div>
    );
  }

  function statusBg(s) {
    return s === 'active' || s === 'live' ? '#0a8a3a'
      : s === 'expiring' ? 'var(--accent)'
      : s === 'pending' ? 'var(--ink-3)'
      : s === 'expired' || s === 'ended' || s === 'terminated' ? 'var(--danger)'
      : 'var(--ink-3)';
  }

  function CounterpartyTimeline({ ags }) {
    const start = ags.map(a => a.start).filter(Boolean).sort()[0];
    const end = ags.map(a => a.end).filter(Boolean).sort().slice(-1)[0];
    if (!start || !end) return null;
    const sd = new Date(start), ed = new Date(end);
    const span = ed - sd;
    if (span <= 0) return null;
    const pct = d => (d - sd) / span * 100;
    return (
      <div style={{ padding: '24px 0' }}>
        <div className="ff-mono upper" style={{ fontSize: 9, color: 'var(--ink-3)', letterSpacing: '.12em', marginBottom: 12 }}>RELATIONSHIP TIMELINE</div>
        <div style={{ position: 'relative', height: 70, border: '1px solid var(--rule)', background: 'var(--bg-2)', padding: '8px 12px' }}>
          <div style={{ position: 'absolute', left: 12, right: 12, top: '50%', height: 1, background: 'var(--rule)' }} />
          {ags.map(a => {
            const s = a.start ? new Date(a.start) : null;
            const e = a.end ? new Date(a.end) : null;
            if (!s) return null;
            const left = pct(s);
            const width = e ? Math.max(2, pct(e) - left) : 2;
            return (
              <div key={a.id} title={`${a.id} · ${a.kind} · ${a.start} → ${a.end || ''}`}
                style={{ position: 'absolute', left: `calc(12px + ${left}%)`, top: '50%', transform: 'translateY(-50%)', height: 12, width: `${width}%`, background: statusBg(a.status), opacity: .85, borderRadius: 1 }} />
            );
          })}
          <div className="ff-mono" style={{ position: 'absolute', left: 12, bottom: 4, fontSize: 9, color: 'var(--ink-3)' }}>{start}</div>
          <div className="ff-mono" style={{ position: 'absolute', right: 12, bottom: 4, fontSize: 9, color: 'var(--ink-3)' }}>{end}</div>
        </div>
      </div>
    );
  }

  function AggregatedWorks({ ags, go }) {
    const works = new Map();
    ags.forEach(a => (a.works || []).forEach(w => {
      const cur = works.get(w.id) || { ...w, agreementIds: [] };
      cur.agreementIds.push(a.id);
      works.set(w.id, cur);
    }));
    const arr = Array.from(works.values()).sort((a, b) => (b.agreementIds.length - a.agreementIds.length));
    if (!arr.length) return null;
    return (
      <div style={{ marginTop: 32 }}>
        <div className="ff-mono upper" style={{ fontSize: 10, color: 'var(--ink-3)', letterSpacing: '.12em', marginBottom: 8 }}>WORKS COVERED · {arr.length}</div>
        <table style={{ width: '100%', borderCollapse: 'collapse', border: '1px solid var(--rule)' }}>
          <thead style={{ background: 'var(--bg-2)' }}>
            <tr>
              {['ID', 'TITLE', 'ISWC', 'COVERED IN', 'COLLECTION', 'STATUS'].map(h => (
                <th key={h} className="ff-mono upper" style={{ padding: '8px 12px', textAlign: 'left', fontSize: 9, color: 'var(--ink-3)', letterSpacing: '.12em', borderBottom: '1px solid var(--rule)' }}>{h}</th>
              ))}
            </tr>
          </thead>
          <tbody>
            {arr.slice(0, 50).map(w => (
              <tr key={w.id} style={{ borderBottom: '1px solid var(--rule-soft)' }}>
                <td style={{ padding: '8px 12px', fontFamily: 'IBM Plex Mono, monospace', fontSize: 11 }}>{w.id}</td>
                <td style={{ padding: '8px 12px', fontSize: 12 }}>{w.title}</td>
                <td style={{ padding: '8px 12px', fontFamily: 'IBM Plex Mono, monospace', fontSize: 11, color: 'var(--ink-3)' }}>{w.iswc || '—'}</td>
                <td style={{ padding: '8px 12px', fontFamily: 'IBM Plex Mono, monospace', fontSize: 10 }}>
                  {w.agreementIds.slice(0, 3).map((id, i) => (
                    <span key={id}>
                      <button onClick={() => go && go('agreement', { id })} style={{ background: 'transparent', border: 0, padding: 0, cursor: 'pointer', fontFamily: 'inherit', fontSize: 'inherit', color: 'var(--ink)', textDecoration: 'underline' }}>{id}</button>
                      {i < Math.min(2, w.agreementIds.length - 1) ? ', ' : ''}
                    </span>
                  ))}
                  {w.agreementIds.length > 3 && <span style={{ color: 'var(--ink-3)' }}> +{w.agreementIds.length - 3}</span>}
                </td>
                <td style={{ padding: '8px 12px', fontFamily: 'IBM Plex Mono, monospace', fontSize: 11 }}>{w.collection != null ? w.collection + '%' : '—'}</td>
                <td style={{ padding: '8px 12px' }}>
                  <span className="ff-mono upper" style={{ fontSize: 9, padding: '2px 6px', background: w.status === 'registered' ? '#0a8a3a' : 'var(--ink-3)', color: '#fff', letterSpacing: '.1em' }}>
                    {w.status || '—'}
                  </span>
                </td>
              </tr>
            ))}
          </tbody>
        </table>
        {arr.length > 50 && <div className="ff-mono" style={{ fontSize: 10, color: 'var(--ink-3)', marginTop: 6 }}>+ {arr.length - 50} more</div>}
      </div>
    );
  }

  function BackBar({ go }) {
    return (
      <div className="ff-mono upper" style={{ fontSize: 10, color: 'var(--ink-3)', letterSpacing: '.12em', marginBottom: 8, display: 'flex', gap: 10 }}>
        <button onClick={() => go && go('catalog', { tab: 'agreements' })} style={{ background: 'transparent', border: 0, padding: 0, color: 'inherit', cursor: 'pointer', font: 'inherit', letterSpacing: 'inherit', textTransform: 'inherit' }}>CATALOG</button>
        <span style={{ color: 'var(--ink-4)' }}>/</span>
        <span>AGREEMENTS</span>
        <span style={{ color: 'var(--ink-4)' }}>/</span>
        <span style={{ color: 'var(--ink)' }}>COUNTERPARTY</span>
      </div>
    );
  }

  window.ScreenAgreementCounterparty = ScreenAgreementCounterparty;
  window.AgCounterpartyChip = AgCounterpartyChip;
  window.AgCounterpartySummarize = summarize;
})();
