// ─────────────────────────────────────────────────────────────────────
// MONTHLY EXPENSE REPORT — expense sheet · document preview · email.
// The back half of the flow. The document is rendered from the same
// records the workspace edits — change a record, the report changes.
// ─────────────────────────────────────────────────────────────────────

const { useState: useRS } = React;

// ── The original document — pulled from the Vault, shown as captured ──
function OriginalViewerSheet({ expense, onClose }) {
  const x = expense;
  const isPhoto = x.fileKind === 'photo';
  const baseId = x.baseId || x.id;
  // Every line item captured from this same document (invoice-level view).
  const lines = REPORT_EXPENSES.filter(e => e.vendor === x.vendor && e.date === x.date && e.period === x.period);
  const total = lines.reduce((s, e) => s + e.amount, 0);
  // Cream "scan" palette — reads as a real captured document, not UI chrome.
  const PAPER = '#f2ecdd', PINK = '#26221a', PRULE = '#cdbf9f', PMUTE = '#8a8068', PGOLD = '#8a6a30';
  const docLabel = { fontFamily: T.mono, fontSize: 7, letterSpacing: '0.16em', textTransform: 'uppercase', color: PMUTE };
  const invNo = (x.file || '').replace(/\.[a-z]+$/i, '');

  const paper = (
    <div style={{
      position: 'relative', width: '100%',
      transform: isPhoto ? 'rotate(-1.4deg)' : 'none',
      boxShadow: '0 22px 50px rgba(0,0,0,0.6)',
    }}>
      {/* scanner light-band + torn top edge sell the "captured original" read */}
      <div style={{
        background: PAPER, color: PINK, padding: '22px 20px 20px', position: 'relative', overflow: 'hidden',
        backgroundImage: 'linear-gradient(180deg, rgba(0,0,0,0.05), rgba(0,0,0,0) 8%), repeating-linear-gradient(90deg, rgba(0,0,0,0.015) 0 2px, rgba(0,0,0,0) 2px 4px)',
      }}>
        {/* faint diagonal ORIGINAL watermark */}
        <div aria-hidden="true" style={{
          position: 'absolute', inset: 0, display: 'flex', alignItems: 'center', justifyContent: 'center',
          transform: 'rotate(-24deg)', pointerEvents: 'none',
          fontFamily: T.mono, fontSize: 46, fontWeight: 700, letterSpacing: '0.3em',
          color: 'rgba(38,34,26,0.05)', whiteSpace: 'nowrap',
        }}>ORIGINAL</div>

        {/* letterhead */}
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', gap: 12, position: 'relative' }}>
          <div style={{ minWidth: 0 }}>
            <div style={{ fontFamily: T.display, fontSize: 18, fontWeight: 700, letterSpacing: '-0.01em', lineHeight: 1.05, color: PINK }}>{x.vendor}</div>
            <div style={{ ...docLabel, marginTop: 6 }}>{isPhoto ? 'Sales receipt' : 'Vendor invoice'}</div>
          </div>
          <div style={{ textAlign: 'right', flexShrink: 0 }}>
            <div style={{ ...docLabel, color: PMUTE }}>{isPhoto ? 'Receipt' : 'Invoice'} №</div>
            <div style={{ fontFamily: T.mono, fontSize: 10, fontWeight: 600, color: PINK, marginTop: 2 }}>{invNo}</div>
            <div style={{ fontFamily: T.body, fontSize: 10, color: PMUTE, marginTop: 5 }}>{x.date}, 2026</div>
          </div>
        </div>

        <div style={{ height: 1.5, background: PINK, margin: '15px 0 0' }} />
        <div style={{ display: 'flex', justifyContent: 'space-between', padding: '7px 6px 6px' }}>
          <span style={{ ...docLabel, color: PMUTE }}>Description</span>
          <span style={{ ...docLabel, color: PMUTE }}>Amount · USD</span>
        </div>

        {lines.map(e => {
          const hit = e.id === baseId;
          return (
            <div key={e.id} style={{
              display: 'flex', justifyContent: 'space-between', gap: 10, alignItems: 'baseline',
              borderBottom: `1px solid ${PRULE}`, padding: '8px 6px',
              background: hit ? 'rgba(138,106,48,0.12)' : 'transparent',
            }}>
              <span style={{ fontFamily: T.body, fontSize: 10.5, color: '#2a261f', minWidth: 0, lineHeight: 1.35 }}>
                {e.desc}
                {hit && <span style={{ display: 'block', fontFamily: T.mono, fontSize: 6.5, letterSpacing: '0.14em', textTransform: 'uppercase', color: PGOLD, marginTop: 2 }}>← this expense</span>}
              </span>
              <span style={{ fontFamily: T.mono, fontSize: 10, flexShrink: 0, color: PINK }}>{rMoney(e.amount)}</span>
            </div>
          );
        })}

        <div style={{
          display: 'flex', justifyContent: 'space-between', alignItems: 'baseline',
          marginTop: 10, paddingTop: 9, borderTop: `2px solid ${PINK}`,
        }}>
          <span style={{ fontFamily: T.display, fontSize: 12, fontWeight: 700, letterSpacing: '0.04em', color: PINK }}>TOTAL</span>
          <span style={{ fontFamily: T.display, fontSize: 19, fontWeight: 700, letterSpacing: '-0.01em', color: PINK }}>{rMoney(total)}</span>
        </div>

        {/* signature row — a tell of a real document */}
        <div style={{ marginTop: 16 }}>
          <div style={{ fontFamily: '"Snell Roundhand", "Segoe Script", cursive', fontSize: 17, color: '#3a3324', lineHeight: 1 }}>{x.vendor.split(' ')[0]}</div>
          <div style={{ height: 1, background: PRULE, marginTop: 3, width: 118 }} />
          <div style={{ ...docLabel, marginTop: 4 }}>Authorized signature</div>
        </div>
      </div>

      {/* scan/vault provenance strip beneath the sheet */}
      <div style={{
        background: '#e4dcc6', borderTop: `1px dashed ${PRULE}`,
        padding: '8px 20px', fontFamily: T.mono, fontSize: 6.5, letterSpacing: '0.14em',
        textTransform: 'uppercase', color: PMUTE, lineHeight: 1.7,
      }}>
        {isPhoto ? 'Photographed' : 'Scanned'} original · {x.file} · captured via Upload Expense · preserved in the Vault
      </div>
    </div>
  );

  const node = (
    <div style={{ position: 'absolute', inset: 0, zIndex: 98, display: 'flex', flexDirection: 'column' }}>
      <div onClick={onClose} style={{ position: 'absolute', inset: 0, background: 'rgba(10,10,11,0.92)', animation: 'sheetFade .2s ease' }} />
      <div style={{ position: 'relative', flex: '0 0 auto', display: 'flex', alignItems: 'center', gap: 12, padding: '16px 18px 10px' }}>
        <button onClick={onClose} aria-label="Close" style={{
          width: 34, height: 34, flexShrink: 0, background: 'transparent', border: `1px solid ${P.slate}`,
          color: P.paper, cursor: 'pointer', fontFamily: T.mono, fontSize: 15, lineHeight: 1,
        }}>×</button>
        <div style={{ minWidth: 0 }}>
          <div style={{ fontFamily: T.body, fontSize: 12.5, color: P.paper, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{x.file}</div>
          <RptMono size={7.5} color={P.gold} style={{ display: 'block', marginTop: 3 }}>
            {isPhoto ? 'PHOTO CAPTURE' : 'PDF'} · ORIGINAL PRESERVED · VAULT
          </RptMono>
        </div>
      </div>
      <div className="proto-scroll" style={{ position: 'relative', flex: 1, overflow: 'auto', padding: '10px 26px 30px', animation: 'sheetIn .25s cubic-bezier(.2,.7,.3,1)' }}>
        {paper}
      </div>
    </div>
  );
  const stage = (typeof document !== 'undefined') ? document.getElementById('proto-stage') : null;
  return stage ? ReactDOM.createPortal(node, stage) : node;
}

// ── Expense sheet — review / edit / exclude / delete, from any phase ──
function ReportExpenseSheet({ expense, locked = false, onClose }) {
  const store = useReportStore();
  // Split shares carry a baseId — all record state lives on the base expense.
  const baseId = expense.baseId || expense.id;
  const x = { ...expense, ...(expense.baseId ? {} : (store.edits[baseId] || {})) };
  const excluded = !!store.excluded[baseId];
  const [mode, setMode] = useRS('view'); // view | edit | assign | confirm-delete
  const [desc, setDesc] = useRS(x.desc);
  const [amount, setAmount] = useRS(String(x.fullAmount || x.amount));
  const [note, setNote] = useRS(x.note || '');
  const [viewing, setViewing] = useRS(false);
  const tgt = reportTarget(x.vehicleId);
  // The invoice this expense was filed from — every line item captured together.
  const invoiceRows = REPORT_EXPENSES.filter(e => e.vendor === x.vendor && e.date === x.date && e.period === x.period);

  const saveEdit = () => {
    ReportStore.setIn('edits', baseId, {
      ...(store.edits[baseId] || {}),
      desc, amount: parseFloat(amount) || x.amount, note: note.trim() || null,
    });
    setMode('view');
  };

  const inputStyle = {
    width: '100%', background: P.ink, border: `1px solid ${P.slate}`,
    padding: '10px 12px', color: P.paper, outline: 'none',
    fontFamily: T.body, fontSize: 12.5,
  };

  const actionRow = (icon, label, onClick, danger = false) => (
    <button onClick={onClick} style={{
      width: '100%', display: 'flex', alignItems: 'center', gap: 12, padding: '13px 14px',
      background: P.ink, border: `1px solid ${danger ? P.signal : P.slate}`, cursor: 'pointer',
      color: danger ? P.signal : P.paper, textAlign: 'left',
      fontFamily: T.mono, fontSize: 10, fontWeight: 600, letterSpacing: '0.16em', textTransform: 'uppercase',
    }}>
      <Icon name={icon} size={16} color={danger ? P.signal : P.gold} strokeWidth={1.6} />
      {label}
    </button>
  );

  const node = (
    <div style={{ position: 'absolute', inset: 0, zIndex: 97 }}>
      <div onClick={onClose} style={{
        position: 'absolute', inset: 0, background: 'rgba(10,10,11,0.8)',
        backdropFilter: 'blur(2px)', WebkitBackdropFilter: 'blur(2px)', animation: 'sheetFade .2s ease',
      }} />
      <div className="proto-scroll" style={{
        position: 'absolute', left: 0, right: 0, bottom: 0, maxHeight: '82%', overflow: 'auto',
        background: P.graphite, borderTop: `1px solid ${P.gold}`, padding: '14px 22px 34px',
        animation: 'sheetIn .25s cubic-bezier(.2,.7,.3,1)',
      }}>
        <div style={{ width: 40, height: 4, background: P.slate, margin: '0 auto 16px' }} />

        {/* header */}
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', gap: 12 }}>
          <div style={{ minWidth: 0 }}>
            <RptMono size={8} color={P.gold} tracking="0.18em">
              {x.category} · {tgt.short}
            </RptMono>
            <div style={{
              fontFamily: T.display, fontSize: 21, fontWeight: 700, color: P.paper,
              marginTop: 6, letterSpacing: '-0.01em', lineHeight: 1.05,
            }}>{x.vendor}</div>
            <RptMono size={8} style={{ display: 'block', marginTop: 5 }}>
              {x.date}, 2026 · {x.contributor ? `Submitted by ${x.contributor}` : 'Uploaded by you'}
            </RptMono>
          </div>
          <div style={{
            fontFamily: T.display, fontSize: 21, fontWeight: 700, color: P.gold, flexShrink: 0,
          }}>{rMoney(x.amount)}</div>
        </div>

        <div style={{ fontFamily: T.body, fontSize: 12.5, color: P.bone, marginTop: 12, lineHeight: 1.5 }}>
          {x.desc}
        </div>
        {x.note && (
          <div style={{ fontFamily: T.body, fontSize: 12, color: P.mute, marginTop: 8, lineHeight: 1.5, fontStyle: 'italic' }}>
            "{x.note}"
          </div>
        )}

        {/* original */}
        <div style={{ marginTop: 14 }}>
          <button onClick={() => setViewing(true)} style={{
            width: '100%', display: 'flex', alignItems: 'center', gap: 11, cursor: 'pointer',
            border: `1px solid ${P.slate}`, background: P.ink, padding: '12px 14px', textAlign: 'left',
          }}>
            <Icon name={x.fileKind === 'photo' ? 'gallery' : 'FileText'} size={18} color={P.gold} strokeWidth={1.5} />
            <div style={{ flex: 1, minWidth: 0 }}>
              <div style={{ fontFamily: T.body, fontSize: 12, color: P.paper }}>{store.attached[baseId] || x.file}</div>
              <RptMono size={7.5} style={{ display: 'block', marginTop: 2 }}>Original · preserved in the Vault</RptMono>
            </div>
            <RptMono size={8} color={P.gold}>View</RptMono>
          </button>
        </div>

        {/* actions */}
        {locked ? (
          <div style={{ marginTop: 16, display: 'flex', alignItems: 'center', gap: 10 }}>
            <span style={{ width: 5, height: 5, background: P.gold, flexShrink: 0 }} />
            <RptMono size={8} style={{ lineHeight: 1.6 }}>Part of a sent report — archived exactly as delivered.</RptMono>
          </div>
        ) : mode === 'edit' ? (
          <div style={{ marginTop: 16, display: 'grid', gap: 10 }}>
            <div>
              <RptMono size={7.5} style={{ display: 'block', marginBottom: 5 }}>Description</RptMono>
              <input value={desc} onChange={e => setDesc(e.target.value)} style={inputStyle} />
            </div>
            <div>
              <RptMono size={7.5} style={{ display: 'block', marginBottom: 5 }}>Amount (USD)</RptMono>
              <input value={amount} onChange={e => setAmount(e.target.value)} inputMode="decimal" style={inputStyle} />
            </div>
            <div>
              <RptMono size={7.5} style={{ display: 'block', marginBottom: 5 }}>Note · printed on the report</RptMono>
              <textarea value={note} onChange={e => setNote(e.target.value)} rows={3}
                placeholder={x.vehicleId === 'none' ? 'Explain why this expense was left unassigned' : 'Optional context for the recipients'}
                style={{ ...inputStyle, resize: 'none', lineHeight: 1.5 }} />
            </div>
            <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 8, marginTop: 4 }}>
              <button onClick={() => setMode('view')} style={{
                height: 46, background: 'transparent', border: `1px solid ${P.slate}`, color: P.paper,
                fontFamily: T.mono, fontSize: 9.5, fontWeight: 600, letterSpacing: '0.18em', textTransform: 'uppercase', cursor: 'pointer',
              }}>Cancel</button>
              <button onClick={saveEdit} style={{
                height: 46, background: P.gold, border: `1px solid ${P.gold}`, color: P.ink,
                fontFamily: T.mono, fontSize: 9.5, fontWeight: 700, letterSpacing: '0.18em', textTransform: 'uppercase', cursor: 'pointer',
              }}>Save Changes</button>
            </div>
          </div>
        ) : mode === 'confirm-delete' ? (
          <div style={{ marginTop: 16 }}>
            <div style={{ fontFamily: T.body, fontSize: 12, color: P.bone, lineHeight: 1.5 }}>
              Delete this entire invoice from the archive?
              {invoiceRows.length > 1
                ? ` All ${invoiceRows.length} line items filed from it — across every vehicle and category — are removed with it.`
                : ' Its line item is removed with it.'}
              {' '}Line items can't be deleted individually.
            </div>
            <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 8, marginTop: 12 }}>
              <button onClick={() => setMode('view')} style={{
                height: 46, background: 'transparent', border: `1px solid ${P.slate}`, color: P.paper,
                fontFamily: T.mono, fontSize: 9.5, fontWeight: 600, letterSpacing: '0.18em', textTransform: 'uppercase', cursor: 'pointer',
              }}>Keep</button>
              <button onClick={() => { invoiceRows.forEach(e => ReportStore.setIn('deleted', e.id, true)); onClose(); }} style={{
                height: 46, background: P.signal, border: `1px solid ${P.signal}`, color: P.paper,
                fontFamily: T.mono, fontSize: 9.5, fontWeight: 700, letterSpacing: '0.18em', textTransform: 'uppercase', cursor: 'pointer',
              }}>Delete Invoice</button>
            </div>
          </div>
        ) : (
          <div style={{ marginTop: 16, display: 'grid', gap: 8 }}>
            {actionRow('ArrowLeftRight', 'Change Assignment', () => setMode('assign'))}
            {actionRow('wrench', 'Edit Details', () => setMode('edit'))}
            {actionRow('flag', 'Delete Invoice', () => setMode('confirm-delete'), true)}
          </div>
        )}
      </div>

      {/* Change assignment — the SAME allocator used in Upload Expense */}
      {mode === 'assign' && (() => {
        const full = x.fullAmount || x.amount;
        const value = (x.split && x.split.length > 1)
          ? { mode: 'split', splits: x.split.map(sp => ({ ...sp })) }
          : x.vehicleId === 'overhead' ? { mode: 'overhead' }
          : x.vehicleId === 'none' ? { mode: 'none' }
          : { mode: 'vehicle', vehicleId: x.vehicleId };
        return (
          <AllocatorSheet
            line={{ desc: x.desc, net: full, suggest: x.vehicleId }}
            vehicles={vehiclePool([VEHICLE, VEHICLE_MERCEDES])}
            value={value}
            money={{ main: rMoney(full) }}
            onApply={(a) => {
              const prev = store.edits[baseId] || {};
              if (a.mode === 'split' && a.splits && a.splits.length > 1) {
                ReportStore.setIn('edits', baseId, { ...prev, split: a.splits.map(sp => ({ ...sp })), vehicleId: a.splits[0].id });
              } else {
                const vid = a.mode === 'vehicle' ? a.vehicleId
                  : a.mode === 'overhead' ? 'overhead'
                  : a.mode === 'none' ? 'none' : null;
                if (vid) ReportStore.setIn('edits', baseId, { ...prev, split: null, vehicleId: vid });
              }
            }}
            onClose={() => setMode('view')} />
        );
      })()}

      {viewing && (
        <OriginalViewerSheet expense={{ ...x, file: store.attached[baseId] || x.file, fileKind: store.attached[baseId] ? 'pdf' : x.fileKind }} onClose={() => setViewing(false)} />
      )}
    </div>
  );
  const stage = (typeof document !== 'undefined') ? document.getElementById('proto-stage') : null;
  return stage ? ReactDOM.createPortal(node, stage) : node;
}

