// Budget tracker screen.
const { useState: useStateB, useMemo: useMemoB } = React;

function budgetStatus(spent, alloc) {
  const pct = spent / alloc;
  if (pct > 1) return { label: 'Over budget', kind: 'danger' };
  if (pct > 0.85) return { label: 'At risk', kind: 'warning' };
  return { label: 'On track', kind: 'success' };
}

const SortHeader = window.SortHeader;

function BudgetScreen({ user, teams, transactions, openTeamId }) {
  const store = window.AppStore.useStore();
  const [sortKey, setSortKey] = useStateB('remaining');
  const [dir, setDir] = useStateB('asc');
  const [expanded, setExpanded] = useStateB(openTeamId || null);
  const [showForm, setShowForm] = useStateB(false);

  // Re-derive grouped SAFs each render from store
  const tx = React.useMemo(() => {
    const out = {};
    store.getSAFs().forEach(s => {
      const tid = s.teamId;
      if (!out[tid]) out[tid] = [];
      out[tid].push(s);
    });
    return out;
  }, [store, teams]);

  const canEdit = user.role === 'super_admin' || user.role === 'staff_admin' || user.role === 'cs_president';

  const rows = useMemoB(() => {
    const list = teams.map(t => ({
      ...t,
      remaining: t.budget.allocated - t.budget.spent,
      pct: t.budget.spent / t.budget.allocated,
    }));
    list.sort((a, b) => {
      let av = a[sortKey], bv = b[sortKey];
      if (sortKey === 'name') { av = a.name; bv = b.name; }
      if (sortKey === 'sport') { av = a.sport; bv = b.sport; }
      if (sortKey === 'allocated') { av = a.budget.allocated; bv = b.budget.allocated; }
      if (sortKey === 'spent') { av = a.budget.spent; bv = b.budget.spent; }
      if (sortKey === 'remaining') { av = a.remaining; bv = b.remaining; }
      if (av < bv) return dir === 'asc' ? -1 : 1;
      if (av > bv) return dir === 'asc' ? 1 : -1;
      return 0;
    });
    return list;
  }, [teams, sortKey, dir]);

  function onSort(k) {
    if (sortKey === k) setDir(d => d === 'asc' ? 'desc' : 'asc');
    else { setSortKey(k); setDir('asc'); }
  }

  const totals = useMemoB(() => {
    const allocated = teams.reduce((s, t) => s + t.budget.allocated, 0);
    const spent = teams.reduce((s, t) => s + t.budget.spent, 0);
    return { allocated, spent, remaining: allocated - spent };
  }, [teams]);

  return (
    <div data-screen-label="04 Budget tracker">
      <div className="page-head">
        <div>
          <h1 className="page-title">Budget tracker</h1>
          <div className="page-subtitle">SAF purchasing applications and team allocations · FY 2025–26</div>
        </div>
        <div className="flex-gap-8">
          <button className="btn btn-secondary"><window.I.Download size={14} /> Export CSV</button>
          {canEdit && (
            <button className="btn btn-primary" onClick={() => setShowForm(s => !s)}>
              <window.I.Plus size={14} /> New SAF application
            </button>
          )}
        </div>
      </div>

      <div className="metric-grid" style={{ gridTemplateColumns: 'repeat(4, 1fr)' }}>
        <div className="card metric">
          <div className="metric-label">Total allocated</div>
          <div className="metric-value cell-mono">${totals.allocated.toLocaleString()}</div>
          <div className="metric-trend">across {teams.length} teams</div>
        </div>
        <div className="card metric">
          <div className="metric-label">Spent to date</div>
          <div className="metric-value cell-mono">${totals.spent.toLocaleString()}</div>
          <div className="metric-trend">{Math.round(totals.spent / totals.allocated * 100)}% of allocated</div>
        </div>
        <div className="card metric success">
          <div className="metric-label">Remaining</div>
          <div className="metric-value cell-mono">${totals.remaining.toLocaleString()}</div>
          <div className="metric-trend">available through June 30</div>
        </div>
        {(() => {
          const ly = teams.reduce((s, t) => s + (t.lastYearBudget?.spent || 0), 0);
          const delta = totals.spent - ly;
          const pct = ly === 0 ? 0 : Math.round((delta / ly) * 100);
          const trendingUp = delta > 0;
          return (
            <div className={`card metric ${trendingUp ? 'warning' : 'success'}`}>
              <div className="metric-label">
                <span className="pill-icon">
                  {trendingUp ? <window.I.AlertTriangle size={14} /> : <window.I.CheckCircle size={14} />}
                </span>
                vs last year
              </div>
              <div className="metric-value cell-mono">{trendingUp ? '+' : ''}{pct}%</div>
              <div className="metric-trend">
                {trendingUp ? 'spending ahead of' : 'spending behind'} FY 2024\u201325 (${ly.toLocaleString()})
              </div>
            </div>
          );
        })()}
      </div>

      {showForm && <SAFForm onCancel={() => setShowForm(false)} onAdd={(rec) => {
        window.AppStore.addSAF({ ...rec, enteredBy: user.name });
        setShowForm(false);
      }} />}

      <div className="card">
        <div className="table-wrap">
          <table className="data">
            <thead>
              <tr>
                <th style={{ width: 28 }}></th>
                <SortHeader id="name" sortKey={sortKey} dir={dir} onSort={onSort}>Team</SortHeader>
                <SortHeader id="sport" sortKey={sortKey} dir={dir} onSort={onSort}>Sport</SortHeader>
                <SortHeader id="allocated" sortKey={sortKey} dir={dir} onSort={onSort}>Allocated</SortHeader>
                <SortHeader id="spent" sortKey={sortKey} dir={dir} onSort={onSort}>Spent</SortHeader>
                <SortHeader id="remaining" sortKey={sortKey} dir={dir} onSort={onSort}>Remaining</SortHeader>
                <th>vs last year</th>
                <th>Last SAF</th>
                <th>Status</th>
              </tr>
            </thead>
            <tbody>
              {rows.map(t => {
                const st = budgetStatus(t.budget.spent, t.budget.allocated);
                const list = tx[t.id] || [];
                const last = list[0];
                const isOpen = expanded === t.id;
                return (
                  <React.Fragment key={t.id}>
                    <tr className="clickable" onClick={() => setExpanded(isOpen ? null : t.id)}>
                      <td style={{ color: 'var(--text-3)' }}>
                        <window.I.ChevronRight size={14} style={{ transform: isOpen ? 'rotate(90deg)' : 'none', transition: 'transform 0.15s' }} />
                      </td>
                      <td><strong>{t.name}</strong></td>
                      <td><span className="tag-sport">{t.sport}</span></td>
                      <td className="cell-mono">${t.budget.allocated.toLocaleString()}</td>
                      <td className="cell-mono">${t.budget.spent.toLocaleString()}</td>
                      <td className="cell-mono">
                        <span style={{ color: t.remaining < 200 ? '#f0a0a0' : 'var(--text)' }}>${t.remaining.toLocaleString()}</span>
                        <span className="dim" style={{ fontSize: 11, marginLeft: 6 }}>{Math.round(t.pct * 100)}% used</span>
                      </td>
                      <td className="cell-mono">
                        {(() => {
                          const ly = t.lastYearBudget?.spent || 0;
                          if (ly === 0) return <span className="dim" style={{ fontSize: 11 }}>new club</span>;
                          const delta = t.budget.spent - ly;
                          const pct = Math.round((delta / ly) * 100);
                          const positive = delta > 0;
                          return (
                            <span style={{ fontSize: 12 }}>
                              <span style={{ color: positive ? 'var(--warning)' : 'var(--success)', fontWeight: 600 }}>
                                {positive ? '\u25b2' : '\u25bc'} {Math.abs(pct)}%
                              </span>
                              <span className="dim" style={{ fontSize: 10, marginLeft: 5 }}>${ly.toLocaleString()}</span>
                            </span>
                          );
                        })()}
                      </td>
                      <td className="cell-muted">{last ? last.date : <span className="dim">—</span>}</td>
                      <td><span className={`badge ${st.kind} dot`}>{st.label}</span></td>
                    </tr>
                    {isOpen && (
                      <tr>
                        <td colSpan={9} style={{ padding: 0, background: 'var(--bg)' }}>
                          <LedgerView team={t} transactions={list} canEdit={canEdit} user={user} />
                        </td>
                      </tr>
                    )}
                  </React.Fragment>
                );
              })}
            </tbody>
          </table>
        </div>
      </div>
    </div>
  );
}

