// COLLECTION OPERATIONS — the operational hub for the whole collection.
// Launched from the "Add" control on the Garage landing page. Every action
// here begins a workflow that ultimately writes records into the archive
// (Timeline, Provenance, Service Ledger, Value History, Vault, Gallery…).
//
// Two views live inside one full-screen overlay:
//   • 'menu'    — the command center (four categories of actions)
//   • 'receipt' — first step of the Upload Receipt workflow
//
// Principle, stated and restated: Actions create records. Records create the archive.

const { useState: useOps } = React;

// ─────────────────────────────────────────────────────────────────────
// Shared overlay chrome
// ─────────────────────────────────────────────────────────────────────

function OpsTopBar({ eyebrow, title, onClose, closeIcon = 'down' }) {
  return (
    <div style={{
      padding: '10px 18px 12px',
      background: P.ink,
      display: 'flex', alignItems: 'center', gap: 12,
      borderBottom: `1px solid ${P.graphite}`,
      flex: '0 0 auto',
    }}>
      <button onClick={onClose} aria-label="Close" style={{
        background: P.gold, border: 'none', borderRadius: 999,
        width: 34, height: 34, flexShrink: 0, color: P.ink, cursor: 'pointer',
        display: 'flex', alignItems: 'center', justifyContent: 'center',
      }}>
        <svg width="18" height="18" viewBox="0 0 24 24" fill="none"
          stroke="currentColor" strokeWidth="1.9" strokeLinecap="round" strokeLinejoin="round">
          {closeIcon === 'down'
            ? <path d="M6 9l6 6 6-6" />
            : <path d="M19 12H5M5 12l6-6M5 12l6 6" />}
        </svg>
      </button>
      <div style={{ flex: 1, minWidth: 0 }}>
        <div style={{
          fontFamily: T.display, fontWeight: 600, fontSize: 15,
          letterSpacing: '0.02em', color: P.paper, lineHeight: 1.1,
        }}>{title}</div>
        <div style={{
          fontFamily: T.mono, fontSize: 8.5, letterSpacing: '0.16em',
          color: P.gold, marginTop: 3,
        }}>{eyebrow}</div>
      </div>
      <CAMonogram size={20} color={P.paper} stroke={1.6} />
    </div>
  );
}

// The principle banner — quiet, tracked, gold-keyed.
function PrincipleBanner({ style = {} }) {
  return (
    <div style={{
      display: 'flex', alignItems: 'center', gap: 10, ...style,
    }}>
      <span style={{ width: 5, height: 5, background: P.gold, flexShrink: 0 }} />
      <div style={{
        fontFamily: T.mono, fontSize: 9, letterSpacing: '0.18em',
        textTransform: 'uppercase', color: P.mute, lineHeight: 1.6,
      }}>
        Actions create records.<br />Records create the <span style={{ color: P.gold }}>archive</span>.
      </div>
    </div>
  );
}

// A single navigation item — title only, matches the interior row rhythm.
function OpRow({ icon, title, onClick, badge, soon }) {
  return (
    <InkCard onClick={onClick} padding={12} style={{
      display: 'grid', gridTemplateColumns: '24px 1fr auto auto', gap: 10, alignItems: 'center',
    }}>
      <Icon name={icon} size={18} color={P.gold} strokeWidth={1.5} />
      <div style={{ fontFamily: T.display, fontSize: 14, fontWeight: 600, color: P.paper, minWidth: 0 }}>{title}</div>
      {soon ? (
        <span style={{
          fontFamily: T.mono, fontSize: 7.5, fontWeight: 600, letterSpacing: '0.16em',
          textTransform: 'uppercase', color: P.mute, border: `1px solid ${P.slate}`, padding: '3px 6px',
        }}>Planned</span>
      ) : badge != null && badge > 0 ? (
        <span style={{
          minWidth: 20, height: 20, padding: '0 6px', borderRadius: 999, background: P.gold, color: P.ink,
          display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
          fontFamily: T.mono, fontSize: 9, fontWeight: 700, letterSpacing: '0.02em',
        }}>{badge}</span>
      ) : <span />}
      <Icon name="arrow" size={16} color={P.gold} strokeWidth={1.4} />
    </InkCard>
  );
}

// ─────────────────────────────────────────────────────────────────────
// MENU — the command center
// ─────────────────────────────────────────────────────────────────────