// ── The document itself — ink on paper, rendered from the records ─────
function ReportPreview({ period, included, roll, sent, onOpenExpense, onViewOriginal, onContinue }) {
  const docLabel = { fontFamily: T.mono, fontSize: 7.5, letterSpacing: '0.18em', textTransform: 'uppercase', color: P.slate };
  const hair = `1px solid ${P.line}`;

  const kvTable = (title, entries) => (
    <div style={{ flex: 1, minWidth: 0 }}>
      <div style={docLabel}>{title}</div>
      <div style={{ marginTop: 6 }}>
        {entries.map(([k, v]) => (
          <div key={k} style={{
            display: 'flex', justifyContent: 'space-between', gap: 10,
            borderTop: hair, padding: '5px 0',
          }}>
            <span style={{ fontFamily: T.body, fontSize: 9.5, color: P.slate, minWidth: 0 }}>{k}</span>
            <span style={{ fontFamily: T.mono, fontSize: 9, color: P.ink, flexShrink: 0 }}>{rMoney(v)}</span>
          </div>
        ))}
      </div>
    </div>
  );

  return (
    <React.Fragment>
      <div className="proto-scroll" style={{ flex: 1, overflow: 'auto', background: P.ink }} data-screen-label="rpt-preview">
        <div style={{ padding: '16px 22px 12px', display: 'flex', justifyContent: 'space-between', alignItems: 'flex-end', gap: 12 }}>
          <div>
            <div style={{ fontFamily: T.display, fontWeight: 700, fontSize: 30, lineHeight: 0.92, letterSpacing: '-0.02em', color: P.paper }}>THE<br />DOCUMENT</div>
            <div style={{ fontFamily: T.body, fontSize: 11.5, color: P.mute, marginTop: 8, lineHeight: 1.45, maxWidth: 250 }}>
              A final preview of the document exactly as the recipient will receive it.
            </div>
          </div>
          <RptMono size={7.5} style={{ flexShrink: 0, paddingBottom: 4 }}>PDF · {roll.docs} originals</RptMono>
        </div>

        {/* THE PAPER */}
        <div style={{ margin: '4px 16px 18px', background: P.paper, color: P.ink, padding: '22px 18px 20px' }}>
          {/* doc header */}
          <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start' }}>
            <CAMonogram size={26} color={P.ink} stroke={1.5} />
            <div style={{ textAlign: 'right' }}>
              <div style={{ ...docLabel, color: P.ink }}>The Voss Collection</div>
              <div style={{ ...docLabel, marginTop: 2 }}>Collector Archives</div>
            </div>
          </div>
          <div style={{
            fontFamily: T.display, fontSize: 25, fontWeight: 700, letterSpacing: '-0.01em',
            lineHeight: 0.95, marginTop: 16,
          }}>EXPENSE<br />REPORT</div>
          <div style={{ marginTop: 12, borderTop: `2px solid ${P.ink}`, paddingTop: 8, display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 6 }}>
            {[
              ['Reporting period', period.range],
              ['Prepared by', 'Jeff Smith · Collection Manager'],
              ['Generated', sent ? sent.on : 'May 29, 2026'],
              ['Delivered to', ACCOUNTANT.name],
            ].map(([k, v]) => (
              <div key={k}>
                <div style={docLabel}>{k}</div>
                <div style={{ fontFamily: T.body, fontSize: 9.5, color: P.ink, marginTop: 2 }}>{v}</div>
              </div>
            ))}
          </div>

          {/* summary */}
          <div style={{ marginTop: 16, background: P.bone, padding: '12px 14px', display: 'flex', justifyContent: 'space-between', alignItems: 'baseline' }}>
            <div>
              <div style={docLabel}>Total for reimbursement</div>
              <div style={{ fontFamily: T.display, fontSize: 26, fontWeight: 700, letterSpacing: '-0.02em', marginTop: 2 }}>{rMoney(roll.total)}</div>
            </div>
            <div style={{ textAlign: 'right' }}>
              <div style={docLabel}>Expenses</div>
              <div style={{ fontFamily: T.display, fontSize: 16, fontWeight: 700, marginTop: 2 }}>{roll.count}</div>
            </div>
          </div>
          <div style={{ display: 'flex', gap: 16, marginTop: 14 }}>
            {kvTable('By vehicle', reportGroupOrder(included).filter(v => roll.byVehicle[v])
              .map(v => [reportTarget(v).short, roll.byVehicle[v]]))}
            {kvTable('By category', Object.entries(roll.byCategory).sort((a, b) => b[1] - a[1]))}
          </div>

          {/* details grouped by vehicle */}
          <div style={{ ...docLabel, marginTop: 30 }}>Expense detail</div>
          {reportGroupOrder(included).map((vid, gi) => {
            const rows = included.filter(x => x.vehicleId === vid);
            if (!rows.length) return null;
            const tgt = reportTarget(vid);
            return (
              <div key={vid} style={{ marginTop: gi === 0 ? 8 : 22 }}>
                <div style={{
                  display: 'flex', justifyContent: 'space-between', alignItems: 'baseline',
                  borderBottom: `1.5px solid ${P.ink}`, paddingBottom: 4,
                }}>
                  <span style={{ fontFamily: T.display, fontSize: 11.5, fontWeight: 700, letterSpacing: '0.03em' }}>
                    {tgt.title.toUpperCase()}
                  </span>
                  <span style={{ fontFamily: T.mono, fontSize: 9, fontWeight: 600 }}>
                    {rMoney(rows.reduce((s, x) => s + x.amount, 0))}
                  </span>
                </div>
                {rows.map(x => (
                  <div key={x.id} onClick={() => onOpenExpense(x)} style={{
                    borderBottom: hair, padding: '6px 0', cursor: 'pointer',
                  }}>
                    <div style={{ display: 'flex', justifyContent: 'space-between', gap: 10 }}>
                      <span style={{ fontFamily: T.body, fontSize: 9.5, fontWeight: 600, color: P.ink, minWidth: 0 }}>
                        {x.date} — {x.vendor}
                      </span>
                      <span style={{ fontFamily: T.mono, fontSize: 9, color: P.ink, flexShrink: 0 }}>{rMoney(x.amount)}</span>
                    </div>
                    <div style={{ fontFamily: T.body, fontSize: 9, color: P.slate, marginTop: 2, lineHeight: 1.35 }}>
                      {x.desc}
                    </div>
                    <div onClick={(e) => { e.stopPropagation(); onViewOriginal && onViewOriginal(x); }} style={{ fontFamily: T.mono, fontSize: 7, letterSpacing: '0.1em', textTransform: 'uppercase', color: P.mute, marginTop: 3 }}>
                      {x.category}{x.splitPct ? ` · split ${x.splitPct}%` : ''} · {x.contributor || 'Collection Manager'}{x.note ? ' · note' : ''} · <span style={{ color: '#8a6a30', fontWeight: 600 }}>encl. {x.file} ↗</span>
                    </div>
                    {x.vehicleId === 'none' && x.note && (
                      <div style={{ fontFamily: T.body, fontSize: 8.5, fontStyle: 'italic', color: P.slate, marginTop: 3, lineHeight: 1.4 }}>
                        Note: {x.note}
                      </div>
                    )}
                  </div>
                ))}
              </div>
            );
          })}

          {/* supporting docs — appended to the PDF as full-page images */}
          <div style={{ ...docLabel, marginTop: 18 }}>Supporting documentation · {roll.docs} originals attached</div>
          <div style={{ fontFamily: T.body, fontSize: 8.5, color: P.slate, marginTop: 4, lineHeight: 1.45 }}>
            Every original receipt and invoice is reproduced full-page in the PDF. Tap to view any document.
          </div>
          <div style={{ display: 'flex', flexWrap: 'wrap', gap: 4, marginTop: 8 }}>
            {[...new Set(included.filter(x => x.file).map(x => x.file))].map(f => {
              const src = included.find(x => x.file === f);
              return (
                <span key={f} role="button"
                  onClick={(e) => { e.stopPropagation(); onViewOriginal && src && onViewOriginal(src); }}
                  style={{
                    display: 'inline-flex', alignItems: 'center', gap: 5, border: `1px solid ${P.slate}`,
                    padding: '4px 7px', fontFamily: T.mono, fontSize: 7.5, color: P.ink, cursor: 'pointer',
                  }}>
                  <Icon name={/\.pdf$/i.test(f) ? 'FileText' : 'gallery'} size={10} color={'#8a6a30'} strokeWidth={1.6} />
                  {f}
                  <span style={{ color: '#8a6a30' }}>↗</span>
                </span>
              );
            })}
          </div>

          <div style={{ marginTop: 16, borderTop: hair, paddingTop: 8, fontFamily: T.mono, fontSize: 7, letterSpacing: '0.12em', textTransform: 'uppercase', color: P.mute, lineHeight: 1.7 }}>
            Rendered from the permanent archive · each line links to its full record
          </div>
        </div>
        <div style={{ height: 6 }} />
      </div>

      <div style={{ padding: '10px 22px 14px', borderTop: `1px solid ${P.graphite}`, background: P.ink, flex: '0 0 auto' }}>
        <button onClick={onContinue} style={{
          width: '100%', height: 52, background: P.gold, border: `1px solid ${P.gold}`,
          color: P.ink, cursor: 'pointer',
          display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 10,
          fontFamily: T.mono, fontSize: 11, fontWeight: 700, letterSpacing: '0.2em', textTransform: 'uppercase',
        }}>
          <Icon name="Send" size={15} color={P.ink} strokeWidth={1.8} />
          {sent ? 'Resend Report' : 'Email Report'}
        </button>
      </div>
    </React.Fragment>
  );
}