function LedgerView({ team, transactions, canEdit, hideHeader, user }) {
  const store = window.AppStore.useStore();
  const list = store.getSAFs(team.id);
  const total = list.reduce((s, t) => s + t.amount, 0);
  const [expanded, setExpanded] = useStateB(null);
  const [showForm, setShowForm] = useStateB(false);

  function advance(safId, next) {
    window.AppStore.advanceSAF(safId, next, user?.name || 'Staff');
  }

  function safStatus(s) {
    if (s === 'posted') return { label: 'Posted · funds moved', kind: 'success' };
    if (s === 'val-confirmed') return { label: 'Val confirmed · posting', kind: 'gold' };
    if (s === 'stoney-signed') return { label: 'Stoney signed · w/ Val', kind: 'gold' };
    if (s === 'submitted') return { label: 'Submitted · awaiting Stoney', kind: 'warning' };
    if (s === 'returned') return { label: 'Returned to team', kind: 'danger' };
    // backwards-compat
    if (s === 'paid') return { label: 'Posted · funds moved', kind: 'success' };
    if (s === 'approved') return { label: 'Approved · in progress', kind: 'gold' };
    if (s === 'pending') return { label: 'Submitted · awaiting Stoney', kind: 'warning' };
    return { label: s || '—', kind: 'neutral' };
  }

  return (
    <div className="ledger">
      <div className="ledger-inner">
        {!hideHeader && (
          <div className="ledger-head">
            <div>
              <div style={{ fontWeight: 600, fontSize: 13 }}>{team.name} · SAF ledger</div>
              <div className="ledger-stats mt-8">
                <span className="ledger-stat">Allocated <strong className="cell-mono">${team.budget.allocated.toLocaleString()}</strong></span>
                <span className="ledger-stat">Spent <strong className="cell-mono">${team.budget.spent.toLocaleString()}</strong></span>
                <span className="ledger-stat">Remaining <strong className="cell-mono">${(team.budget.allocated - team.budget.spent).toLocaleString()}</strong></span>
                <span className="ledger-stat">Applications <strong>{list.length}</strong></span>
              </div>
            </div>
            {canEdit && (
              <button className="btn btn-secondary btn-sm" onClick={() => setShowForm(s => !s)}>
                <window.I.Plus size={13} /> New SAF application
              </button>
            )}
          </div>
        )}

        {showForm && (
          <div style={{ marginBottom: 14 }}>
            <SAFForm
              defaultTeamId={team.id}
              onCancel={() => setShowForm(false)}
              onAdd={(rec) => {
                window.AppStore.addSAF({ ...rec, enteredBy: user?.name || 'Staff' });
                setShowForm(false);
              }}
            />
          </div>
        )}

        {list.length === 0 ? (
          <div className="empty" style={{ padding: '32px 20px' }}>
            <div className="empty-icon"><window.I.FileText size={20} /></div>
            <div className="empty-title">No SAF applications yet</div>
            <div className="empty-msg">Submit the first SAF purchasing application for {team.name}.</div>
            {canEdit && (
              <button className="btn btn-primary btn-sm" onClick={() => setShowForm(true)}>
                <window.I.Plus size={13} /> New SAF application
              </button>
            )}
          </div>
        ) : (
          <div className="card" style={{ background: 'var(--surface)' }}>
            <table className="data">
              <thead>
                <tr>
                  <th style={{ width: 28 }}></th>
                  <th>Date</th>
                  <th>Vendor / purpose</th>
                  <th>Category</th>
                  <th>Reimburse</th>
                  <th>Status</th>
                  <th>Receipt</th>
                  <th style={{ textAlign: 'right' }}>Amount</th>
                  <th>Submitted by</th>
                </tr>
              </thead>
              <tbody>
                {list.map(t => {
                  const isOpen = expanded === t.id;
                  const st = safStatus(t.status);
                  return (
                    <React.Fragment key={t.id}>
                      <tr className="clickable" onClick={() => setExpanded(isOpen ? null : t.id)}>
                        <td style={{ color: 'var(--text-3)' }}>
                          <window.I.ChevronRight size={14} style={{ transform: isOpen ? 'rotate(90deg)' : 'none', transition: 'transform 0.15s' }} />
                        </td>
                        <td className="cell-mono cell-muted">{t.date}</td>
                        <td>
                          <div style={{ fontWeight: 600 }}>{t.vendor?.name || t.desc}</div>
                          <div className="cell-muted" style={{ fontSize: 11 }}>{t.desc}</div>
                        </td>
                        <td><span className="badge neutral">{t.category}</span></td>
                        <td>
                          {t.isReimbursement
                            ? <span className="badge gold">Reimbursement</span>
                            : <span className="dim" style={{ fontSize: 11 }}>Direct pay</span>}
                          {t.isReimbursement && t.check && (
                            <div style={{ marginTop: 4, fontSize: 10 }}>
                              <span className={`badge ${t.check.status === 'cashed' ? 'success' : 'gold'} dot`}>
                                Check {t.check.status}
                              </span>
                            </div>
                          )}
                        </td>
                        <td><span className={`badge ${st.kind} dot`}>{st.label}</span></td>
                        <td>
                          {t.receipt
                            ? <span className="flex-gap-8" style={{ gap: 4, fontSize: 11, color: 'var(--text-2)' }}>
                                <window.I.FileText size={12} />
                                {t.receipt.kind}
                              </span>
                            : <span className="dim" style={{ fontSize: 11 }}>Missing</span>}
                        </td>
                        <td className="cell-mono" style={{ textAlign: 'right', fontWeight: 600 }}>${t.amount.toLocaleString()}</td>
                        <td className="cell-muted" style={{ fontSize: 11 }}>
                          {t.officer?.name || t.enteredBy}
                          <div className="dim">{t.enteredBy ? `entered by ${t.enteredBy}` : ''}</div>
                        </td>
                      </tr>
                      {isOpen && (
                        <tr>
                          <td colSpan={9} style={{ padding: 0, background: 'var(--bg)' }}>
                            <SAFDetail rec={t} onAdvance={advance} user={user} />
                          </td>
                        </tr>
                      )}
                    </React.Fragment>
                  );
                })}
                <tr style={{ background: 'var(--surface-2)' }}>
                  <td colSpan={7} style={{ textAlign: 'right', fontWeight: 600, fontSize: 11, textTransform: 'uppercase', letterSpacing: '0.06em', color: 'var(--text-2)' }}>Total this ledger</td>
                  <td className="cell-mono" style={{ textAlign: 'right', fontWeight: 700 }}>${total.toLocaleString()}</td>
                  <td></td>
                </tr>
              </tbody>
            </table>
          </div>
        )}
      </div>
    </div>
  );
}