const OPS_CATEGORIES = [
  {
    label: 'Vehicles',
    items: [
      { id: 'add-vehicle', icon: 'car', title: 'Add Vehicle',
        desc: 'New archive · full history' },
      { id: 'transfer', icon: 'ArrowLeftRight', title: 'Transfer Ownership', soon: true,
        desc: 'Provenance · new owner' },
      { id: 'record-sale', icon: 'hammer', title: 'Record Sale', soon: true,
        desc: 'Method · buyer · price' },
    ],
  },
  {
    label: 'Activities',
    items: [
      { id: 'event', icon: 'Trophy', title: 'Record Event', soon: true,
        desc: 'Concours · rallies · track · results' },
      { id: 'story', icon: 'BookOpen', title: 'Add Story',
        desc: 'Memories · moments · media' },
    ],
  },
  {
    label: 'Financials',
    items: [
      { id: 'upload-receipt', icon: 'Receipt', title: 'Upload Expense',
        desc: 'AI extraction · allocation' },
      { id: 'report', icon: 'FileSpreadsheet', title: 'Send Expense Report',
        desc: 'Monthly expense · reimbursements' },
    ],
  },
  {
    label: 'Documents',
    items: [
      { id: 'upload-doc', icon: 'FileText', title: 'Upload Document', soon: true,
        desc: 'Titles · certificates · appraisals' },
    ],
  },
];

