// statement-out.jsx — Wave 2b: Counterparty-facing royalty statement generator
//
// One screen, two views:
//   • Builder — pick counterparty + period + agreement(s); preview the doc
//   • Print preview — full statement laid out in print-styled HTML with page
//     breaks, ready for ⌘-P to PDF or "Send to counterparty" (mock)
//
// Replaces the Pages workflow Paul does manually today. The doc layout matches
// what a typical royalty statement looks like: cover sheet with summary,
// per-recording detail breakdown, deductions, net payable, signature block.
//
// Exports: window.ScreenStatementOut, window.StatementOutPrint

(function () {
  const { useState, useMemo, useEffect } = React;

  const fmt$ = (n, ccy = 'USD') => {
    const sym = ccy === 'USD' ? '$' : ccy === 'GBP' ? '£' : ccy === 'EUR' ? '€' : '';
    const v = Number(n) || 0;
    return (v < 0 ? '-' : '') + sym + Math.abs(v).toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2 });
  };
  const fmtPct = (n) => (Number(n) * 100).toFixed(2) + '%';

  // ─────────── Derive a statement from a counterparty + period ───────────
  function buildStatementOut({ counterparty, period, agreements, recordings, works, statements }) {
    // 1. Find agreements where counterparty is a payable party
    const ags = (agreements || []).filter(ag => {
      if (counterparty && ag.b !== counterparty.name && ag.a !== counterparty.name) return false;
      const parties = ag.parties || [];
      return parties.some(p => p.name === counterparty?.name);
    });

    // 2. Synthesize line items from statement lines that match works/recordings on those agreements
    const ownedWorkIds = new Set();
    const ownedRecIds = new Set();
    ags.forEach(ag => (ag.works || []).forEach(w => ownedWorkIds.add(w.id || w)));
    ags.forEach(ag => (ag.recordings || []).forEach(r => ownedRecIds.add(r.id || r)));

    // 3. Group earnings by source × asset
    const lineItems = [];
    const byRec = new Map();
    let total = 0;
    let lineCount = 0;

    for (const stmt of (statements || [])) {
      if (period && stmt.period !== period && stmt.periodLabel !== period) continue;
      for (const ln of stmt.lines || []) {
        // synth: assume 18% of statement lines belong to the counterparty in this period
        if ((stmt.lines.indexOf(ln) % 6) !== 0) continue;
        const key = (ln.isrc || ln.trackTitle || 'unknown') + '::' + stmt.sourceName;
        const amt = ln.royaltyUsd || ln.amountUsd || 0;
        if (!byRec.has(key)) {
          byRec.set(key, {
            isrc: ln.isrc,
            title: ln.trackTitle || ln.workTitle || '(untitled)',
            artist: ln.trackArtists || ln.releaseArtists || '',
            source: stmt.sourceName,
            sourceKind: stmt.sourceKind,
            count: 0,
            gross: 0,
          });
        }
        const row = byRec.get(key);
        row.count += ln.count || 1;
        row.gross += amt;
        total += amt;
        lineCount++;
      }
    }
    for (const v of byRec.values()) lineItems.push(v);
    lineItems.sort((a, b) => b.gross - a.gross);

    // 4. Compute share to counterparty (use first matching agreement's split)
    const ag = ags[0];
    const cpartyShare = ag?.parties?.find(p => p.name === counterparty?.name)?.share ?? 50;
    const grossShare = total * (cpartyShare / 100);

    // 5. Deductions
    const adminFeeRate = ag && /sub-pub/i.test(ag.kind || '') ? 0.15 : ag && /admin/i.test(ag.kind || '') ? 0.10 : 0.10;
    const adminFee = Math.round(grossShare * adminFeeRate * 100) / 100;
    const witholding = 0; // simplifying
    const recoupment = ag?.recoupmentLedger?.unrecouped > 0
      ? Math.min(ag.recoupmentLedger.unrecouped, Math.round(grossShare * 0.5 * 100) / 100)
      : 0;

    const net = Math.round((grossShare - adminFee - witholding - recoupment) * 100) / 100;

    return {
      counterparty,
      period,
      agreements: ags,
      lineItems: lineItems.slice(0, 60), // cap for layout
      lineCount,
      gross: total,
      cpartyShare,
      grossShare,
      adminFeeRate,
      adminFee,
      witholding,
      recoupment,
      net,
      generatedAt: new Date().toISOString(),
      stmtNumber: 'RS-' + new Date().getFullYear() + '-' + String(Math.abs((counterparty?.name || 'X').split('').reduce((a, c) => a + c.charCodeAt(0), 0)) % 10000).padStart(4, '0'),
    };
  }

  // ═══════════════════════════════════════════════════════ MAIN SCREEN
  function ScreenStatementOut({ go, payload }) {
    const parties = window.PARTIES || [];
    const agreements = window.AGREEMENTS || [];
    const recordings = window.RECORDINGS || [];
    const works = window.WORKS || [];
    const stmtIdx = window.__STMT_INDEX || { statements: [] };

    // Derive counterparties from agreements (not your own party)
    const yourParty = parties.find(p => p.isYou) || parties[0];
    const counterparties = useMemo(() => {
      const set = new Map();
      for (const ag of agreements) {
        for (const p of (ag.parties || [])) {
          if (yourParty && p.name === yourParty.name) continue;
          if (!set.has(p.name)) set.set(p.name, { name: p.name, role: p.role, agreementCount: 0 });
          set.get(p.name).agreementCount++;
        }
      }
      return [...set.values()].sort((a, b) => b.agreementCount - a.agreementCount);
    }, [agreements, yourParty]);

    const periods = useMemo(() => {
      const set = new Set();
      for (const s of stmtIdx.statements) set.add(s.periodLabel || s.period);
      return [...set].sort().reverse();
    }, [stmtIdx]);

    const [counterpartyName, setCounterpartyName] = useState(payload?.counterparty || (counterparties[0]?.name || ''));
    const [period, setPeriod] = useState(payload?.period || periods[0] || '');
    const [showPreview, setShowPreview] = useState(false);
    const [printMode, setPrintMode] = useState(false);

    const counterparty = counterparties.find(c => c.name === counterpartyName);

    const stmtOut = useMemo(() => {
      if (!counterparty || !period) return null;
      return buildStatementOut({
        counterparty, period, agreements, recordings, works, statements: stmtIdx.statements,
      });
    }, [counterparty, period, agreements, recordings, works, stmtIdx]);

    // Print mode: hide everything else and show only the document
    useEffect(() => {
      if (!printMode) return;
      document.body.classList.add('astro-print-mode');
      return () => document.body.classList.remove('astro-print-mode');
    }, [printMode]);

    if (printMode && stmtOut) {
      return <StatementOutPrint stmt={stmtOut} onClose={() => setPrintMode(false)} />;
    }

    return (
      <div>
        {/* Breadcrumb */}
        <div className="ff-mono upper" style={{ fontSize:10, color:'var(--ink-3)', letterSpacing:'.12em', marginBottom:8, display:'flex', gap:10 }}>
          <button onClick={() => go && go('royalties')} style={{ background:'transparent', border:0, padding:0, color:'inherit', cursor:'pointer', font:'inherit', letterSpacing:'inherit', textTransform:'inherit' }}>ROYALTIES</button>
          <span style={{ color:'var(--ink-4)' }}>/</span>
          <span style={{ color:'var(--ink)' }}>STATEMENT-OUT GENERATOR</span>
        </div>

        {/* Hero */}
        <div style={{ marginBottom:24 }}>
          <h1 className="heading-swap ff-display" style={{ fontSize:'clamp(36px,4.5vw,64px)', fontWeight:700, letterSpacing:'-0.04em', lineHeight:.95, margin:0 }}>
            Send a statement
          </h1>
          <p style={{ fontSize:14, color:'var(--ink-2)', maxWidth:680, margin:'14px 0 0', lineHeight:1.5 }}>
            Produce a counterparty-facing royalty statement from your reconciled income lines. Pick the counterparty and the period; ASTRO assembles the document, computes the net payable, and files it on the counterparty record.
          </p>
        </div>

        {/* Builder form */}
        <div style={{ display:'grid', gridTemplateColumns:'2fr 1fr', gap:32, alignItems:'flex-start' }}>
          <div>
            {/* Step 1: counterparty */}
            <Sec num="01">Counterparty</Sec>
            <div style={{ marginTop:14 }}>
              <input value={counterpartyName} onChange={e => setCounterpartyName(e.target.value)} placeholder="Search counterparties…" list="cparties"
                className="ff-mono"
                style={{ width:'100%', padding:'12px 14px', fontSize:14, border:'1px solid var(--rule)', background:'var(--paper)' }}/>
              <datalist id="cparties">
                {counterparties.map(c => <option key={c.name} value={c.name}>{c.role} · {c.agreementCount} agmt(s)</option>)}
              </datalist>
              <div style={{ display:'flex', gap:6, marginTop:10, flexWrap:'wrap' }}>
                {counterparties.slice(0, 6).map(c => (
                  <button key={c.name} onClick={() => setCounterpartyName(c.name)} className="ff-mono"
                    style={{ padding:'6px 10px', fontSize:11, border:'1px solid var(--rule)', background: counterpartyName === c.name ? 'var(--ink)' : 'transparent', color: counterpartyName === c.name ? 'var(--bg)' : 'var(--ink)', cursor:'pointer' }}>
                    {c.name}
                  </button>
                ))}
              </div>
            </div>

            {/* Step 2: period */}
            <Sec num="02">Reporting period</Sec>
            <div style={{ display:'flex', gap:6, marginTop:14, flexWrap:'wrap' }}>
              {periods.length === 0 && <div style={{ color:'var(--ink-3)', fontSize:13 }}>No periods available — load statements first.</div>}
              {periods.map(p => (
                <button key={p} onClick={() => setPeriod(p)} className="ff-mono upper"
                  style={{ padding:'10px 14px', fontSize:11, letterSpacing:'.08em', fontWeight:600, border:'1px solid ' + (period === p ? 'var(--ink)' : 'var(--rule)'), background: period === p ? 'var(--ink)' : 'transparent', color: period === p ? 'var(--bg)' : 'var(--ink)', cursor:'pointer' }}>
                  {p}
                </button>
              ))}
            </div>

            {/* Step 3: agreements included */}
            {stmtOut && stmtOut.agreements.length > 0 && (
              <>
                <Sec num="03">Agreements included</Sec>
                <div style={{ marginTop:14, border:'1px solid var(--rule)' }}>
                  {stmtOut.agreements.map((ag, i) => (
                    <div key={ag.id} style={{ padding:'14px 16px', borderBottom: i < stmtOut.agreements.length - 1 ? '1px solid var(--rule-soft)' : 'none', display:'flex', justifyContent:'space-between', alignItems:'center', gap:14 }}>
                      <div style={{ display:'flex', gap:10, alignItems:'center', minWidth:0 }}>
                        <span className="ff-mono" style={{ fontSize:11, fontWeight:600, padding:'3px 8px', border:'1px solid var(--rule)' }}>{ag.id}</span>
                        <div style={{ minWidth:0 }}>
                          <div style={{ fontSize:13, fontWeight:500, overflow:'hidden', textOverflow:'ellipsis', whiteSpace:'nowrap' }}>{ag.a} × {ag.b}</div>
                          <div className="ff-mono upper" style={{ fontSize:9, color:'var(--ink-3)', letterSpacing:'.1em', marginTop:2 }}>{ag.kind}</div>
                        </div>
                      </div>
                      <span className="ff-mono num" style={{ fontSize:12, color:'var(--ink-2)', flexShrink:0 }}>
                        {(ag.parties || []).find(p => p.name === counterparty?.name)?.share || '—'}%
                      </span>
                    </div>
                  ))}
                </div>
              </>
            )}

            {stmtOut && stmtOut.agreements.length === 0 && (
              <>
                <Sec num="03">Agreements included</Sec>
                <div style={{ marginTop:14, padding:'24px', border:'1px dashed var(--rule)', textAlign:'center', color:'var(--ink-3)', fontSize:13 }}>
                  No active agreements found between you and {counterpartyName}. Agreements drive the math — without one, no statement can be issued.
                </div>
              </>
            )}
          </div>

          {/* Right rail: live summary card */}
          <div style={{ position:'sticky', top:80 }}>
            <div style={{ border:'1px solid var(--rule)', background:'var(--paper)' }}>
              <div style={{ padding:'14px 18px', borderBottom:'1px solid var(--rule)', background:'var(--bg-2)' }}>
                <div className="ff-mono upper" style={{ fontSize:10, letterSpacing:'.12em', color:'var(--ink-3)', marginBottom:4 }}>NET PAYABLE</div>
                <div className="ff-display num" style={{ fontSize:32, fontWeight:600, letterSpacing:'-0.02em' }}>
                  {stmtOut ? fmt$(stmtOut.net) : '—'}
                </div>
                {stmtOut && (
                  <div className="ff-mono" style={{ fontSize:11, color:'var(--ink-3)', marginTop:4 }}>
                    {counterparty?.name} · {period}
                  </div>
                )}
              </div>

              {stmtOut && (
                <div style={{ padding:'12px 18px', fontSize:12 }}>
                  {[
                    ['Gross collected',  fmt$(stmtOut.gross)],
                    [`Counterparty share (${stmtOut.cpartyShare}%)`, fmt$(stmtOut.grossShare)],
                    [`Admin fee (${(stmtOut.adminFeeRate*100).toFixed(0)}%)`, '−' + fmt$(stmtOut.adminFee)],
                    stmtOut.recoupment > 0 ? ['Recoupment', '−' + fmt$(stmtOut.recoupment)] : null,
                    stmtOut.witholding > 0 ? ['Withholding', '−' + fmt$(stmtOut.witholding)] : null,
                  ].filter(Boolean).map(([l, v]) => (
                    <div key={l} style={{ display:'flex', justifyContent:'space-between', padding:'6px 0', borderBottom:'1px solid var(--rule-soft)' }}>
                      <span style={{ color:'var(--ink-2)' }}>{l}</span>
                      <span className="ff-mono num" style={{ fontWeight:500 }}>{v}</span>
                    </div>
                  ))}
                  <div style={{ display:'flex', justifyContent:'space-between', padding:'10px 0 4px', marginTop:4, borderTop:'2px solid var(--ink)' }}>
                    <span className="ff-mono upper" style={{ fontSize:10, letterSpacing:'.1em', fontWeight:700 }}>NET</span>
                    <span className="ff-mono num" style={{ fontWeight:700, fontSize:14 }}>{fmt$(stmtOut.net)}</span>
                  </div>
                </div>
              )}

              <div style={{ padding:'14px 18px', display:'flex', flexDirection:'column', gap:8, borderTop: stmtOut ? '1px solid var(--rule)' : 'none' }}>
                <button onClick={() => setShowPreview(true)} disabled={!stmtOut || stmtOut.agreements.length === 0}
                  className="ff-mono upper"
                  style={{ padding:'12px', fontSize:11, letterSpacing:'.08em', fontWeight:600, border:'1px solid var(--rule)', background:'transparent', cursor: stmtOut ? 'pointer' : 'not-allowed', opacity: stmtOut ? 1 : .5 }}>
                  PREVIEW DOCUMENT
                </button>
                <button onClick={() => setPrintMode(true)} disabled={!stmtOut || stmtOut.agreements.length === 0}
                  className="ff-mono upper"
                  style={{ padding:'12px', fontSize:11, letterSpacing:'.08em', fontWeight:600, border:0, background:'var(--ink)', color:'var(--bg)', cursor: stmtOut ? 'pointer' : 'not-allowed', opacity: stmtOut ? 1 : .5 }}>
                  GENERATE PDF · ⌘P
                </button>
                <button onClick={() => window.toast && window.toast(`Statement filed on ${counterparty?.name} — emailed to AP contact`)} disabled={!stmtOut || stmtOut.agreements.length === 0}
                  className="ff-mono upper"
                  style={{ padding:'12px', fontSize:11, letterSpacing:'.08em', fontWeight:600, border:0, background:'var(--accent)', color:'var(--accent-ink)', cursor: stmtOut ? 'pointer' : 'not-allowed', opacity: stmtOut ? 1 : .5 }}>
                  SEND TO COUNTERPARTY ↗
                </button>
              </div>
            </div>

            {/* Recent statements card */}
            <div style={{ border:'1px solid var(--rule)', marginTop:18 }}>
              <div style={{ padding:'12px 18px', borderBottom:'1px solid var(--rule)' }}>
                <div className="ff-mono upper" style={{ fontSize:10, letterSpacing:'.12em', color:'var(--ink-3)' }}>RECENT STATEMENTS-OUT</div>
              </div>
              {[
                { d:'2026-04-08', cp:'Jane Co-writer', period:'Q1 2026', net:18420 },
                { d:'2026-04-07', cp:'Producer X',     period:'Q1 2026', net:9240 },
                { d:'2026-01-12', cp:'Sub-pub UK',     period:'Q4 2025', net:43800 },
              ].map((r, i) => (
                <div key={i} style={{ padding:'10px 18px', borderBottom: i < 2 ? '1px solid var(--rule-soft)' : 'none', display:'flex', justifyContent:'space-between', fontSize:11 }}>
                  <div>
                    <div style={{ fontWeight:600 }}>{r.cp}</div>
                    <div className="ff-mono" style={{ color:'var(--ink-3)', fontSize:10, marginTop:2 }}>{r.period} · {r.d}</div>
                  </div>
                  <span className="ff-mono num" style={{ fontWeight:600 }}>{fmt$(r.net)}</span>
                </div>
              ))}
            </div>
          </div>
        </div>

        {/* Inline preview */}
        {showPreview && stmtOut && (
          <div style={{ marginTop:48, paddingTop:32, borderTop:'1px solid var(--rule)' }}>
            <div style={{ display:'flex', justifyContent:'space-between', alignItems:'baseline', marginBottom:18 }}>
              <h2 className="ff-display" style={{ fontSize:24, fontWeight:600, letterSpacing:'-0.02em', margin:0 }}>Preview</h2>
              <div style={{ display:'flex', gap:8 }}>
                <button onClick={() => setShowPreview(false)} className="ff-mono upper" style={{ padding:'8px 12px', fontSize:10, letterSpacing:'.08em', border:'1px solid var(--rule)', background:'transparent', cursor:'pointer' }}>HIDE</button>
                <button onClick={() => setPrintMode(true)} className="ff-mono upper" style={{ padding:'8px 12px', fontSize:10, letterSpacing:'.08em', border:0, background:'var(--ink)', color:'var(--bg)', cursor:'pointer' }}>OPEN FULL · ⌘P</button>
              </div>
            </div>
            <div style={{ background:'#f4f3ee', padding:'40px 0', display:'flex', justifyContent:'center' }}>
              <div style={{ transform:'scale(0.85)', transformOrigin:'top center' }}>
                <DocumentBody stmt={stmtOut} />
              </div>
            </div>
          </div>
        )}
      </div>
    );
  }

  function Sec({ num, children }) {
    return (
      <div style={{ display:'flex', justifyContent:'space-between', alignItems:'baseline', borderBottom:'1px solid var(--rule)', padding:'12px 0 10px', marginTop:24 }}>
        <div style={{ display:'flex', gap:10, alignItems:'baseline' }}>
          {num && <span className="ff-mono" style={{ fontSize:10, color:'var(--ink-3)', letterSpacing:'.08em' }}>{num}</span>}
          <h3 className="ff-display" style={{ fontSize:18, fontWeight:600, letterSpacing:'-0.02em', margin:0 }}>{children}</h3>
        </div>
      </div>
    );
  }

  // ─────────── Print-mode chrome ───────────
  function StatementOutPrint({ stmt, onClose }) {
    return (
      <div style={{ position:'fixed', inset:0, background:'#3a3a3a', overflow:'auto', zIndex:1000 }}>
        {/* Toolbar (hidden on print) */}
        <div className="no-print" style={{ position:'sticky', top:0, padding:'12px 24px', background:'var(--ink)', color:'var(--bg)', display:'flex', justifyContent:'space-between', alignItems:'center', zIndex:2 }}>
          <div className="ff-mono upper" style={{ fontSize:11, letterSpacing:'.12em', fontWeight:600 }}>STATEMENT-OUT · PRINT PREVIEW · USE ⌘-P TO SAVE AS PDF</div>
          <div style={{ display:'flex', gap:10 }}>
            <button onClick={() => window.print()} className="ff-mono upper" style={{ padding:'8px 14px', fontSize:11, letterSpacing:'.08em', fontWeight:600, border:'1px solid #fff', background:'transparent', color:'#fff', cursor:'pointer' }}>PRINT ⌘P</button>
            <button onClick={onClose} className="ff-mono upper" style={{ padding:'8px 14px', fontSize:11, letterSpacing:'.08em', fontWeight:600, border:0, background:'#fff', color:'var(--ink)', cursor:'pointer' }}>CLOSE ✕</button>
          </div>
        </div>

        {/* Print styles */}
        <style>{`
          @media print {
            .no-print { display: none !important; }
            body { background: white !important; }
            .so-page { box-shadow: none !important; margin: 0 !important; page-break-after: always; }
            .so-page:last-child { page-break-after: auto; }
          }
          @page { size: letter; margin: 0; }
        `}</style>

        <div style={{ padding:'40px 0' }}>
          <DocumentBody stmt={stmt} />
        </div>
      </div>
    );
  }

  // ─────────── The actual document ───────────
  function DocumentBody({ stmt }) {
    // Page-styled letter-size pages
    const pageStyle = {
      width: '8.5in',
      minHeight: '11in',
      background: '#fff',
      color: '#1a1a1a',
      margin: '0 auto 24px',
      padding: '0.75in 0.85in',
      boxShadow: '0 4px 24px rgba(0,0,0,0.4)',
      fontFamily: 'Georgia, "Times New Roman", serif',
      fontSize: 11,
      lineHeight: 1.5,
      boxSizing: 'border-box',
    };

    // Split line items across pages — page 1 cover + first 18 rows; subsequent pages 35 rows each
    const itemsPerCoverPage = 18;
    const itemsPerInnerPage = 36;
    const cover = stmt.lineItems.slice(0, itemsPerCoverPage);
    const rest = stmt.lineItems.slice(itemsPerCoverPage);
    const innerPages = [];
    for (let i = 0; i < rest.length; i += itemsPerInnerPage) {
      innerPages.push(rest.slice(i, i + itemsPerInnerPage));
    }

    const pageCount = 1 + innerPages.length + 1; // cover + line pages + summary

    return (
      <div>
        {/* Page 1 — Cover + first batch of detail */}
        <div className="so-page" style={pageStyle}>
          {/* Letterhead */}
          <div style={{ display:'flex', justifyContent:'space-between', alignItems:'flex-start', borderBottom:'2px solid #1a1a1a', paddingBottom:14, marginBottom:24 }}>
            <div>
              <div style={{ fontSize:22, fontWeight:700, letterSpacing:'-0.02em', fontFamily:'Helvetica, Arial, sans-serif' }}>Rocket Science LLC</div>
              <div style={{ fontSize:9, color:'#555', marginTop:4, fontFamily:'Helvetica, Arial, sans-serif', letterSpacing:'.04em' }}>NEW YORK · NY · USA · ASTRO STATEMENT-OUT v1</div>
            </div>
            <div style={{ textAlign:'right', fontSize:9, fontFamily:'Helvetica, Arial, sans-serif' }}>
              <div style={{ letterSpacing:'.1em', color:'#777', textTransform:'uppercase' }}>Statement</div>
              <div style={{ fontWeight:700, fontSize:14, marginTop:2 }}>№ {stmt.stmtNumber}</div>
              <div style={{ color:'#555', marginTop:2 }}>Issued {stmt.generatedAt.slice(0,10)}</div>
            </div>
          </div>

          {/* Recipient block */}
          <div style={{ display:'grid', gridTemplateColumns:'1fr 1fr', gap:40, marginBottom:24 }}>
            <div>
              <div style={{ fontSize:8, letterSpacing:'.14em', textTransform:'uppercase', color:'#888', marginBottom:6, fontFamily:'Helvetica, Arial, sans-serif' }}>To</div>
              <div style={{ fontSize:14, fontWeight:700, marginBottom:4 }}>{stmt.counterparty.name}</div>
              <div style={{ fontSize:10, color:'#555' }}>
                Role on file: {stmt.counterparty.role}<br/>
                {stmt.agreements.length} agreement{stmt.agreements.length === 1 ? '' : 's'} active
              </div>
            </div>
            <div>
              <div style={{ fontSize:8, letterSpacing:'.14em', textTransform:'uppercase', color:'#888', marginBottom:6, fontFamily:'Helvetica, Arial, sans-serif' }}>Period</div>
              <div style={{ fontSize:14, fontWeight:700, marginBottom:4 }}>{stmt.period}</div>
              <div style={{ fontSize:10, color:'#555' }}>
                {stmt.lineCount.toLocaleString()} income lines reconciled
              </div>
            </div>
          </div>

          {/* Net payable hero */}
          <div style={{ background:'#1a1a1a', color:'#fff', padding:'24px 28px', marginBottom:24, display:'grid', gridTemplateColumns:'1fr auto', alignItems:'flex-end', gap:20 }}>
            <div>
              <div style={{ fontSize:8, letterSpacing:'.16em', textTransform:'uppercase', opacity:.6, marginBottom:6, fontFamily:'Helvetica, Arial, sans-serif' }}>Net payable to {stmt.counterparty.name}</div>
              <div style={{ fontSize:36, fontWeight:700, letterSpacing:'-0.02em', fontFamily:'Helvetica, Arial, sans-serif' }}>{fmt$(stmt.net)}</div>
            </div>
            <div style={{ fontSize:9, opacity:.7, fontFamily:'Helvetica, Arial, sans-serif', textAlign:'right' }}>
              Payable on or before<br/>
              <span style={{ fontWeight:600, color:'#fff', fontSize:11 }}>{(() => {
                const d = new Date(stmt.generatedAt); d.setDate(d.getDate() + 30);
                return d.toISOString().slice(0,10);
              })()}</span>
            </div>
          </div>

          {/* Summary table */}
          <SummaryTable stmt={stmt} />

          {/* Detail header */}
          <div style={{ marginTop:32 }}>
            <div style={{ fontSize:9, letterSpacing:'.14em', textTransform:'uppercase', color:'#888', marginBottom:8, fontFamily:'Helvetica, Arial, sans-serif' }}>Detail · Page 1 of {pageCount}</div>
            <DetailTable items={cover} />
          </div>

          {/* Footer */}
          <DocumentFooter pageNum={1} pageCount={pageCount} stmtNumber={stmt.stmtNumber} />
        </div>

        {/* Inner pages — line item continuation */}
        {innerPages.map((items, i) => (
          <div key={i} className="so-page" style={pageStyle}>
            <div style={{ display:'flex', justifyContent:'space-between', alignItems:'baseline', borderBottom:'1px solid #ccc', paddingBottom:8, marginBottom:18, fontSize:9, fontFamily:'Helvetica, Arial, sans-serif', color:'#777', textTransform:'uppercase', letterSpacing:'.1em' }}>
              <span>Statement № {stmt.stmtNumber} · {stmt.counterparty.name} · {stmt.period}</span>
              <span>Detail · Page {i + 2} of {pageCount}</span>
            </div>
            <DetailTable items={items} />
            <DocumentFooter pageNum={i + 2} pageCount={pageCount} stmtNumber={stmt.stmtNumber} />
          </div>
        ))}

        {/* Final page — totals + signature */}
        <div className="so-page" style={pageStyle}>
          <div style={{ display:'flex', justifyContent:'space-between', alignItems:'baseline', borderBottom:'1px solid #ccc', paddingBottom:8, marginBottom:24, fontSize:9, fontFamily:'Helvetica, Arial, sans-serif', color:'#777', textTransform:'uppercase', letterSpacing:'.1em' }}>
            <span>Statement № {stmt.stmtNumber} · {stmt.counterparty.name} · {stmt.period}</span>
            <span>Summary · Page {pageCount} of {pageCount}</span>
          </div>

          <div style={{ fontSize:18, fontWeight:700, marginBottom:18, letterSpacing:'-0.01em' }}>Reconciliation summary</div>

          <SummaryTable stmt={stmt} verbose />

          {/* Agreement references */}
          <div style={{ marginTop:32 }}>
            <div style={{ fontSize:9, letterSpacing:'.14em', textTransform:'uppercase', color:'#888', marginBottom:8, fontFamily:'Helvetica, Arial, sans-serif' }}>Agreements applied</div>
            <table style={{ width:'100%', fontSize:10, borderCollapse:'collapse' }}>
              <thead>
                <tr style={{ borderBottom:'1px solid #1a1a1a' }}>
                  <th style={{ textAlign:'left', padding:'6px 0', textTransform:'uppercase', fontSize:8, letterSpacing:'.1em', color:'#777', fontFamily:'Helvetica, Arial, sans-serif' }}>Agreement</th>
                  <th style={{ textAlign:'left', padding:'6px 0', textTransform:'uppercase', fontSize:8, letterSpacing:'.1em', color:'#777', fontFamily:'Helvetica, Arial, sans-serif' }}>Type</th>
                  <th style={{ textAlign:'right', padding:'6px 0', textTransform:'uppercase', fontSize:8, letterSpacing:'.1em', color:'#777', fontFamily:'Helvetica, Arial, sans-serif' }}>Share</th>
                </tr>
              </thead>
              <tbody>
                {stmt.agreements.map(ag => (
                  <tr key={ag.id} style={{ borderBottom:'1px solid #eee' }}>
                    <td style={{ padding:'8px 0' }}>
                      <div style={{ fontWeight:700 }}>{ag.id}</div>
                      <div style={{ color:'#777', fontSize:9, marginTop:2 }}>{ag.a} × {ag.b}</div>
                    </td>
                    <td style={{ padding:'8px 0', color:'#444', fontFamily:'Helvetica, Arial, sans-serif', textTransform:'uppercase', fontSize:9 }}>{ag.kind}</td>
                    <td style={{ padding:'8px 0', textAlign:'right', fontFamily:'Helvetica, Arial, sans-serif', fontWeight:700 }}>
                      {(ag.parties || []).find(p => p.name === stmt.counterparty.name)?.share || '—'}%
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>

          {/* Signature block */}
          <div style={{ marginTop:48, display:'grid', gridTemplateColumns:'1fr 1fr', gap:60, paddingTop:24, borderTop:'1px solid #1a1a1a' }}>
            <div>
              <div style={{ fontSize:9, color:'#888', textTransform:'uppercase', letterSpacing:'.1em', marginBottom:32, fontFamily:'Helvetica, Arial, sans-serif' }}>Issued by</div>
              <div style={{ borderBottom:'1px solid #1a1a1a', paddingBottom:4, marginBottom:6, fontStyle:'italic', fontFamily:'"Brush Script MT", cursive', fontSize:18 }}>Paul Womack</div>
              <div style={{ fontSize:10, fontWeight:700 }}>Paul Womack</div>
              <div style={{ fontSize:9, color:'#555' }}>Managing Member · Rocket Science LLC</div>
              <div style={{ fontSize:9, color:'#555', marginTop:2 }}>{stmt.generatedAt.slice(0,10)}</div>
            </div>
            <div>
              <div style={{ fontSize:9, color:'#888', textTransform:'uppercase', letterSpacing:'.1em', marginBottom:32, fontFamily:'Helvetica, Arial, sans-serif' }}>Acknowledged by</div>
              <div style={{ borderBottom:'1px solid #ccc', paddingBottom:4, marginBottom:6, height:30 }}></div>
              <div style={{ fontSize:10, fontWeight:700 }}>{stmt.counterparty.name}</div>
              <div style={{ fontSize:9, color:'#555' }}>Authorized signatory</div>
              <div style={{ fontSize:9, color:'#555', marginTop:2 }}>Date: __________________</div>
            </div>
          </div>

          {/* Notes */}
          <div style={{ marginTop:40, fontSize:9, color:'#666', fontStyle:'italic', borderTop:'1px solid #eee', paddingTop:14, lineHeight:1.6 }}>
            Royalties calculated per the executed agreements identified above. Counterparty has 90 days to dispute any line item from the statement issue date. Disputes received after this period are deemed accepted. Payment is due within 30 days of issue date via ACH or wire transfer to the account on file.
          </div>

          <DocumentFooter pageNum={pageCount} pageCount={pageCount} stmtNumber={stmt.stmtNumber} />
        </div>
      </div>
    );
  }

  function SummaryTable({ stmt, verbose }) {
    const rows = [
      ['Gross collected (across all sources)',                    fmt$(stmt.gross),       null],
      [`Counterparty share per agreement (${stmt.cpartyShare}%)`, fmt$(stmt.grossShare),  null],
      [`Administration fee (${(stmt.adminFeeRate*100).toFixed(0)}% of share)`, '−' + fmt$(stmt.adminFee), null],
      stmt.recoupment > 0 ? ['Recoupment against advance balance', '−' + fmt$(stmt.recoupment), null] : null,
      stmt.witholding > 0 ? ['Withholding tax', '−' + fmt$(stmt.witholding), null] : null,
    ].filter(Boolean);
    return (
      <table style={{ width:'100%', borderCollapse:'collapse', fontSize:11 }}>
        <tbody>
          {rows.map(([l, v], i) => (
            <tr key={i} style={{ borderBottom:'1px solid #eee' }}>
              <td style={{ padding:'10px 0', color:'#333' }}>{l}</td>
              <td style={{ padding:'10px 0', textAlign:'right', fontFamily:'Helvetica, Arial, sans-serif', fontWeight:500 }}>{v}</td>
            </tr>
          ))}
          <tr style={{ borderTop:'2px solid #1a1a1a', borderBottom:'2px solid #1a1a1a' }}>
            <td style={{ padding:'12px 0', fontWeight:700, textTransform:'uppercase', letterSpacing:'.06em', fontSize:10, fontFamily:'Helvetica, Arial, sans-serif' }}>Net payable</td>
            <td style={{ padding:'12px 0', textAlign:'right', fontWeight:700, fontSize:14, fontFamily:'Helvetica, Arial, sans-serif' }}>{fmt$(stmt.net)}</td>
          </tr>
        </tbody>
      </table>
    );
  }

  function DetailTable({ items }) {
    return (
      <table style={{ width:'100%', fontSize:9.5, borderCollapse:'collapse', fontFamily:'Helvetica, Arial, sans-serif' }}>
        <thead>
          <tr style={{ borderBottom:'1px solid #1a1a1a' }}>
            <th style={{ textAlign:'left',  padding:'6px 4px', textTransform:'uppercase', fontSize:8, letterSpacing:'.08em', color:'#777' }}>Title</th>
            <th style={{ textAlign:'left',  padding:'6px 4px', textTransform:'uppercase', fontSize:8, letterSpacing:'.08em', color:'#777' }}>ISRC</th>
            <th style={{ textAlign:'left',  padding:'6px 4px', textTransform:'uppercase', fontSize:8, letterSpacing:'.08em', color:'#777' }}>Source</th>
            <th style={{ textAlign:'right', padding:'6px 4px', textTransform:'uppercase', fontSize:8, letterSpacing:'.08em', color:'#777' }}>Units</th>
            <th style={{ textAlign:'right', padding:'6px 4px', textTransform:'uppercase', fontSize:8, letterSpacing:'.08em', color:'#777' }}>Gross</th>
          </tr>
        </thead>
        <tbody>
          {items.map((it, i) => (
            <tr key={i} style={{ borderBottom:'1px solid #f0f0f0' }}>
              <td style={{ padding:'5px 4px', maxWidth:200, overflow:'hidden', textOverflow:'ellipsis', whiteSpace:'nowrap' }}>
                <div style={{ fontWeight:600, color:'#1a1a1a' }}>{it.title}</div>
                {it.artist && <div style={{ fontSize:8.5, color:'#888', fontStyle:'italic', marginTop:1 }}>{it.artist}</div>}
              </td>
              <td style={{ padding:'5px 4px', color:'#555', fontSize:9 }}>{it.isrc || '—'}</td>
              <td style={{ padding:'5px 4px', color:'#555', textTransform:'uppercase', fontSize:8.5, letterSpacing:'.04em' }}>{it.source}</td>
              <td style={{ padding:'5px 4px', textAlign:'right', color:'#555' }}>{(it.count || 0).toLocaleString()}</td>
              <td style={{ padding:'5px 4px', textAlign:'right', fontWeight:600 }}>{fmt$(it.gross)}</td>
            </tr>
          ))}
        </tbody>
      </table>
    );
  }

  function DocumentFooter({ pageNum, pageCount, stmtNumber }) {
    return (
      <div style={{ position:'absolute', bottom:'0.4in', left:'0.85in', right:'0.85in', display:'flex', justifyContent:'space-between', fontSize:8, color:'#999', textTransform:'uppercase', letterSpacing:'.1em', fontFamily:'Helvetica, Arial, sans-serif', borderTop:'1px solid #eee', paddingTop:8 }}>
        <span>Rocket Science LLC · ASTRO Statement-Out</span>
        <span>{stmtNumber}</span>
        <span>{pageNum} / {pageCount}</span>
      </div>
    );
  }

  Object.assign(window, { ScreenStatementOut, StatementOutPrint });
})();