function SAFDetail({ rec, onAdvance, user }) {
  const [printRec, setPrintRec] = useStateB(null);
  const wf = rec.workflow || {};
  const status = rec.status;

  const fmt = (iso) => window.Fmt.dateTime(iso);

  const isStoney = user?.role === 'staff_admin' && user?.domain === 'fields';
  const isVal = user?.role === 'staff_admin' && user?.domain === 'courts';
  const isSuper = user?.role === 'super_admin';

  // Determine current step (0..3)
  let currentStep = 0;
  if (wf.posted) currentStep = 4;
  else if (wf.valConfirmed) currentStep = 3;
  else if (wf.stoneySigned) currentStep = 2;
  else if (wf.submitted) currentStep = 1;
  if (wf.returned) currentStep = -1;

  const steps = [
    { num: 1, label: 'Submitted', meta: wf.submitted ? `${wf.submitted.by} · ${fmt(wf.submitted.at)}` : 'Officer files SAF via Canvas' },
    { num: 2, label: 'Stoney signs', meta: wf.stoneySigned ? `${wf.stoneySigned.by} · ${fmt(wf.stoneySigned.at)}` : 'Print + staple receipt, hand to Stoney' },
    { num: 3, label: 'Val confirms', meta: wf.valConfirmed ? `${wf.valConfirmed.by} · ${fmt(wf.valConfirmed.at)}` : 'Val checks accuracy, moves money' },
    { num: 4, label: 'Posted', meta: wf.posted ? `${wf.posted.by} · ${fmt(wf.posted.at)}` : 'Update team sheet, notify president' },
  ];

  function stepClass(idx) {
    if (wf.returned && idx === 1) return 'returned';
    if (idx + 1 < currentStep) return 'done';
    if (idx + 1 === currentStep) return wf.returned ? 'returned' : 'current';
    return '';
  }

  // Determine which advance action to show
  let advanceAction = null;
  if (status === 'submitted' && (isStoney || isSuper)) {
    advanceAction = { label: 'Mark Stoney signed', next: 'stoney-signed', icon: 'Check' };
  } else if (status === 'stoney-signed' && (isVal || isSuper)) {
    advanceAction = { label: 'Mark Val confirmed', next: 'val-confirmed', icon: 'Check' };
  } else if ((status === 'val-confirmed' || status === 'approved') && (isVal || isSuper)) {
    advanceAction = { label: 'Post funds + notify president', next: 'posted', icon: 'Send' };
  }

  return (
    <div style={{ padding: '18px 24px' }}>
      {/* Workflow stepper */}
      <div className="stepper mb-16">
        {steps.map((s, i) => (
          <div key={i} className={`step ${stepClass(i)}`}>
            <div className="step-num">{s.num}</div>
            <div className="step-label">{s.label}</div>
            <div className="step-meta">{s.meta}</div>
          </div>
        ))}
      </div>

      {wf.returned && (
        <div className="tip" style={{ borderLeftColor: 'var(--danger)', background: 'rgba(229, 57, 53, 0.05)' }}>
          <window.I.AlertTriangle size={14} style={{ flexShrink: 0, marginTop: 1, color: 'var(--danger)' }} />
          <div>
            <strong style={{ color: 'var(--danger)' }}>Returned to team</strong> · {wf.returned.by} · {fmt(wf.returned.at)}
            <div style={{ marginTop: 2, color: 'var(--text-2)' }}>{wf.returned.reason}</div>
          </div>
        </div>
      )}

      {/* Action bar */}
      <div className="flex-between mb-16">
        <div className="flex-gap-8" style={{ flexWrap: 'wrap', gap: 6 }}>
          <button className="btn btn-secondary btn-sm" onClick={() => setPrintRec(rec)}>
            <window.I.Download size={13} /> Print + staple to receipt
          </button>
          {advanceAction && (
            <button
              className="btn btn-primary btn-sm"
              onClick={() => onAdvance && onAdvance(rec.id, advanceAction.next)}
            >
              {(() => { const Ic = window.I[advanceAction.icon]; return <Ic size={13} />; })()}
              {advanceAction.label}
            </button>
          )}
          {!wf.posted && !wf.returned && (isStoney || isVal || isSuper) && (
            <button
              className="btn btn-deny btn-sm"
              onClick={() => onAdvance && onAdvance(rec.id, 'returned')}
            >
              <window.I.RefreshCw size={13} /> Return to team
            </button>
          )}
        </div>
        <div className="dim" style={{ fontSize: 11 }}>
          Application ID · <span className="cell-mono" style={{ color: 'var(--text-2)' }}>{rec.id.toUpperCase()}</span>
        </div>
      </div>

      {/* Detail cards */}
      <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 14 }}>
        <div className="card" style={{ padding: 16, background: 'var(--surface)' }}>
          <div className="section-title" style={{ margin: '0 0 10px' }}>Officer + submission</div>
          <dl className="approval-meta">
            <dt>Officer</dt><dd>{rec.officer?.name}</dd>
            <dt>Position</dt><dd>{rec.officer?.position}</dd>
            <dt>Email</dt><dd>{rec.officer?.email}</dd>
            <dt>Submitted</dt><dd>{rec.submittedAt ? fmt(rec.submittedAt) : rec.date}</dd>
            <dt>Reimbursement</dt><dd>{rec.isReimbursement ? 'Yes — reimburse officer' : 'No — direct pay vendor'}</dd>
            <dt>Entered by</dt><dd>{rec.enteredBy}</dd>
          </dl>
        </div>
        <div className="card" style={{ padding: 16, background: 'var(--surface)' }}>
          <div className="section-title" style={{ margin: '0 0 10px' }}>Vendor / supplier</div>
          <dl className="approval-meta">
            <dt>Name</dt><dd>{rec.vendor?.name || '—'}</dd>
            <dt>Phone</dt><dd>{rec.vendor?.phone || <span className="dim">—</span>}</dd>
            <dt>Address</dt><dd>{rec.vendor?.address || '—'}</dd>
            <dt>Email</dt><dd>{rec.vendor?.email || <span className="dim">—</span>}</dd>
          </dl>
        </div>
        <div className="card" style={{ padding: 16, background: 'var(--surface)', gridColumn: 'span 2' }}>
          <div className="section-title" style={{ margin: '0 0 10px' }}>Justification + receipt</div>
          <div style={{ fontSize: 13, marginBottom: 12, color: 'var(--text)' }}>{rec.justification || <span className="dim">No justification recorded.</span>}</div>
          <div className="flex-gap-12" style={{ gap: 12 }}>
            {rec.receipt ? (
              <button className="btn btn-secondary btn-sm">
                <window.I.FileText size={13} />
                {rec.receipt.filename}
                <span className="dim" style={{ marginLeft: 6, fontSize: 11 }}>{rec.receipt.size}</span>
              </button>
            ) : (
              <span className="badge danger">Receipt required</span>
            )}
          </div>
          {rec.gas && (
            <div style={{ marginTop: 14 }}>
              <div className="section-title" style={{ margin: '0 0 10px' }}>Gas reimbursement detail</div>
              <dl className="approval-meta" style={{ gridTemplateColumns: '160px 1fr' }}>
                <dt>Cars taken</dt><dd>{rec.gas.cars}</dd>
                <dt>Departure</dt><dd>{rec.gas.from}</dd>
                <dt>Destination</dt><dd>{rec.gas.to}</dd>
              </dl>
            </div>
          )}
        </div>

        {/* Reimbursement check status — only for reimbursement SAFs */}
        {rec.isReimbursement && (rec.status === 'posted' || rec.check) && (
          <div className="card" style={{ padding: 16, background: 'var(--surface)', gridColumn: 'span 2' }}>
            <div className="section-title" style={{ margin: '0 0 10px' }}>Reimbursement check status</div>
            <ReimbursementTracker rec={rec} user={user} />
          </div>
        )}
      </div>

      {printRec && <window.SAFPrintModal rec={printRec} onClose={() => setPrintRec(null)} />}
    </div>
  );
}