function OperationsMenu({ onClose, onAction }) {
  const M = (typeof COLLECTION_MANAGER !== 'undefined') ? COLLECTION_MANAGER : { initials: 'CM' };
  const pendingCount = (typeof CONTRIBUTORS_PENDING !== 'undefined') ? CONTRIBUTORS_PENDING.length : 0;
  return (
    <React.Fragment>
      {/* Home-page sticky header — monogram + wordmark, with a down arrow to close */}
      <div style={{
        padding: '14px 22px 8px',
        display: 'flex', justifyContent: 'space-between', alignItems: 'center',
        flex: '0 0 auto', background: P.ink,
      }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
          <CAMonogram size={20} color={P.paper} stroke={1.6} />
          <div style={{
            fontFamily: T.display, fontSize: 14, fontWeight: 700,
            letterSpacing: '0.06em', color: P.paper,
          }}>COLLECTOR / ARCHIVES</div>
        </div>
        {/* Close */}
        <button onClick={onClose} aria-label="Close operations menu" style={{
          width: 38, height: 38, flexShrink: 0, borderRadius: 999, cursor: 'pointer',
          background: 'transparent', border: `1px solid ${P.gold}`, color: P.gold,
          display: 'flex', alignItems: 'center', justifyContent: 'center',
        }}>
          <svg className="ops-x" width="18" height="18" viewBox="0 0 24 24" fill="none"
            stroke="currentColor" strokeWidth="1.9" strokeLinecap="round">
            <line x1="6" y1="6" x2="18" y2="18" />
            <line x1="18" y1="6" x2="6" y2="18" />
          </svg>
        </button>
      </div>

      <div className="proto-scroll" style={{ flex: 1, overflow: 'auto', background: P.ink }}
        data-screen-label="ops-menu">
        {/* Platform navigation — gateway into review + account */}
        <div style={{ padding: '20px 22px 4px', display: 'grid', gap: 5 }}>
          <OpRow icon="Inbox" title="View Inbox"
            onClick={() => onAction('review-queue')} />
          <OpRow icon="UserCog" title="Manage Account"
            onClick={() => onAction('account')} />
        </div>
        {/* Categories */}
        {OPS_CATEGORIES.map((cat, ci) => (
          <div key={cat.label}>
            <div style={{ padding: ci === 0 ? '20px 0 4px' : '20px 0 4px' }}>
              <RowRule>{cat.label}</RowRule>
            </div>
            <div style={{ padding: '12px 22px 10px', display: 'grid', gap: 5 }}>
              {cat.items.map(it => (
                <OpRow key={it.id} icon={it.icon} title={it.title} soon={it.soon}
                  onClick={() => onAction(it.id)} />
              ))}
            </div>
          </div>
        ))}

        <div style={{ height: 28 }} />
      </div>
    </React.Fragment>
  );
}

// ─────────────────────────────────────────────────────────────────────
// UPLOAD RECEIPT — first step of the workflow
// ─────────────────────────────────────────────────────────────────────

function Toggle({ on, onChange }) {
  return (
    <button onClick={() => onChange(!on)} aria-pressed={on} style={{
      width: 44, height: 26, flexShrink: 0, borderRadius: 999, cursor: 'pointer',
      border: `1px solid ${on ? P.gold : P.slate}`,
      background: on ? P.gold : 'transparent',
      position: 'relative', transition: 'background .15s, border-color .15s', padding: 0,
    }}>
      <span style={{
        position: 'absolute', top: 2, left: on ? 20 : 2,
        width: 20, height: 20, borderRadius: 999,
        background: on ? P.ink : P.mute, transition: 'left .15s, background .15s',
      }} />
    </button>
  );
}

// The fields Collector Archives extracts automatically.
const EXTRACT_FIELDS = [
  { k: 'Vendor', v: 'Auto-detected', icon: 'Building2' },
  { k: 'Date', v: 'Auto-detected', icon: 'Calendar' },
  { k: 'Currency', v: 'Auto-detected', icon: 'Coins' },
  { k: 'Amount', v: 'Auto-detected', icon: 'CircleDollarSign' },
  { k: 'Category', v: 'Classified', icon: 'Tags' },
  { k: 'Tax / VAT', v: 'Parsed', icon: 'Percent' },
];

function UploadReceipt({ vehicles = [], onBack, onClose }) {
  const [method, setMethod] = useOps('drop');         // photo | camera | pdf | drop
  const [assignMode, setAssignMode] = useOps('single'); // single | split
  const activeVehicles = vehicles.filter(v => v.status !== 'Sold' && v.status !== 'Archived');
  const [singleId, setSingleId] = useOps(activeVehicles[0] ? activeVehicles[0].id : null);
  const [splitIds, setSplitIds] = useOps(activeVehicles.slice(0, 2).map(v => v.id));
  const [preserve, setPreserve] = useOps(true);

  const toggleSplit = (id) => setSplitIds(prev =>
    prev.includes(id) ? prev.filter(x => x !== id) : [...prev, id]);
  const splitPct = splitIds.length ? Math.round(100 / splitIds.length) : 0;

  const methods = [
    { id: 'photo', icon: 'gallery', label: 'Photo' },
    { id: 'camera', icon: 'camera', label: 'Camera' },
    { id: 'pdf', icon: 'FileText', label: 'PDF' },
  ];

  return (
    <React.Fragment>
      <OpsTopBar eyebrow="Financials · Step 1 of 3" title="Upload Receipt"
        onClose={onBack} closeIcon="back" />

      <div className="proto-scroll" style={{ flex: 1, overflow: 'auto', background: P.ink }}
        data-screen-label="ops-upload-receipt">
        {/* Intro */}
        <div style={{ padding: '18px 22px 14px' }}>
          <div style={{
            fontFamily: T.display, fontWeight: 700, fontSize: 32,
            lineHeight: 0.92, letterSpacing: '-0.02em', color: P.paper,
          }}>CAPTURE THE<br />SOURCE</div>
          <div style={{
            fontFamily: T.body, fontSize: 12.5, color: P.mute,
            marginTop: 10, lineHeight: 1.5, maxWidth: 300,
          }}>
            Upload a receipt or invoice. Collector Archives extracts, categorizes,
            and tracks the cost — and keeps the original on file, forever.
          </div>
        </div>

        {/* Drag & drop zone */}
        <div style={{ padding: '0 22px 14px' }}>
          <div className="op-drop">
            <span className="op-drop__ring">
              <Icon name="Upload" size={24} color={P.gold} strokeWidth={1.5} />
            </span>
            <div style={{
              fontFamily: T.display, fontSize: 18, fontWeight: 600,
              color: P.paper, letterSpacing: '0.01em', marginTop: 12,
            }}>Drag &amp; drop invoice</div>
            <div style={{
              fontFamily: T.body, fontSize: 12, color: P.mute, marginTop: 5,
            }}>or choose a source below</div>
            <div style={{
              fontFamily: T.mono, fontSize: 8.5, color: P.slate, marginTop: 14,
              letterSpacing: '0.18em', textTransform: 'uppercase',
            }}>JPG · PNG · HEIC · PDF · up to 25MB</div>
          </div>
        </div>

        {/* Capture methods */}
        <div style={{ padding: '0 22px 18px' }}>
          <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr', gap: 8 }}>
            {methods.map(m => {
              const on = method === m.id;
              return (
                <button key={m.id} onClick={() => setMethod(m.id)} style={{
                  display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 8,
                  padding: '16px 8px', cursor: 'pointer',
                  background: on ? P.graphite : 'transparent',
                  border: `1px solid ${on ? P.gold : P.slate}`,
                  transition: 'border-color .15s, background .15s',
                }}>
                  <Icon name={m.icon} size={22} color={on ? P.gold : P.paper} strokeWidth={1.5} />
                  <span style={{
                    fontFamily: T.mono, fontSize: 9, fontWeight: 600,
                    letterSpacing: '0.18em', textTransform: 'uppercase',
                    color: on ? P.gold : P.paper,
                  }}>{m.label}</span>
                </button>
              );
            })}
          </div>
        </div>

        {/* AI extraction explainer */}
        <div style={{ padding: '0 22px 10px' }}>
          <RowRule>AUTOMATIC EXTRACTION</RowRule>
        </div>
        <div style={{ padding: '0 22px 18px' }}>
          <div style={{
            background: P.graphite, borderLeft: `2px solid ${P.gold}`, padding: 18,
          }}>
            <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
              <Icon name="spark" size={18} color={P.gold} strokeWidth={1.6} />
              <div style={{
                fontFamily: T.mono, fontSize: 10, fontWeight: 600,
                letterSpacing: '0.2em', textTransform: 'uppercase', color: P.paper,
              }}>The archive reads it for you</div>
            </div>
            <div style={{
              fontFamily: T.body, fontSize: 12, color: P.bone, marginTop: 10, lineHeight: 1.55,
            }}>
              On upload, Collector Archives detects the vendor and currency, parses
              line items and totals, and files the expense to the right category and vehicle.
            </div>
            <div style={{
              marginTop: 16, display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 1,
              background: P.slate, border: `1px solid ${P.slate}`,
            }}>
              {EXTRACT_FIELDS.map(f => (
                <div key={f.k} style={{
                  background: P.ink, padding: '12px 12px', display: 'flex',
                  alignItems: 'center', gap: 10,
                }}>
                  <Icon name={f.icon} size={15} color={P.gold} strokeWidth={1.5} />
                  <div style={{ minWidth: 0 }}>
                    <div style={{
                      fontFamily: T.mono, fontSize: 8.5, letterSpacing: '0.16em',
                      textTransform: 'uppercase', color: P.mute,
                    }}>{f.k}</div>
                    <div style={{
                      fontFamily: T.body, fontSize: 11.5, color: P.paper, marginTop: 2,
                    }}>{f.v}</div>
                  </div>
                </div>
              ))}
            </div>
            <div style={{
              marginTop: 12, display: 'flex', alignItems: 'center', gap: 8,
            }}>
              <span style={{
                width: 6, height: 6, borderRadius: 4, background: P.gold,
                animation: 'pulseDot 1.8s ease-in-out infinite',
              }} />
              <div style={{
                fontFamily: T.mono, fontSize: 9, letterSpacing: '0.14em',
                textTransform: 'uppercase', color: P.mute,
              }}>Fields populate the moment a file is added</div>
            </div>
          </div>
        </div>

        {/* Vehicle assignment */}
        <div style={{ padding: '0 22px 10px' }}>
          <RowRule>ASSIGN COST TO</RowRule>
        </div>
        <div style={{ padding: '0 22px 18px' }}>
          {/* Mode toggle */}
          <div style={{ display: 'inline-flex', border: `1px solid ${P.slate}`, marginBottom: 12 }}>
            {[{ id: 'single', label: 'One Vehicle' }, { id: 'split', label: 'Split Across' }].map((m, i) => {
              const on = assignMode === m.id;
              return (
                <button key={m.id} onClick={() => setAssignMode(m.id)} style={{
                  padding: '9px 16px',
                  background: on ? P.paper : 'transparent',
                  color: on ? P.ink : P.paper,
                  border: 'none', borderLeft: i > 0 ? `1px solid ${P.slate}` : 'none',
                  fontFamily: T.mono, fontSize: 9, fontWeight: 600,
                  letterSpacing: '0.16em', textTransform: 'uppercase', cursor: 'pointer',
                }}>{m.label}</button>
              );
            })}
          </div>

          {assignMode === 'single' ? (
            <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
              {activeVehicles.map(v => {
                const on = singleId === v.id;
                return (
                  <button key={v.id} onClick={() => setSingleId(v.id)} style={{
                    width: '100%', display: 'flex', alignItems: 'center', gap: 12,
                    padding: '12px 14px', cursor: 'pointer', textAlign: 'left',
                    background: on ? P.graphite : 'transparent',
                    border: `1px solid ${on ? P.gold : P.slate}`,
                    transition: 'border-color .15s, background .15s',
                  }}>
                    <span style={{
                      width: 16, height: 16, borderRadius: 999, flexShrink: 0,
                      border: `1px solid ${on ? P.gold : P.slate}`,
                      display: 'flex', alignItems: 'center', justifyContent: 'center',
                    }}>
                      {on && <span style={{ width: 8, height: 8, borderRadius: 999, background: P.gold }} />}
                    </span>
                    <span style={{ flex: 1, minWidth: 0 }}>
                      <span style={{
                        display: 'block', fontFamily: T.display, fontSize: 15, fontWeight: 600,
                        color: P.paper, letterSpacing: '0.005em', lineHeight: 1.1,
                      }}>{v.year} {v.make} {v.model}</span>
                      <span style={{
                        display: 'block', fontFamily: T.mono, fontSize: 8.5, color: P.mute,
                        letterSpacing: '0.16em', textTransform: 'uppercase', marginTop: 3,
                      }}>"{v.nickname}"</span>
                    </span>
                  </button>
                );
              })}
            </div>
          ) : (
            <div>
              <div style={{
                fontFamily: T.body, fontSize: 11.5, color: P.mute, marginBottom: 10, lineHeight: 1.5,
              }}>
                Select the vehicles this invoice covers. The amount is divided
                evenly and reconciled after extraction.
              </div>
              <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
                {activeVehicles.map(v => {
                  const on = splitIds.includes(v.id);
                  return (
                    <button key={v.id} onClick={() => toggleSplit(v.id)} style={{
                      width: '100%', display: 'flex', alignItems: 'center', gap: 12,
                      padding: '12px 14px', cursor: 'pointer', textAlign: 'left',
                      background: on ? P.graphite : 'transparent',
                      border: `1px solid ${on ? P.gold : P.slate}`,
                      transition: 'border-color .15s, background .15s',
                    }}>
                      <span style={{
                        width: 16, height: 16, flexShrink: 0,
                        border: `1px solid ${on ? P.gold : P.slate}`,
                        background: on ? P.gold : 'transparent',
                        display: 'flex', alignItems: 'center', justifyContent: 'center',
                      }}>
                        {on && (
                          <svg width="11" height="11" viewBox="0 0 24 24" fill="none"
                            stroke={P.ink} strokeWidth="3" strokeLinecap="round" strokeLinejoin="round">
                            <path d="M5 12l5 5L20 6" />
                          </svg>
                        )}
                      </span>
                      <span style={{ flex: 1, minWidth: 0 }}>
                        <span style={{
                          display: 'block', fontFamily: T.display, fontSize: 15, fontWeight: 600,
                          color: P.paper, letterSpacing: '0.005em', lineHeight: 1.1,
                        }}>{v.year} {v.make} {v.model}</span>
                        <span style={{
                          display: 'block', fontFamily: T.mono, fontSize: 8.5, color: P.mute,
                          letterSpacing: '0.16em', textTransform: 'uppercase', marginTop: 3,
                        }}>"{v.nickname}"</span>
                      </span>
                      {on && (
                        <span style={{
                          fontFamily: T.display, fontSize: 17, fontWeight: 700,
                          color: P.gold, letterSpacing: '-0.01em', flexShrink: 0,
                        }}>{splitPct}%</span>
                      )}
                    </button>
                  );
                })}
              </div>
              <div style={{
                marginTop: 12, display: 'flex', justifyContent: 'space-between', alignItems: 'center',
                paddingTop: 12, borderTop: `1px solid ${P.graphite}`,
              }}>
                <span style={{
                  fontFamily: T.mono, fontSize: 9, letterSpacing: '0.18em',
                  textTransform: 'uppercase', color: P.mute,
                }}>{splitIds.length} vehicle{splitIds.length === 1 ? '' : 's'} · allocation</span>
                <span style={{
                  fontFamily: T.display, fontSize: 17, fontWeight: 700, color: P.paper,
                }}>{splitIds.length ? splitPct * splitIds.length : 0}%</span>
              </div>
            </div>
          )}
        </div>

        {/* Preserve original */}
        <div style={{ padding: '0 22px 22px' }}>
          <div style={{
            display: 'flex', alignItems: 'center', gap: 14,
            background: P.graphite, padding: '16px 16px',
          }}>
            <Icon name="archive" size={20} color={P.gold} strokeWidth={1.6} />
            <div style={{ flex: 1, minWidth: 0 }}>
              <div style={{
                fontFamily: T.display, fontSize: 15, fontWeight: 600, color: P.paper,
                letterSpacing: '0.005em',
              }}>Preserve original</div>
              <div style={{
                fontFamily: T.body, fontSize: 11.5, color: P.mute, marginTop: 3, lineHeight: 1.45,
              }}>Keep the source document in the Vault as part of the permanent record.</div>
            </div>
            <Toggle on={preserve} onChange={setPreserve} />
          </div>
        </div>

        {/* Primary CTA */}
        <div style={{ padding: '0 22px 14px' }}>
          <button onClick={onClose} 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.22em', textTransform: 'uppercase',
          }}>
            <Icon name="spark" size={16} color={P.ink} strokeWidth={2} />
            Extract &amp; File
          </button>
        </div>

        <div style={{ padding: '4px 22px 28px' }}>
          <PrincipleBanner />
        </div>
      </div>
    </React.Fragment>
  );
}

