// ============================================================================
// AGREEMENT-RENEWALS — renewal & reversion clock watcher
//
// Scans window.AGREEMENTS for upcoming end dates, retentionEndDate, and
// auto-renew notice windows. Computes per-agreement urgency:
//
//   • EXPIRED                  end < today
//   • NOTICE-WINDOW-OPEN       end - renewNoticeMonths < today < end  (auto-renew)
//   • NOTICE-WINDOW-CLOSED     today > end - renewNoticeMonths  AND  auto-renew=true
//                              → silently renewed; flag for awareness
//   • EXPIRING-SOON            end - 12mo < today < end  (any kind)
//   • REVERSION-DUE            retentionEndDate within 12mo
//   • OK                       nothing imminent
//
// Surfaces:
//   • Calendar grid (12 months forward, agreements pinned to their key dates)
//   • Watch list (sorted by days-until-action)
//   • Notice draft generator (uses AgreementPaperGen with a synthetic template)
//
// EXPORT: window.ScreenAgreementRenewals — main screen
//          window.AgRenewalsPanel        — embeddable panel for agreement-detail
// ============================================================================
(function () {
  const { useMemo, useState } = React;

  const MS_DAY = 86400000;
  function parse(d) { return d ? new Date(d + 'T00:00:00Z') : null; }
  function daysBetween(a, b) { return Math.round((b - a) / MS_DAY); }
  function addMonths(d, m) { const x = new Date(d); x.setUTCMonth(x.getUTCMonth() + m); return x; }
  function fmtDate(d) {
    if (!d) return '—';
    if (typeof d === 'string') d = parse(d);
    return d.toISOString().slice(0, 10);
  }

  function classify(ag, today) {
    today = today || new Date();
    const end = parse(ag.end);
    const ret = parse(ag.retentionEndDate);
    if (!end) return { state: 'OK', urgency: 999, action: null };
    const dEnd = daysBetween(today, end);
    const noticeMonths = ag.renewNoticeMonths || 0;
    const noticeOpen = end ? addMonths(end, -noticeMonths) : null;
    const dNoticeOpen = noticeOpen ? daysBetween(today, noticeOpen) : null;
    const dRet = ret ? daysBetween(today, ret) : null;

    if (dEnd < 0) {
      // Expired or auto-renewed
      if (ag.autoRenew) {
        // already auto-renewed — flag the next cycle
        return { state: 'AUTO-RENEWED', urgency: 365 + dEnd, action: 'TRACK', dEnd, dNoticeOpen, dRet };
      }
      return { state: 'EXPIRED', urgency: -dEnd, action: 'CLOSE-OUT', dEnd, dNoticeOpen, dRet };
    }
    if (ag.autoRenew && noticeMonths > 0) {
      if (dNoticeOpen <= 0 && dEnd > 0) {
        return { state: 'NOTICE-WINDOW-OPEN', urgency: dEnd, action: 'SEND-NOTICE-OR-RENEW', dEnd, dNoticeOpen, dRet };
      }
      if (dNoticeOpen > 0 && dNoticeOpen < 60) {
        return { state: 'NOTICE-WINDOW-OPENING-SOON', urgency: dNoticeOpen, action: 'PREPARE', dEnd, dNoticeOpen, dRet };
      }
    }
    if (dEnd < 365) {
      return { state: 'EXPIRING-SOON', urgency: dEnd, action: 'PLAN-RENEWAL', dEnd, dNoticeOpen, dRet };
    }
    if (dRet != null && dRet > 0 && dRet < 365) {
      return { state: 'REVERSION-DUE', urgency: dRet, action: 'CONFIRM-REVERSION', dEnd, dNoticeOpen, dRet };
    }
    return { state: 'OK', urgency: 999, action: null, dEnd, dNoticeOpen, dRet };
  }

  function stateColor(s) {
    switch (s) {
      case 'EXPIRED': return 'var(--danger)';
      case 'NOTICE-WINDOW-OPEN': return 'var(--danger)';
      case 'NOTICE-WINDOW-OPENING-SOON': return 'var(--accent)';
      case 'EXPIRING-SOON': return 'var(--accent)';
      case 'REVERSION-DUE': return '#7c4dff';
      case 'AUTO-RENEWED': return 'var(--ink-3)';
      default: return 'var(--ink-3)';
    }
  }

  // ── Notice templates ───────────────────────────────────────────────────
  const NOTICE_TEMPLATES = {
    'non-renew': {
      id: 'NOTICE-NONRENEW',
      name: 'Notice of Non-Renewal',
      kindLabel: 'NOTICE',
      version: 1,
      variables: [
        { name: 'sender_name', label: 'Sender', required: true },
        { name: 'recipient_name', label: 'Recipient', required: true },
        { name: 'agreement_id', label: 'Agreement ID', required: true },
        { name: 'agreement_title', label: 'Agreement', required: true },
        { name: 'effective_date', label: 'Effective Termination Date', required: true },
        { name: 'reason', label: 'Reason', kind: 'enum', options: ['Strategic realignment', 'Performance', 'Mutual termination', 'Not provided'], required: false },
      ],
      sections: [
        { n: '1', title: 'Notice', body: 'Reference is made to that certain agreement {{agreement_id}} dated effective between {{sender_name}} and {{recipient_name}} ("Agreement"). Pursuant to the renewal/notice provisions thereof, {{sender_name}} hereby provides written notice that it elects NOT to renew the Agreement. The Agreement shall therefore terminate on {{effective_date}} in accordance with its terms.' },
        { n: '2', title: 'Reason', body: 'Reason for non-renewal: {{reason}}.' },
        { n: '3', title: 'Survival', body: 'All provisions of the Agreement that by their terms survive termination — including post-term retention, audit rights, indemnities, and royalty payment obligations — shall continue in full force and effect.' },
        { n: '4', title: 'Counterparts', body: 'This notice may be delivered electronically and shall be effective upon receipt.' },
      ],
    },
    'renew': {
      id: 'NOTICE-RENEW',
      name: 'Notice of Renewal',
      kindLabel: 'NOTICE',
      version: 1,
      variables: [
        { name: 'sender_name', label: 'Sender', required: true },
        { name: 'recipient_name', label: 'Recipient', required: true },
        { name: 'agreement_id', label: 'Agreement ID', required: true },
        { name: 'agreement_title', label: 'Agreement', required: true },
        { name: 'new_term_years', label: 'New term (years)', kind: 'numeric', required: true },
        { name: 'new_end_date', label: 'New end date', required: true },
      ],
      sections: [
        { n: '1', title: 'Notice', body: 'Reference is made to that certain agreement {{agreement_id}} ("Agreement") between {{sender_name}} and {{recipient_name}}. Pursuant to the renewal provisions thereof, {{sender_name}} hereby exercises its right to renew the Agreement for an additional term of {{new_term_years}} years, such renewal term commencing immediately upon expiration of the current term and ending on {{new_end_date}}.' },
        { n: '2', title: 'Confirmation', body: 'All other terms of the Agreement remain unchanged. Please acknowledge receipt of this renewal notice within thirty (30) days.' },
      ],
    },
    'reversion': {
      id: 'NOTICE-REVERSION',
      name: 'Reversion Confirmation',
      kindLabel: 'NOTICE',
      version: 1,
      variables: [
        { name: 'sender_name', label: 'Sender', required: true },
        { name: 'recipient_name', label: 'Recipient', required: true },
        { name: 'agreement_id', label: 'Agreement ID', required: true },
        { name: 'reversion_date', label: 'Reversion date', required: true },
        { name: 'works_count', label: 'Works reverting', kind: 'numeric' },
      ],
      sections: [
        { n: '1', title: 'Notice', body: 'Reference is made to agreement {{agreement_id}} between {{sender_name}} and {{recipient_name}}. As of {{reversion_date}}, the post-term retention period under such agreement shall have expired and all rights ({{works_count}} works) shall revert to {{sender_name}} pursuant to the reversion provisions thereof.' },
        { n: '2', title: 'Statements', body: 'A final statement covering the period through reversion shall be delivered within ninety (90) days. No further royalty obligations shall accrue thereafter.' },
        { n: '3', title: 'Acknowledgement', body: 'Please acknowledge this reversion in writing within thirty (30) days. Counter-signature returned to the address above shall constitute such acknowledgement.' },
      ],
    },
  };

  function fillNoticeVars(kind, ag) {
    const t = NOTICE_TEMPLATES[kind];
    if (!t) return {};
    const out = {};
    t.variables.forEach(v => {
      switch (v.name) {
        case 'sender_name': out[v.name] = ag.a; break;
        case 'recipient_name': out[v.name] = ag.b; break;
        case 'agreement_id': out[v.name] = ag.id; break;
        case 'agreement_title': out[v.name] = `${ag.a} × ${ag.b}`; break;
        case 'effective_date': out[v.name] = ag.end || ''; break;
        case 'new_end_date': out[v.name] = ag.end ? new Date(parse(ag.end).getTime() + 365 * MS_DAY * 5).toISOString().slice(0,10) : ''; break;
        case 'new_term_years': out[v.name] = '5'; break;
        case 'reversion_date': out[v.name] = ag.retentionEndDate || ''; break;
        case 'works_count': out[v.name] = String((ag.works || []).length || ''); break;
        case 'reason': out[v.name] = 'Not provided'; break;
        default: out[v.name] = '';
      }
    });
    return out;
  }

  // ── Watch list row ─────────────────────────────────────────────────────
  function WatchRow({ ag, info, onAction, go }) {
    const days = info.urgency;
    return (
      <tr style={{ borderBottom: '1px solid var(--rule-soft)', cursor: 'pointer' }} onClick={() => go && go('agreement', ag)}>
        <td style={{ padding: '10px 12px', fontFamily: 'IBM Plex Mono, monospace', fontSize: 11 }}>{ag.id}</td>
        <td style={{ padding: '10px 12px', fontSize: 12 }}>{ag.a} <span style={{ color: 'var(--ink-3)' }}>×</span> {ag.b}</td>
        <td style={{ padding: '10px 12px', fontFamily: 'IBM Plex Mono, monospace', fontSize: 10, color: 'var(--ink-3)' }}>{ag.kind}</td>
        <td style={{ padding: '10px 12px', fontFamily: 'IBM Plex Mono, monospace', fontSize: 11 }}>{fmtDate(ag.end)}</td>
        <td style={{ padding: '10px 12px' }}>
          <span className="ff-mono upper" style={{ fontSize: 9, padding: '3px 7px', background: stateColor(info.state), color: '#fff', letterSpacing: '.1em' }}>
            {info.state}
          </span>
        </td>
        <td style={{ padding: '10px 12px', fontFamily: 'IBM Plex Mono, monospace', fontSize: 11, color: days < 30 ? 'var(--danger)' : days < 90 ? 'var(--accent)' : 'var(--ink)' }}>
          {info.state === 'EXPIRED' ? `${Math.abs(days)}d ago` : `in ${days}d`}
        </td>
        <td style={{ padding: '10px 12px' }} onClick={e => e.stopPropagation()}>
          <button onClick={() => onAction(ag, info)} className="ff-mono upper"
            style={{ fontSize: 9, padding: '4px 10px', background: 'var(--ink)', color: 'var(--bg)', border: 0, cursor: 'pointer', letterSpacing: '.1em' }}>
            DRAFT NOTICE
          </button>
        </td>
      </tr>
    );
  }

  // ── Calendar grid ──────────────────────────────────────────────────────
  function CalendarStrip({ items, today, go }) {
    // items: { date, ag, kind }
    const months = [];
    const start = new Date(today);
    start.setUTCDate(1);
    for (let i = 0; i < 12; i++) {
      const m = addMonths(start, i);
      const ms = m.toISOString().slice(0, 7);
      const inMonth = items.filter(it => it.date && it.date.toISOString().slice(0, 7) === ms);
      months.push({ m, ms, items: inMonth });
    }
    return (
      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(12, 1fr)', border: '1px solid var(--rule)', borderRadius: 0 }}>
        {months.map((mo, i) => (
          <div key={i} style={{ borderRight: i < 11 ? '1px solid var(--rule-soft)' : 0, padding: '10px 8px', minHeight: 140, background: i === 0 ? 'var(--bg-2)' : 'var(--bg)' }}>
            <div className="ff-mono upper" style={{ fontSize: 9, color: 'var(--ink-3)', letterSpacing: '.12em', marginBottom: 6 }}>
              {mo.m.toLocaleString('en', { month: 'short', year: '2-digit', timeZone: 'UTC' })}
            </div>
            {mo.items.length === 0 ? (
              <div className="ff-mono" style={{ fontSize: 10, color: 'var(--ink-4)' }}>—</div>
            ) : (
              mo.items.slice(0, 6).map((it, j) => (
                <div key={j} onClick={() => go && go('agreement', it.ag)} title={`${it.ag.id} · ${it.kind}`}
                  style={{ fontSize: 10, padding: '3px 5px', marginBottom: 2, background: stateColor(it.state || (it.kind === 'reversion' ? 'REVERSION-DUE' : 'EXPIRING-SOON')), color: '#fff', cursor: 'pointer', fontFamily: 'IBM Plex Mono, monospace', letterSpacing: '.02em', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>
                  {it.ag.id.replace(/^AG-/, '')} · {it.kind === 'reversion' ? 'REV' : it.kind === 'notice' ? 'NTC' : 'END'}
                </div>
              ))
            )}
          </div>
        ))}
      </div>
    );
  }

  // ── Notice draft modal ─────────────────────────────────────────────────
  function NoticeModal({ ag, kind, onClose }) {
    const [k, setK] = useState(kind || 'non-renew');
    const tpl = NOTICE_TEMPLATES[k];
    const [vars, setVars] = useState(() => fillNoticeVars(k, ag));
    React.useEffect(() => { setVars(fillNoticeVars(k, ag)); }, [k, ag.id]);
    const PG = window.AgreementPaperGen;
    const { html, missing } = PG ? PG.renderHtml(tpl, vars, { parties: [{ role: tpl.id === 'NOTICE-NONRENEW' ? 'SENDER' : 'SENDER', name: ag.a }, { role: 'RECIPIENT', name: ag.b }] }) : { html: '<p>PaperGen not loaded</p>', missing: [] };
    return (
      <div style={{ position: 'fixed', inset: 0, background: 'rgba(0,0,0,.5)', display: 'flex', alignItems: 'center', justifyContent: 'center', zIndex: 9999 }} onClick={onClose}>
        <div onClick={e => e.stopPropagation()} style={{ width: 'min(1100px, 96vw)', maxHeight: '92vh', background: 'var(--bg)', display: 'grid', gridTemplateColumns: '320px 1fr', overflow: 'hidden' }}>
          <div style={{ padding: 16, borderRight: '1px solid var(--rule)', overflow: 'auto' }}>
            <div className="ff-mono upper" style={{ fontSize: 11, letterSpacing: '.12em', marginBottom: 14 }}>DRAFT NOTICE · {ag.id}</div>
            <div className="ff-mono upper" style={{ fontSize: 9, color: 'var(--ink-3)', letterSpacing: '.12em', marginBottom: 6 }}>NOTICE TYPE</div>
            <select value={k} onChange={e => setK(e.target.value)} style={{ width: '100%', padding: '6px 8px', fontSize: 12, background: 'var(--bg)', border: '1px solid var(--rule)', marginBottom: 14 }}>
              <option value="non-renew">Notice of Non-Renewal</option>
              <option value="renew">Notice of Renewal</option>
              <option value="reversion">Reversion Confirmation</option>
            </select>
            {tpl.variables.map(v => (
              <div key={v.name} style={{ marginBottom: 8 }}>
                <label className="ff-mono" style={{ fontSize: 10, color: 'var(--ink-3)', display: 'block', marginBottom: 2 }}>{v.label}{v.required && <span style={{ color: 'var(--danger)' }}> *</span>}</label>
                {v.kind === 'enum' ? (
                  <select value={vars[v.name] || ''} onChange={e => setVars({ ...vars, [v.name]: e.target.value })} style={{ width: '100%', padding: '4px 6px', fontSize: 11, background: 'var(--bg)', border: '1px solid var(--rule)' }}>
                    <option value="">— pick —</option>
                    {v.options.map(o => <option key={o}>{o}</option>)}
                  </select>
                ) : (
                  <input value={vars[v.name] || ''} onChange={e => setVars({ ...vars, [v.name]: e.target.value })}
                    style={{ width: '100%', padding: '4px 6px', fontSize: 11, fontFamily: 'IBM Plex Mono, monospace', background: 'var(--bg)', border: '1px solid var(--rule)', boxSizing: 'border-box' }} />
                )}
              </div>
            ))}
            <div style={{ marginTop: 16, paddingTop: 12, borderTop: '1px solid var(--rule)' }}>
              {PG && <button onClick={() => PG.printPdf(tpl, vars, { parties: [{ role: 'SENDER', name: ag.a }, { role: 'RECIPIENT', name: ag.b }] })}
                className="ff-mono upper" style={{ width: '100%', padding: '7px 10px', fontSize: 10, letterSpacing: '.12em', background: 'var(--ink)', color: 'var(--bg)', border: 0, cursor: 'pointer', marginBottom: 6 }}>
                Print / Save PDF
              </button>}
              {PG && <button onClick={() => PG.downloadDocx(tpl, vars, null, { parties: [{ role: 'SENDER', name: ag.a }, { role: 'RECIPIENT', name: ag.b }] })}
                className="ff-mono upper" style={{ width: '100%', padding: '7px 10px', fontSize: 10, letterSpacing: '.12em', background: 'transparent', color: 'var(--ink)', border: '1px solid var(--ink)', cursor: 'pointer', marginBottom: 6 }}>
                Download .docx
              </button>}
              <button onClick={() => { window.toast && window.toast(`Notice queued · ${ag.id}`, 'ok'); onClose(); }}
                className="ff-mono upper" style={{ width: '100%', padding: '7px 10px', fontSize: 10, letterSpacing: '.12em', background: 'var(--accent)', color: 'var(--accent-ink)', border: 0, cursor: 'pointer', marginBottom: 6 }}>
                Queue for delivery
              </button>
              <button onClick={onClose} className="ff-mono upper" style={{ width: '100%', padding: '7px 10px', fontSize: 10, letterSpacing: '.12em', background: 'transparent', color: 'var(--ink-3)', border: '1px solid var(--rule)', cursor: 'pointer' }}>
                Cancel
              </button>
            </div>
          </div>
          <div style={{ background: '#e8e8e8', padding: 16, overflow: 'auto' }}>
            <iframe srcDoc={html} title="notice-preview" style={{ width: '100%', minHeight: 600, border: '1px solid #ccc', background: '#fff', boxShadow: '0 2px 8px rgba(0,0,0,.08)' }} />
          </div>
        </div>
      </div>
    );
  }

  // ── Embeddable panel for agreement-detail tab ──────────────────────────
  function AgRenewalsPanel({ ag }) {
    const today = new Date();
    const info = classify(ag, today);
    const [modalKind, setModalKind] = useState(null);
    const cardLabel = {
      'EXPIRED': 'Agreement has expired — close out.',
      'NOTICE-WINDOW-OPEN': `Auto-renew kicks in at ${fmtDate(ag.end)}. Send notice now to opt out.`,
      'NOTICE-WINDOW-OPENING-SOON': `Notice window opens in ${info.dNoticeOpen} days.`,
      'EXPIRING-SOON': `Term ends in ${info.dEnd} days.`,
      'REVERSION-DUE': `Reversion due in ${info.dRet} days.`,
      'AUTO-RENEWED': 'Auto-renewed — verify next-cycle terms.',
      'OK': 'No imminent action.',
    }[info.state];

    return (
      <div>
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', borderTop: '1px solid var(--rule)', borderBottom: '1px solid var(--rule)' }}>
          {[
            ['STATUS', info.state],
            ['END', fmtDate(ag.end)],
            ['NOTICE WINDOW OPENS', ag.autoRenew && ag.renewNoticeMonths ? fmtDate(addMonths(parse(ag.end), -ag.renewNoticeMonths)) : '—'],
            ['REVERSION', fmtDate(ag.retentionEndDate)],
          ].map(([l, v]) => (
            <div key={l} style={{ padding: '14px 16px', 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: 14, marginTop: 4, color: l === 'STATUS' ? stateColor(info.state) : 'var(--ink)' }}>{v}</div>
            </div>
          ))}
        </div>
        <div style={{ padding: '18px 16px', borderBottom: '1px solid var(--rule)' }}>
          <div style={{ fontSize: 14, marginBottom: 14 }}>{cardLabel}</div>
          <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap' }}>
            <button onClick={() => setModalKind('non-renew')} className="ff-mono upper" style={btn1()}>DRAFT NON-RENEWAL NOTICE</button>
            <button onClick={() => setModalKind('renew')} className="ff-mono upper" style={btn2()}>DRAFT RENEWAL NOTICE</button>
            {ag.retentionEndDate && <button onClick={() => setModalKind('reversion')} className="ff-mono upper" style={btn2()}>DRAFT REVERSION CONFIRMATION</button>}
          </div>
        </div>
        <Timeline ag={ag} info={info} today={today} />
        {modalKind && <NoticeModal ag={ag} kind={modalKind} onClose={() => setModalKind(null)} />}
      </div>
    );
  }

  function Timeline({ ag, info, today }) {
    const start = parse(ag.start);
    const end = parse(ag.end);
    const ret = parse(ag.retentionEndDate);
    const noticeOpen = ag.autoRenew && ag.renewNoticeMonths ? addMonths(end, -ag.renewNoticeMonths) : null;
    if (!start || !end) return null;
    const span = (ret || end) - start;
    const pct = d => Math.max(0, Math.min(100, ((d - start) / span) * 100));
    return (
      <div style={{ padding: '24px 16px' }}>
        <div className="ff-mono upper" style={{ fontSize: 9, color: 'var(--ink-3)', letterSpacing: '.12em', marginBottom: 14 }}>TIMELINE</div>
        <div style={{ position: 'relative', height: 60, marginTop: 8 }}>
          <div style={{ position: 'absolute', top: 28, left: 0, right: 0, height: 2, background: 'var(--rule)' }} />
          <div style={{ position: 'absolute', top: 28, left: 0, height: 2, background: 'var(--ink)', width: pct(today) + '%', transition: 'width .4s' }} />
          {[
            { d: start, l: 'Start', v: fmtDate(start) },
            noticeOpen && { d: noticeOpen, l: 'Notice opens', v: fmtDate(noticeOpen), color: 'var(--accent)' },
            { d: end, l: 'Term end', v: fmtDate(end), color: stateColor(info.state) },
            ret && { d: ret, l: 'Reversion', v: fmtDate(ret), color: '#7c4dff' },
            { d: today, l: 'Today', v: fmtDate(today), color: 'var(--ink)', dot: true },
          ].filter(Boolean).map((p, i) => (
            <div key={i} style={{ position: 'absolute', left: `calc(${pct(p.d)}% - 6px)`, top: 22, textAlign: 'center', width: 12 }}>
              <div style={{ width: 12, height: 12, background: p.color || 'var(--ink-3)', borderRadius: p.dot ? '50%' : 0, border: p.dot ? '2px solid var(--bg)' : 0, boxShadow: p.dot ? '0 0 0 2px var(--ink)' : 0 }} />
              <div className="ff-mono" style={{ position: 'absolute', top: 16, left: '50%', transform: 'translateX(-50%)', fontSize: 9, color: 'var(--ink-3)', whiteSpace: 'nowrap', letterSpacing: '.04em' }}>
                {p.l}<br /><span style={{ color: 'var(--ink)' }}>{p.v}</span>
              </div>
            </div>
          ))}
        </div>
      </div>
    );
  }

  // ── Main screen ────────────────────────────────────────────────────────
  function ScreenAgreementRenewals({ go }) {
    const today = new Date();
    const ags = window.AGREEMENTS || [];
    const annotated = useMemo(() => ags.map(ag => ({ ag, info: classify(ag, today) }))
      .filter(x => x.info.state !== 'OK')
      .sort((a, b) => a.info.urgency - b.info.urgency), [ags.length]);
    const [filter, setFilter] = useState('all');
    const [modal, setModal] = useState(null); // {ag, kind}

    const counts = {
      all: annotated.length,
      noticeOpen: annotated.filter(x => x.info.state === 'NOTICE-WINDOW-OPEN').length,
      expiring: annotated.filter(x => x.info.state === 'EXPIRING-SOON' || x.info.state === 'NOTICE-WINDOW-OPENING-SOON').length,
      reversion: annotated.filter(x => x.info.state === 'REVERSION-DUE').length,
      expired: annotated.filter(x => x.info.state === 'EXPIRED').length,
    };
    const filtered = annotated.filter(x => {
      if (filter === 'all') return true;
      if (filter === 'noticeOpen') return x.info.state === 'NOTICE-WINDOW-OPEN';
      if (filter === 'expiring') return x.info.state === 'EXPIRING-SOON' || x.info.state === 'NOTICE-WINDOW-OPENING-SOON';
      if (filter === 'reversion') return x.info.state === 'REVERSION-DUE';
      if (filter === 'expired') return x.info.state === 'EXPIRED';
      return true;
    });

    // Calendar items
    const calItems = [];
    annotated.forEach(({ ag, info }) => {
      if (ag.end) calItems.push({ date: parse(ag.end), ag, kind: 'end', state: info.state });
      if (ag.retentionEndDate) calItems.push({ date: parse(ag.retentionEndDate), ag, kind: 'reversion', state: 'REVERSION-DUE' });
      if (ag.autoRenew && ag.renewNoticeMonths) calItems.push({ date: addMonths(parse(ag.end), -ag.renewNoticeMonths), ag, kind: 'notice', state: 'NOTICE-WINDOW-OPEN' });
    });

    return (
      <div>
        <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)' }}>RENEWALS & REVERSIONS</span>
        </div>
        <h1 className="heading-swap ff-display" style={{ fontSize: 'clamp(36px,4.5vw,56px)', fontWeight: 700, letterSpacing: '-0.04em', lineHeight: .95, margin: '0 0 8px' }}>
          Renewals <span style={{ color: 'var(--ink-3)', fontWeight: 500 }}>&amp;</span> reversions
        </h1>
        <div style={{ color: 'var(--ink-3)', marginBottom: 28, maxWidth: 720 }}>
          {counts.noticeOpen} agreement{counts.noticeOpen === 1 ? '' : 's'} {counts.noticeOpen === 1 ? 'is' : 'are'} inside the notice window — auto-renew triggers if you don't act. {counts.reversion} reversion{counts.reversion === 1 ? '' : 's'} due within 12 months.
        </div>

        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(5, 1fr)', borderTop: '1px solid var(--rule)', borderBottom: '1px solid var(--rule)', marginBottom: 24 }}>
          {[
            ['ALL', counts.all, 'all'],
            ['NOTICE OPEN', counts.noticeOpen, 'noticeOpen'],
            ['EXPIRING', counts.expiring, 'expiring'],
            ['REVERSION', counts.reversion, 'reversion'],
            ['EXPIRED', counts.expired, 'expired'],
          ].map(([l, n, k]) => (
            <button key={k} onClick={() => setFilter(k)}
              style={{ padding: '20px 18px', textAlign: 'left', borderRight: '1px solid var(--rule-soft)', background: filter === k ? 'var(--bg-2)' : 'transparent', border: 0, borderBottom: filter === k ? '3px solid var(--ink)' : '3px solid transparent', cursor: 'pointer', fontFamily: 'inherit' }}>
              <div className="ff-mono upper" style={{ fontSize: 9, color: 'var(--ink-3)', letterSpacing: '.12em' }}>{l}</div>
              <div className="ff-mono" style={{ fontSize: 28, marginTop: 6, fontWeight: 500 }}>{n}</div>
            </button>
          ))}
        </div>

        <div className="ff-mono upper" style={{ fontSize: 10, color: 'var(--ink-3)', letterSpacing: '.12em', marginBottom: 8 }}>NEXT 12 MONTHS</div>
        <CalendarStrip items={calItems} today={today} go={go} />

        <div className="ff-mono upper" style={{ fontSize: 10, color: 'var(--ink-3)', letterSpacing: '.12em', margin: '32px 0 8px' }}>WATCH LIST · {filtered.length}</div>
        <table style={{ width: '100%', borderCollapse: 'collapse', border: '1px solid var(--rule)' }}>
          <thead style={{ background: 'var(--bg-2)' }}>
            <tr>
              {['ID', 'PARTIES', 'KIND', 'END', 'STATE', 'IN', ''].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={7} style={{ padding: 32, textAlign: 'center', color: 'var(--ink-3)' }}>Nothing imminent — your agreements are looking good.</td></tr>
              : filtered.map(({ ag, info }) => (
                <WatchRow key={ag.id} ag={ag} info={info} go={go} onAction={(a, i) => {
                  const kind = i.state === 'REVERSION-DUE' ? 'reversion'
                            : i.state === 'NOTICE-WINDOW-OPEN' ? 'non-renew'
                            : 'non-renew';
                  setModal({ ag: a, kind });
                }} />
              ))}
          </tbody>
        </table>

        {modal && <NoticeModal ag={modal.ag} kind={modal.kind} onClose={() => setModal(null)} />}
      </div>
    );
  }

  function btn1() { return { padding: '8px 14px', fontSize: 11, letterSpacing: '.08em', background: 'var(--ink)', color: 'var(--bg)', border: 0, cursor: 'pointer' }; }
  function btn2() { return { padding: '8px 14px', fontSize: 11, letterSpacing: '.08em', background: 'transparent', color: 'var(--ink)', border: '1px solid var(--rule)', cursor: 'pointer' }; }

  // Public API
  window.ScreenAgreementRenewals = ScreenAgreementRenewals;
  window.AgRenewalsPanel = AgRenewalsPanel;
  window.AgRenewalsClassify = classify;
  window.AgRenewalsTemplates = NOTICE_TEMPLATES;
})();