function SAFForm({ onCancel, onAdd, defaultTeamId }) {
  const [team, setTeam] = useStateB(defaultTeamId || '');
  const [date, setDate] = useStateB('2026-05-15');
  const [cat, setCat] = useStateB(window.AppData.SAF_CATEGORIES[0]);
  const [isReimburse, setIsReimburse] = useStateB('no');
  const [amount, setAmount] = useStateB('');
  const [otherExpenses, setOtherExpenses] = useStateB('');

  const officerDefault = team ? window.AppData.OFFICERS_BY_TEAM[team] : null;
  const [officerName, setOfficerName] = useStateB(officerDefault?.name || '');
  const [officerPos, setOfficerPos] = useStateB(officerDefault?.position || 'President');
  const [officerEmail, setOfficerEmail] = useStateB(officerDefault?.email || '');

  const [vendorName, setVendorName] = useStateB('');
  const [vendorPhone, setVendorPhone] = useStateB('');
  const [vendorAddr, setVendorAddr] = useStateB('');
  const [vendorEmail, setVendorEmail] = useStateB('');
  const [justification, setJustification] = useStateB('');
  const [receiptName, setReceiptName] = useStateB('');

  // Gas section
  const [gasCars, setGasCars] = useStateB('');
  const [gasFrom, setGasFrom] = useStateB('901 S State St, Big Rapids MI');
  const [gasTo, setGasTo] = useStateB('');

  const isGas = cat === 'Gas reimbursement';
  const showGas = isGas || isReimburse === 'yes' && cat === 'Travel · lodging' === false && isGas;

  React.useEffect(() => {
    if (team && window.AppData.OFFICERS_BY_TEAM[team]) {
      const o = window.AppData.OFFICERS_BY_TEAM[team];
      setOfficerName(o.name); setOfficerPos(o.position); setOfficerEmail(o.email);
    }
  }, [team]);

  React.useEffect(() => {
    if (isGas) setIsReimburse('yes');
  }, [isGas]);

  function submit() {
    if (!team || !officerName || !amount || !vendorName || !justification) return;
    onAdd({
      teamId: team,
      date,
      desc: cat === 'Other' && otherExpenses ? otherExpenses : `${cat} · ${vendorName}`,
      vendor: { name: vendorName, phone: vendorPhone, address: vendorAddr, email: vendorEmail },
      amount: Number(String(amount).replace(/[^\d.]/g, '')) || 0,
      category: cat,
      isReimbursement: isReimburse === 'yes',
      justification,
      receipt: receiptName ? { filename: receiptName, size: '—', kind: receiptName.split('.').pop()?.toUpperCase() || 'FILE' } : null,
      gas: isGas ? { cars: Number(gasCars) || 0, from: gasFrom, to: gasTo } : null,
      officer: { name: officerName, position: officerPos, email: officerEmail },
      status: 'pending',
      enteredBy: 'Justin Reilly',
      submittedAt: new Date().toISOString(),
    });
  }

  const SectionHead = ({ children }) => (
    <div style={{
      fontSize: 11, fontWeight: 600, color: 'var(--text-2)',
      textTransform: 'uppercase', letterSpacing: '0.08em',
      borderTop: '1px solid var(--border)', paddingTop: 14, marginTop: 6,
    }}>
      {children}
    </div>
  );

  return (
    <div className="inline-form">
      <div className="inline-form-head">
        <div>
          <div style={{ fontSize: 14, fontWeight: 600 }}>Club Sports SAF purchasing application</div>
          <div className="dim" style={{ fontSize: 11, fontWeight: 400, marginTop: 2 }}>
            Replaces the legacy SAF Google Form. Staff log applications on behalf of the team after the officer submits via Canvas.
          </div>
        </div>
        <button className="btn btn-ghost btn-sm" onClick={onCancel}><window.I.X size={14} /></button>
      </div>

      <div className="form-grid cols-3">
        <div>
          <label className="field-label">FSU club name <span className="gold">*</span></label>
          <select className="select" value={team} onChange={e => setTeam(e.target.value)}>
            <option value="" disabled>Select club…</option>
            {window.AppData.TEAMS.map(t => <option key={t.id} value={t.id}>{t.name}</option>)}
          </select>
        </div>
        <div>
          <label className="field-label">Date <span className="gold">*</span></label>
          <input type="date" className="input" value={date} onChange={e => setDate(e.target.value)} />
        </div>
        <div>
          <label className="field-label">Amount <span className="gold">*</span></label>
          <input className="input" placeholder="$0.00" value={amount} onChange={e => setAmount(e.target.value)} />
        </div>
      </div>

      <SectionHead>Officer completing form</SectionHead>
      <div className="form-grid cols-3 mt-8">
        <div>
          <label className="field-label">Officer name <span className="gold">*</span></label>
          <input className="input" value={officerName} onChange={e => setOfficerName(e.target.value)} placeholder="Riley Garcia" />
        </div>
        <div>
          <label className="field-label">Position on E-board <span className="gold">*</span></label>
          <select className="select" value={officerPos} onChange={e => setOfficerPos(e.target.value)}>
            {window.AppData.E_BOARD_POSITIONS.map(p => <option key={p}>{p}</option>)}
          </select>
        </div>
        <div>
          <label className="field-label">Officer email <span className="gold">*</span></label>
          <input className="input" value={officerEmail} onChange={e => setOfficerEmail(e.target.value)} placeholder="name@ferris.edu" />
        </div>
      </div>

      <SectionHead>Purchase</SectionHead>
      <div className="form-grid cols-3 mt-8">
        <div>
          <label className="field-label">Is this a reimbursement? <span className="gold">*</span></label>
          <div className="flex-gap-8" style={{ gap: 0, background: 'var(--bg)', border: '1px solid var(--border)', borderRadius: 6, padding: 3 }}>
            {['yes','no'].map(v => (
              <button
                key={v}
                type="button"
                onClick={() => setIsReimburse(v)}
                disabled={isGas && v === 'no'}
                style={{
                  flex: 1, padding: '6px 10px', borderRadius: 4, fontSize: 12, fontWeight: 600,
                  background: isReimburse === v ? 'var(--surface-2)' : 'transparent',
                  color: isReimburse === v ? 'var(--gold)' : 'var(--text-2)',
                  cursor: isGas && v === 'no' ? 'not-allowed' : 'pointer',
                  opacity: isGas && v === 'no' ? 0.4 : 1,
                }}
              >
                {v === 'yes' ? 'Yes · reimburse officer' : 'No · pay vendor direct'}
              </button>
            ))}
          </div>
        </div>
        <div>
          <label className="field-label">Event category <span className="gold">*</span></label>
          <select className="select" value={cat} onChange={e => setCat(e.target.value)}>
            {window.AppData.SAF_CATEGORIES.map(c => <option key={c}>{c}</option>)}
          </select>
        </div>
        <div>
          <label className="field-label">Other expenses (please list)</label>
          <input className="input" value={otherExpenses} onChange={e => setOtherExpenses(e.target.value)} placeholder="Banquet decor, awards, etc." disabled={cat !== 'Other'} />
        </div>
      </div>

      <SectionHead>Supplier / vendor information</SectionHead>
      <div className="form-grid cols-2 mt-8">
        <div>
          <label className="field-label">Full name <span className="gold">*</span></label>
          <input className="input" value={vendorName} onChange={e => setVendorName(e.target.value)} placeholder="BSN Sports" />
        </div>
        <div>
          <label className="field-label">Phone</label>
          <input className="input" value={vendorPhone} onChange={e => setVendorPhone(e.target.value)} placeholder="(231) 555-0123" />
        </div>
        <div>
          <label className="field-label">Address <span className="gold">*</span></label>
          <input className="input" value={vendorAddr} onChange={e => setVendorAddr(e.target.value)} placeholder="1234 Main St, Grand Rapids MI" />
        </div>
        <div>
          <label className="field-label">Email</label>
          <input className="input" value={vendorEmail} onChange={e => setVendorEmail(e.target.value)} placeholder="orders@vendor.com" />
        </div>
      </div>

      <SectionHead>Justification + receipt</SectionHead>
      <div className="form-grid mt-8" style={{ gridTemplateColumns: '1fr' }}>
        <div>
          <label className="field-label">Justification for expenditure <span className="gold">*</span></label>
          <textarea
            className="textarea"
            rows={3}
            value={justification}
            onChange={e => setJustification(e.target.value)}
            placeholder="Replacement jerseys for six players whose sizing changed mid-season; needed before May 25 home opener."
            style={{ resize: 'vertical' }}
          />
        </div>
        <div>
          <label className="field-label">Receipt from purchase <span className="gold">*</span></label>
          <label
            style={{
              display: 'flex', alignItems: 'center', gap: 10,
              padding: '10px 14px', border: '1px dashed var(--border-2)', borderRadius: 6,
              background: 'var(--bg)', cursor: 'pointer',
            }}
          >
            <window.I.Upload size={14} style={{ color: 'var(--gold)' }} />
            <span style={{ fontSize: 13 }}>
              {receiptName || 'Drop or choose a file'}
            </span>
            <span className="dim" style={{ fontSize: 11, marginLeft: 'auto' }}>
              PDF · DOC/DOCX · XLS/CSV · JPG · PNG · GIF
            </span>
            <input
              type="file"
              style={{ display: 'none' }}
              onChange={e => setReceiptName(e.target.files?.[0]?.name || '')}
            />
          </label>
        </div>
      </div>

      {isGas && (
        <>
          <SectionHead>For gas reimbursements</SectionHead>
          <div className="form-grid cols-3 mt-8">
            <div>
              <label className="field-label">How many cars were taken</label>
              <input className="input" value={gasCars} onChange={e => setGasCars(e.target.value)} placeholder="2" />
            </div>
            <div>
              <label className="field-label">Address of departure</label>
              <input className="input" value={gasFrom} onChange={e => setGasFrom(e.target.value)} />
            </div>
            <div>
              <label className="field-label">Address of destination</label>
              <input className="input" value={gasTo} onChange={e => setGasTo(e.target.value)} placeholder="1700 Fulton St E, Grand Rapids MI" />
            </div>
          </div>
        </>
      )}

      <div className="flex-between mt-16" style={{ borderTop: '1px solid var(--border)', paddingTop: 14 }}>
        <span className="dim" style={{ fontSize: 12 }}>
          On submit this application enters the SAF review queue, stamped with your name and timestamp.
        </span>
        <div className="flex-gap-8">
          <button className="btn btn-ghost btn-sm" onClick={onCancel}>Cancel</button>
          <button className="btn btn-secondary btn-sm">Save as draft</button>
          <button className="btn btn-primary btn-sm" onClick={submit}>Submit SAF application</button>
        </div>
      </div>
    </div>
  );
}