// ─────────────────────────────────────────────────────────────────────
// FLOW SHELL — full-screen overlay portalled to the phone stage
// ─────────────────────────────────────────────────────────────────────

function OperationsFlow({ vehicles = [], onClose, onAddVehicle, initialView = 'menu' }) {
  const [view, setView] = useOps(initialView); // menu | account | emergency | transfer | owner | billing | receipt | story | review-queue | review-item | contributors
  const [reviewItem, setReviewItem] = useOps(null); // submission opened from the queue
  const [reportPeriod, setReportPeriod] = useOps(null); // period opened from Reports home
  const [reviewOrigin, setReviewOrigin] = useOps('review-queue'); // which queue we opened from
  const [removedIds, setRemovedIds] = useOps([]); // submissions filed to the archive — drop from the queue
  const [closing, setClosing] = useOps(false);

  // A submission, once reviewed and filed to the archive, leaves the queue.
  const completeReview = () => {
    setRemovedIds(ids => (reviewItem && !ids.includes(reviewItem.id)) ? [...ids, reviewItem.id] : ids);
    setView(reviewOrigin);
  };

  // Fade out, then unmount.
  const requestClose = () => {
    if (closing) return;
    setClosing(true);
    setTimeout(() => { onClose && onClose(); }, 240);
  };

  const openReviewItem = (item) => {
    setReviewItem(item);
    // A receipt opens the full Upload Receipt review/allocate workflow,
    // unchanged after the review step. The monthly report task opens the
    // Monthly Expense Report flow. Other kinds get a light review.
    if (item.kind === 'report') { setView('report-task'); return; }
    setView(item.kind === 'receipt' ? 'review-receipt' : 'review-item');
  };

  const handleAction = (id) => {
    if (id === 'view-collection') { requestClose(); return; }
    if (id === 'add-vehicle') { onAddVehicle && onAddVehicle(); requestClose(); return; }
    if (id === 'upload-receipt') { setView('receipt'); return; }
    if (id === 'report') { setView('reports'); return; }
    if (id === 'story') { setView('story'); return; }
    if (id === 'review-queue') { setReviewOrigin('review-queue'); setView('review-queue'); return; }
    if (id === 'review-expenses') { setReviewOrigin('review-expenses'); setView('review-expenses'); return; }
    if (id === 'contributors') { setView('contributors'); return; }
    if (id === 'account') { setView('account'); return; }
    // Other workflows are stubbed in this prototype — they would each open
    // their own first-step screen, mirroring Upload Receipt.
  };

  const node = (
    <div style={{
      position: 'absolute', inset: 0, zIndex: 95, background: P.ink,
      animation: `${closing ? 'opsFadeOut' : 'opsFadeIn'} .24s ease forwards`,
    }}>
      <div style={{
        position: 'absolute', inset: 0, display: 'flex', flexDirection: 'column',
        background: P.ink,
      }}>
        {/* status-bar spacer to match the app shell */}
        <div style={{ height: 54, flex: '0 0 auto', background: P.ink }} />
        {view === 'menu' && (
          <OperationsMenu onClose={requestClose} onAction={handleAction} />
        )}
        {view === 'receipt' && (
          <ReceiptFlow vehicles={vehicles} onBack={() => setView('menu')} onClose={requestClose} />
        )}
        {view === 'reports' && (
          <ReportsHome onBack={() => setView('menu')}
            onOpenMonthly={(pid) => { setReportPeriod(pid); setView('report-monthly'); }} />
        )}
        {view === 'report-monthly' && (
          <MonthlyReportFlow initialPeriodId={reportPeriod}
            onBack={() => setView('reports')}
            onAddExpense={() => setView('receipt')}
            onSent={() => { setRemovedIds(ids => ids.includes('rq-task-report') ? ids : [...ids, 'rq-task-report']); setView('reports'); }} />
        )}
        {view === 'report-task' && (
          <MonthlyReportFlow fromTask
            onBack={() => setView('review-queue')}
            onAddExpense={() => setView('receipt')}
            onSent={() => { setRemovedIds(ids => ids.includes('rq-task-report') ? ids : [...ids, 'rq-task-report']); setView('review-queue'); }} />
        )}
        {view === 'story' && (
          <StoryFlow vehicles={vehicles} onBack={() => setView('menu')} onClose={requestClose} />
        )}
        {view === 'review-queue' && (
          <ReviewQueue removedIds={removedIds} onBack={() => setView('menu')} onOpenItem={openReviewItem} />
        )}
        {view === 'review-expenses' && (
          <ReviewQueue mode="expenses" removedIds={removedIds} onBack={() => setView('menu')} onOpenItem={openReviewItem} />
        )}
        {view === 'review-receipt' && (
          <ReceiptFlow vehicles={vehicles} initialPhase="review" initialPicked="RT-2026-0488.pdf" fromReview
            reviewLabel={reviewOrigin === 'review-expenses' ? 'Review Contributor Expenses' : 'Review Submission'}
            onBack={() => setView(reviewOrigin)} onClose={completeReview} />
        )}
        {view === 'review-item' && reviewItem && (
          <ReviewItem item={reviewItem} onBack={() => setView(reviewOrigin)} onClose={completeReview} />
        )}
        {view === 'account' && (
          <AdminHome
            onBack={() => setView('menu')}
            onOpenTeam={() => setView('contributors')}
            onOpenEmergency={() => setView('emergency')}
            onOpenTransfer={() => setView('transfer')}
            onOpenOwner={() => setView('owner')}
            onOpenBilling={() => setView('billing')}
            onSignOut={requestClose} />
        )}
        {view === 'emergency' && (
          <EmergencyAccessScreen onBack={() => setView('account')} />
        )}
        {view === 'transfer' && (
          <TransferAccountScreen onBack={() => setView('account')} />
        )}
        {view === 'owner' && (
          <CollectionOwnerScreen onBack={() => setView('account')} />
        )}
        {view === 'billing' && (
          <BillingScreen onBack={() => setView('account')} />
        )}
        {view === 'contributors' && (
          <Contributors onBack={() => setView('account')} />
        )}
        {/* home-indicator spacer */}
        <div style={{ height: 28, flex: '0 0 auto', background: P.ink }} />
      </div>

      <style>{`
        @keyframes opsFadeIn { from { opacity: 0; } to { opacity: 1; } }
        @keyframes opsFadeOut { from { opacity: 1; } to { opacity: 0; } }
        @keyframes opsXDraw { from { stroke-dashoffset: 18; } to { stroke-dashoffset: 0; } }
        .ops-x line { stroke-dasharray: 18; stroke-dashoffset: 18; animation: opsXDraw .32s cubic-bezier(.5,0,.2,1) forwards; }
        .ops-x line:nth-child(2) { animation-delay: .12s; }
        .op-drop {
          display: flex; flex-direction: column; align-items: center; justify-content: center;
          padding: 30px 20px 26px; text-align: center;
          background: repeating-linear-gradient(135deg, ${P.graphite} 0 16px, rgba(255,255,255,0.015) 16px 17px);
          border: 1px dashed ${P.slate};
        }
        .op-drop__ring {
          width: 60px; height: 60px; border-radius: 999px;
          border: 1px solid ${P.gold};
          display: flex; align-items: center; justify-content: center;
          background: rgba(184,144,85,0.08);
        }
      `}</style>
    </div>
  );

  const stage = (typeof document !== 'undefined') ? document.getElementById('proto-stage') : null;
  return stage ? ReactDOM.createPortal(node, stage) : node;
}

Object.assign(window, { OperationsFlow, OperationsMenu, UploadReceipt });