// ── Email — prefilled, sent directly from Collector Archives ─────────
function ReportEmail({ period, roll, onSend }) {
  const [subject, setSubject] = useRS(`The Voss Collection — Expense Report · ${period.label}`);
  const [body, setBody] = useRS(
    `Hi Patricia,\n\nAttached is the expense report for The Voss Collection covering ${period.label} — ${roll.count} expenses totaling ${rMoney(roll.total)}, with all original receipts and invoices enclosed.\n\nPlease process reimbursement at your convenience.\n\nJeff Smith\nCollection Manager`);

  const fieldLabel = { fontFamily: T.mono, fontSize: 7.5, letterSpacing: '0.18em', textTransform: 'uppercase', color: P.mute };

  return (
    <React.Fragment>
      <div className="proto-scroll" style={{ flex: 1, overflow: 'auto', background: P.ink }} data-screen-label="rpt-email">
        <div style={{ padding: '18px 22px 14px' }}>
          <div style={{ fontFamily: T.display, fontWeight: 700, fontSize: 30, lineHeight: 0.92, letterSpacing: '-0.02em', color: P.paper }}>SEND THE<br />PACKAGE</div>
          <div style={{ fontFamily: T.body, fontSize: 12, color: P.mute, marginTop: 9, lineHeight: 1.5, maxWidth: 310 }}>
            Emailed directly from Collector Archives — no printing, no scanning, no app-switching.
          </div>
        </div>

        <div style={{ padding: '0 22px', display: 'grid', gap: 12 }}>
          {/* To */}
          <div>
            <div style={fieldLabel}>To</div>
            <div style={{ display: 'grid', gap: 8, marginTop: 6 }}>
              <span style={{
                display: 'flex', alignItems: 'center', gap: 8, background: P.graphite,
                border: `1px solid ${P.slate}`, padding: '8px 11px',
              }}>
                <span style={{
                  width: 22, height: 22, borderRadius: 999, border: `1px solid ${P.gold}`, color: P.gold, flexShrink: 0,
                  display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
                  fontFamily: T.mono, fontSize: 7.5, fontWeight: 700,
                }}>PL</span>
                <span style={{ minWidth: 0 }}>
                  <span style={{ display: 'block', fontFamily: T.body, fontSize: 11.5, color: P.paper }}>{ACCOUNTANT.email}</span>
                  <span style={{ display: 'block', fontFamily: T.mono, fontSize: 7, letterSpacing: '0.12em', textTransform: 'uppercase', color: P.mute, marginTop: 1 }}>{ACCOUNTANT.role}</span>
                </span>
              </span>
              <button style={{
                width: '100%', height: 32, background: 'transparent', border: `1px dashed ${P.slate}`,
                color: P.mute, cursor: 'pointer', display: 'inline-flex', alignItems: 'center', justifyContent: 'center', gap: 8,
                fontFamily: T.mono, fontSize: 8.5, fontWeight: 600, letterSpacing: '0.16em', textTransform: 'uppercase',
              }}>
                <Icon name="add" size={14} color={P.mute} strokeWidth={1.6} /> Add Recipient
              </button>
            </div>
          </div>

          {/* Subject */}
          <div>
            <div style={fieldLabel}>Subject</div>
            <input value={subject} onChange={e => setSubject(e.target.value)} style={{
              width: '100%', marginTop: 6, background: P.graphite, border: `1px solid ${P.slate}`,
              padding: '11px 12px', color: P.paper, outline: 'none', fontFamily: T.body, fontSize: 12.5,
            }} />
          </div>

          {/* Message */}
          <div>
            <div style={fieldLabel}>Message</div>
            <textarea value={body} onChange={e => setBody(e.target.value)} rows={9} style={{
              width: '100%', marginTop: 6, background: P.graphite, border: `1px solid ${P.slate}`,
              padding: '11px 12px', color: P.bone, outline: 'none', resize: 'none',
              fontFamily: T.body, fontSize: 12, lineHeight: 1.55,
            }} />
          </div>

          {/* Attachment */}
          <div>
            <div style={fieldLabel}>Attachment</div>
            <div style={{
              marginTop: 6, display: 'flex', alignItems: 'center', gap: 12,
              background: P.graphite, borderLeft: `2px solid ${P.gold}`, padding: '13px 14px',
            }}>
              <Icon name="FileText" size={20} color={P.gold} strokeWidth={1.5} />
              <div style={{ flex: 1, minWidth: 0 }}>
                <div style={{ fontFamily: T.body, fontSize: 12.5, color: P.paper }}>
                  Voss-Expense-Report-{period.id}.pdf
                </div>
                <RptMono size={7.5} style={{ display: 'block', marginTop: 3 }}>
                  Expense Report + {roll.docs} original documents
                </RptMono>
              </div>
            </div>
          </div>
        </div>
        <div style={{ height: 16 }} />
      </div>

      <div style={{ padding: '10px 22px 14px', borderTop: `1px solid ${P.graphite}`, background: P.ink, flex: '0 0 auto' }}>
        <button onClick={onSend} style={{
          width: '100%', height: 52, background: P.gold, border: `1px solid ${P.gold}`,
          color: P.ink, cursor: 'pointer',
          display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 10,
          fontFamily: T.mono, fontSize: 11, fontWeight: 700, letterSpacing: '0.2em', textTransform: 'uppercase',
        }}>
          <Icon name="Send" size={15} color={P.ink} strokeWidth={1.8} />
          Send
        </button>
        <RptMono size={8} style={{ display: 'block', textAlign: 'center', marginTop: 8 }}>
          The sent report is archived with the collection's records
        </RptMono>
      </div>
    </React.Fragment>
  );
}