window.BudgetScreen = BudgetScreen;
window.LedgerView = LedgerView;
window.SAFForm = SAFForm;
window.SAFDetail = SAFDetail;

function ReimbursementTracker({ rec, user }) {
  const check = rec.check || {};
  const status = check.status; // 'requested' | 'mailed' | 'cashed' | null

  const steps = [
    { key: 'requested', label: 'Check requested', meta: 'Accounting cuts the check' },
    { key: 'mailed', label: 'Check mailed', meta: `${rec.officer?.name || 'Officer'} \u00b7 home address on file` },
    { key: 'cashed', label: 'Officer confirmed received', meta: 'Officer marks cashed in Canvas' },
  ];

  const idx = status === 'cashed' ? 2 : status === 'mailed' ? 1 : status === 'requested' ? 0 : -1;
  const canAdvance = user?.role === 'super_admin' || (user?.role === 'staff_admin' && user?.domain === 'courts');

  function advance(next) {
    window.AppStore.advanceCheck(rec.id, next, user?.name || 'Staff');
  }

  return (
    <div>
      <div className="stepper mb-12" style={{ gridTemplateColumns: 'repeat(3, 1fr)' }}>
        {steps.map((s, i) => {
          let cls = '';
          if (i < idx) cls = 'done';
          else if (i === idx) cls = 'current';
          return (
            <div key={s.key} className={`step ${cls}`}>
              <div className="step-num">{i + 1}</div>
              <div className="step-label">{s.label}</div>
              <div className="step-meta">
                {i <= idx
                  ? <span>{i === idx && check.at ? window.Fmt.dateTime(check.at) : (i < idx ? '\u2713 done' : s.meta)}</span>
                  : s.meta}
              </div>
            </div>
          );
        })}
      </div>
      <div className="flex-between" style={{ flexWrap: 'wrap', gap: 8 }}>
        <div className="flex-gap-12" style={{ flexWrap: 'wrap', gap: 14, fontSize: 12, color: 'var(--text-2)' }}>
          {check.number && <span>Check # <strong className="cell-mono" style={{ color: 'var(--text)' }}>{check.number}</strong></span>}
          <span>Amount <strong className="cell-mono" style={{ color: 'var(--text)' }}>${(rec.amount || 0).toLocaleString()}</strong></span>
          <span>Payee <strong style={{ color: 'var(--text)' }}>{rec.officer?.name}</strong></span>
        </div>
        {canAdvance && (
          <div className="flex-gap-8" style={{ gap: 6 }}>
            {!status && (
              <button className="btn btn-secondary btn-sm" onClick={() => advance('requested')}>
                <window.I.Send size={12} /> Mark check requested
              </button>
            )}
            {status === 'requested' && (
              <button className="btn btn-secondary btn-sm" onClick={() => advance('mailed')}>
                <window.I.Mail size={12} /> Mark check mailed
              </button>
            )}
            {status === 'mailed' && (
              <button className="btn btn-success btn-sm" onClick={() => advance('cashed')}>
                <window.I.CheckCircle size={12} /> Mark received
              </button>
            )}
          </div>
        )}
      </div>
    </div>
  );
}

window.ReimbursementTracker = ReimbursementTracker;