// ── Sent confirmation ────────────────────────────────────────────────
function ReportSentOverlay({ period, roll, onClose }) {
  const node = (
    <div style={{ position: 'absolute', inset: 0, zIndex: 98, display: 'flex', alignItems: 'center', justifyContent: 'center', padding: 24 }}>
      <div style={{ position: 'absolute', inset: 0, background: 'rgba(10,10,11,0.85)', backdropFilter: 'blur(2px)', WebkitBackdropFilter: 'blur(2px)' }} />
      <div style={{ position: 'relative', width: '100%', background: P.graphite, border: `1px solid ${P.gold}`, padding: 22, animation: 'sheetIn .25s cubic-bezier(.2,.7,.3,1)' }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
          <span style={{ width: 38, height: 38, borderRadius: 999, border: `1px solid ${P.gold}`, background: 'rgba(184,144,85,0.1)', display: 'inline-flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}>
            <Icon name="Send" size={17} color={P.gold} strokeWidth={1.8} />
          </span>
          <div>
            <Eyebrow color={P.gold}>SENT · MARKED AS SENT</Eyebrow>
            <div style={{ fontFamily: T.display, fontSize: 22, fontWeight: 700, color: P.paper, marginTop: 5, letterSpacing: '-0.015em', lineHeight: 1 }}>Report Delivered</div>
          </div>
        </div>
        <div style={{ fontFamily: T.body, fontSize: 12.5, color: P.bone, marginTop: 14, lineHeight: 1.55 }}>
          {period.label} — {roll.count} expenses, {rMoney(roll.total)} — is on its way to {ACCOUNTANT.name} with
          every original enclosed. Once reimbursement arrives, pay contributors and vendors.
        </div>
        <div style={{ marginTop: 14, display: 'flex', alignItems: 'center', gap: 10 }}>
          <span style={{ width: 5, height: 5, background: P.gold, flexShrink: 0 }} />
          <RptMono size={8} style={{ lineHeight: 1.6 }}>The task is cleared from Complete Tasks · next reminder near the end of June.</RptMono>
        </div>
        <button onClick={onClose} style={{ width: '100%', height: 48, marginTop: 18, background: P.gold, border: `1px solid ${P.gold}`, color: P.ink, fontFamily: T.mono, fontSize: 10, fontWeight: 700, letterSpacing: '0.2em', textTransform: 'uppercase', cursor: 'pointer' }}>Done</button>
      </div>
    </div>
  );
  const stage = (typeof document !== 'undefined') ? document.getElementById('proto-stage') : null;
  return stage ? ReactDOM.createPortal(node, stage) : node;
}

Object.assign(window, { ReportExpenseSheet, ReportPreview, ReportEmail, ReportSentOverlay, OriginalViewerSheet });
