// Admin analytics view — per-investor engagement

const FAKE_INVESTORS = [
  {
    id: 'i1', name: 'Jane Catalano', firm: 'Latticework Capital', email: 'jane@latticework.vc',
    profile: 'Fund / RIA', allocation: '$500K – $2M', timeline: '3–6 months',
    invitedDays: 2, lastSeen: '2h ago', status: 'ACTIVE',
    sessions: 4, totalTime: 1842, // seconds
    docs: [
      { id: 'deck',     time: 412, scroll: 100, downloaded: false, opens: 3 },
      { id: 'memo',     time: 663, scroll: 100, downloaded: false, opens: 2 },
      { id: 'model',    time: 487, scroll: 88,  downloaded: true,  opens: 2 },
      { id: 'audit-tob',time: 144, scroll: 42,  downloaded: false, opens: 1 },
      { id: 'audit-oz', time:  46, scroll: 18,  downloaded: false, opens: 1 },
      { id: 'term',     time:  90, scroll: 100, downloaded: true,  opens: 1 },
      { id: 'sol',      time:   0, scroll: 0,   downloaded: false, opens: 0 },
    ],
    activity: [0,0,1,2,2,3,2,1,2,4,3,2,1,0,0,0,0,1,2,1,0,0,0,0],
    score: 91,
  },
  {
    id: 'i2', name: 'Marcus Reed', firm: 'Bridgewater Family Office', email: 'mreed@bwfo.com',
    profile: 'Family Office', allocation: '$2M+', timeline: 'This quarter',
    invitedDays: 1, lastSeen: '14m ago', status: 'ACTIVE',
    sessions: 6, totalTime: 2960,
    docs: [
      { id: 'deck',     time: 522, scroll: 100, downloaded: true,  opens: 4 },
      { id: 'memo',     time: 408, scroll: 100, downloaded: false, opens: 3 },
      { id: 'model',    time: 894, scroll: 95,  downloaded: true,  opens: 5 },
      { id: 'audit-tob',time: 320, scroll: 78,  downloaded: true,  opens: 2 },
      { id: 'audit-oz', time: 280, scroll: 70,  downloaded: true,  opens: 2 },
      { id: 'term',     time: 412, scroll: 100, downloaded: true,  opens: 3 },
      { id: 'sol',      time: 124, scroll: 100, downloaded: false, opens: 1 },
    ],
    activity: [0,1,2,3,4,3,2,1,2,3,4,5,4,3,2,1,2,3,4,3,2,1,1,0],
    score: 96,
  },
  {
    id: 'i3', name: 'Sara Lindqvist', firm: 'North Sea Crypto', email: 's.lindqvist@nsc.fund',
    profile: 'Fund / RIA', allocation: '$100K – $500K', timeline: '6–12 months',
    invitedDays: 6, lastSeen: '1d ago', status: 'WARM',
    sessions: 2, totalTime: 612,
    docs: [
      { id: 'deck',     time: 380, scroll: 100, downloaded: false, opens: 2 },
      { id: 'memo',     time: 210, scroll: 64,  downloaded: false, opens: 1 },
      { id: 'model',    time:  22, scroll: 12,  downloaded: false, opens: 1 },
      { id: 'audit-tob',time:   0, scroll: 0,   downloaded: false, opens: 0 },
      { id: 'audit-oz', time:   0, scroll: 0,   downloaded: false, opens: 0 },
      { id: 'term',     time:   0, scroll: 0,   downloaded: false, opens: 0 },
      { id: 'sol',      time:   0, scroll: 0,   downloaded: false, opens: 0 },
    ],
    activity: [0,0,0,0,0,2,3,2,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0],
    score: 54,
  },
  {
    id: 'i4', name: 'Ravi Anand', firm: 'Self', email: 'ravi.anand@gmail.com',
    profile: 'Individual (Accredited)', allocation: '$100K – $500K', timeline: 'This quarter',
    invitedDays: 3, lastSeen: '5h ago', status: 'ACTIVE',
    sessions: 3, totalTime: 1180,
    docs: [
      { id: 'deck',     time: 460, scroll: 100, downloaded: true, opens: 3 },
      { id: 'memo',     time: 320, scroll: 92,  downloaded: false, opens: 2 },
      { id: 'model',    time: 160, scroll: 60,  downloaded: false, opens: 1 },
      { id: 'audit-tob',time:  80, scroll: 28,  downloaded: false, opens: 1 },
      { id: 'audit-oz', time:   0, scroll: 0,   downloaded: false, opens: 0 },
      { id: 'term',     time: 160, scroll: 100, downloaded: false, opens: 1 },
      { id: 'sol',      time:   0, scroll: 0,   downloaded: false, opens: 0 },
    ],
    activity: [0,0,0,0,1,2,3,1,0,0,0,0,1,2,1,0,0,0,0,2,1,0,0,0],
    score: 76,
  },
  {
    id: 'i5', name: 'Yuki Tanaka', firm: 'Octant DAO', email: 'yuki@octant.eth',
    profile: 'Strategic / DAO', allocation: '$2M+', timeline: '3–6 months',
    invitedDays: 4, lastSeen: '8h ago', status: 'WARM',
    sessions: 2, totalTime: 720,
    docs: [
      { id: 'deck',     time: 240, scroll: 90,  downloaded: false, opens: 2 },
      { id: 'memo',     time: 180, scroll: 100, downloaded: false, opens: 1 },
      { id: 'model',    time:   0, scroll: 0,   downloaded: false, opens: 0 },
      { id: 'audit-tob',time: 120, scroll: 48,  downloaded: false, opens: 1 },
      { id: 'audit-oz', time:   0, scroll: 0,   downloaded: false, opens: 0 },
      { id: 'term',     time:   0, scroll: 0,   downloaded: false, opens: 0 },
      { id: 'sol',      time: 180, scroll: 100, downloaded: false, opens: 1 },
    ],
    activity: [0,0,0,0,0,0,0,2,1,0,0,0,0,0,1,2,1,0,0,0,0,0,0,0],
    score: 67,
  },
  {
    id: 'i6', name: 'Eli Brooks', firm: 'Veridian Partners', email: 'eli@veridian.partners',
    profile: 'Family Office', allocation: '< $100K', timeline: 'Just exploring',
    invitedDays: 9, lastSeen: '6d ago', status: 'COLD',
    sessions: 1, totalTime: 124,
    docs: [
      { id: 'deck',     time: 110, scroll: 36,  downloaded: false, opens: 1 },
      { id: 'memo',     time:  14, scroll:  8,  downloaded: false, opens: 1 },
      { id: 'model',    time:   0, scroll: 0,   downloaded: false, opens: 0 },
      { id: 'audit-tob',time:   0, scroll: 0,   downloaded: false, opens: 0 },
      { id: 'audit-oz', time:   0, scroll: 0,   downloaded: false, opens: 0 },
      { id: 'term',     time:   0, scroll: 0,   downloaded: false, opens: 0 },
      { id: 'sol',      time:   0, scroll: 0,   downloaded: false, opens: 0 },
    ],
    activity: [0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    score: 21,
  },
];

function fmtSec(s) {
  if (s < 60) return `${s}s`;
  return `${Math.floor(s/60)}m ${String(s%60).padStart(2,'0')}s`;
}

function statusColor(s) {
  return s === 'ACTIVE' ? 'success' : s === 'WARM' ? 'gold' : s === 'COLD' ? 'default' : 'default';
}

function Admin({ tweaks, onLogout }) {
  const [tab, setTab] = React.useState('investors');
  const [selectedId, setSelectedId] = React.useState(null);
  const [sortBy, setSortBy] = React.useState('score');

  const sorted = [...FAKE_INVESTORS].sort((a, b) => {
    if (sortBy === 'score') return b.score - a.score;
    if (sortBy === 'time') return b.totalTime - a.totalTime;
    if (sortBy === 'recent') return a.lastSeen.localeCompare(b.lastSeen);
    return 0;
  });

  const totalInvestors = FAKE_INVESTORS.length;
  const activeNow = FAKE_INVESTORS.filter(i => i.status === 'ACTIVE').length;
  const totalDownloads = FAKE_INVESTORS.reduce((sum, i) => sum + i.docs.filter(d => d.downloaded).length, 0);
  const avgScore = Math.round(FAKE_INVESTORS.reduce((s, i) => s + i.score, 0) / totalInvestors);

  const selected = selectedId ? FAKE_INVESTORS.find(i => i.id === selectedId) : null;

  return (
    <div style={{ display: 'flex', minHeight: '100vh', background: 'var(--bg)' }}>
      {/* Sidebar */}
      <aside style={{
        width: 240, flexShrink: 0,
        borderRight: '1px solid var(--border)',
        padding: '20px 0',
        display: 'flex', flexDirection: 'column',
      }}>
        <div style={{ padding: '0 20px', marginBottom: 28 }}>
          <ArbWordmark size={11} variant={tweaks.logoVariant} />
        </div>
        <div style={{ padding: '0 20px', marginBottom: 8 }}>
          <div className="mono" style={{ fontSize: 9, letterSpacing: '0.14em', color: 'var(--text-tertiary)' }}>
            ADMIN
          </div>
        </div>
        <NavItem active={tab === 'overview'} onClick={() => { setTab('overview'); setSelectedId(null); }} num={1} label="Overview" count="" />
        <NavItem active={tab === 'invites'} onClick={() => { setTab('invites'); setSelectedId(null); }} num={2} label="Invites" count="" />
        <NavItem active={tab === 'investors'} onClick={() => { setTab('investors'); setSelectedId(null); }} num={3} label="Investors" count={totalInvestors} />
        <NavItem active={tab === 'docs'} onClick={() => { setTab('docs'); setSelectedId(null); }} num={4} label="Documents" count={ROOM_FILES.length} />
        <NavItem active={tab === 'activity'} onClick={() => { setTab('activity'); setSelectedId(null); }} num={5} label="Activity log" count="" />

        <div style={{ marginTop: 'auto', padding: '8px 20px', borderTop: '1px solid var(--border)' }}>
          <div style={{ fontSize: 13, marginBottom: 4 }}>Maya Strom</div>
          <div className="mono" style={{ fontSize: 10, color: 'var(--text-tertiary)', letterSpacing: '0.06em' }}>
            FOUNDER · CEO
          </div>
          <button className="btn btn-ghost btn-sm" style={{ padding: 0, marginTop: 12 }} onClick={onLogout}>
            ↻ Switch to investor view (admin sign out)
          </button>
        </div>
      </aside>

      {/* Main */}
      <main style={{ flex: 1, padding: '36px 48px', overflow: 'auto' }}>
        {!selected && tab === 'overview' && (
          <Overview totalInvestors={totalInvestors} activeNow={activeNow} totalDownloads={totalDownloads} avgScore={avgScore} />
        )}
        {!selected && tab === 'invites' && <InvitesTab />}
        {!selected && tab === 'investors' && (
          <InvestorList investors={sorted} sortBy={sortBy} setSortBy={setSortBy} onOpen={setSelectedId} />
        )}
        {!selected && tab === 'docs' && <DocsAnalytics />}
        {!selected && tab === 'activity' && <ActivityLog />}
        {selected && <InvestorDetail investor={selected} onBack={() => setSelectedId(null)} />}
      </main>
    </div>
  );
}

function Overview({ totalInvestors, activeNow, totalDownloads, avgScore }) {
  return (
    <div>
      <div className="section-num" style={{ marginBottom: 12 }}>
        <span>[ ADMIN_VIEW ]</span><span className="div" /><span>SERIES_SEED · DATAROOM</span>
      </div>
      <h1 style={{ fontSize: 34, letterSpacing: '-0.025em', fontWeight: 400, margin: '0 0 8px' }}>
        Room overview
      </h1>
      <p style={{ fontSize: 14, color: 'var(--text-secondary)', marginBottom: 32 }}>
        Last 7 days · all investors
      </p>
      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 12, marginBottom: 32 }}>
        <RoomStat label="INVESTORS" value={totalInvestors} delta="+2 this wk" pos />
        <RoomStat label="ACTIVE_NOW" value={activeNow} />
        <RoomStat label="DOWNLOADS" value={totalDownloads} delta="+9 this wk" pos />
        <RoomStat label="AVG_ENGAGEMENT" value={`${avgScore}%`} />
      </div>

      <Brackets style={{ padding: 24, border: '1px solid var(--border)', background: 'var(--bg-card)', marginBottom: 24 }}>
        <SectionNum n={1} label="ENGAGEMENT_BY_DOCUMENT" />
        <div style={{ marginTop: 20 }}>
          {ROOM_FILES.map(f => {
            const totalSec = FAKE_INVESTORS.reduce((s, inv) => s + (inv.docs.find(d => d.id === f.id)?.time || 0), 0);
            const opens = FAKE_INVESTORS.reduce((s, inv) => s + (inv.docs.find(d => d.id === f.id)?.opens || 0), 0);
            const dl = FAKE_INVESTORS.reduce((s, inv) => s + (inv.docs.find(d => d.id === f.id)?.downloaded ? 1 : 0), 0);
            const max = 4500;
            return (
              <div key={f.id} style={{ display: 'grid', gridTemplateColumns: '20px 1fr 1fr 70px 70px 70px', gap: 16, alignItems: 'center', padding: '10px 0', borderBottom: '1px solid var(--border)' }}>
                <FileIcon kind={f.kind} size={18} />
                <span style={{ fontSize: 13 }}>{f.title || f.name}</span>
                <div className="bar bar-gold"><i style={{ width: `${(totalSec/max)*100}%` }} /></div>
                <span className="mono" style={{ fontSize: 11, color: 'var(--text-secondary)', textAlign: 'right' }}>{fmtSec(totalSec)}</span>
                <span className="mono" style={{ fontSize: 11, color: 'var(--text-secondary)', textAlign: 'right' }}>{opens} opens</span>
                <span className="mono" style={{ fontSize: 11, color: dl ? 'var(--success)' : 'var(--text-tertiary)', textAlign: 'right' }}>{dl} ↓</span>
              </div>
            );
          })}
        </div>
      </Brackets>

      <Brackets style={{ padding: 24, border: '1px solid var(--border)', background: 'var(--bg-card)' }}>
        <SectionNum n={2} label="ACTIVITY_HEATMAP" />
        <div style={{ marginTop: 20, display: 'grid', gridTemplateColumns: '120px 1fr', gap: 12 }}>
          {FAKE_INVESTORS.map(inv => (
            <React.Fragment key={inv.id}>
              <div style={{ fontSize: 12 }}>{inv.name.split(' ')[0]} {inv.name.split(' ')[1][0]}.</div>
              <HeatRow values={inv.activity.map(v => v / 5)} />
            </React.Fragment>
          ))}
          <div></div>
          <div style={{ display: 'flex', justifyContent: 'space-between', fontFamily: 'var(--font-mono)', fontSize: 9, color: 'var(--text-tertiary)', letterSpacing: '0.08em', marginTop: 4 }}>
            <span>24H AGO</span><span>18H</span><span>12H</span><span>6H</span><span>NOW</span>
          </div>
        </div>
      </Brackets>
    </div>
  );
}

function InvestorList({ investors, sortBy, setSortBy, onOpen }) {
  return (
    <div>
      <div className="section-num" style={{ marginBottom: 12 }}>
        <span>[ ADMIN_VIEW ]</span><span className="div" /><span>INVESTORS</span>
      </div>
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 24 }}>
        <div>
          <h1 style={{ fontSize: 34, letterSpacing: '-0.025em', fontWeight: 400, margin: '0 0 4px' }}>Investors</h1>
          <p style={{ fontSize: 14, color: 'var(--text-secondary)', margin: 0 }}>{investors.length} invited · {investors.filter(i=>i.status==='ACTIVE').length} active</p>
        </div>
        <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
          <span className="mono" style={{ fontSize: 9, letterSpacing: '0.14em', color: 'var(--text-tertiary)' }}>SORT_BY</span>
          <Segmented value={sortBy} setValue={setSortBy} options={[
            { v: 'score', label: 'Engagement' },
            { v: 'time', label: 'Time' },
            { v: 'recent', label: 'Recent' },
          ]} />
          <button className="btn btn-sm btn-filled">+ Invite</button>
        </div>
      </div>

      <Brackets style={{ background: 'var(--bg-card)', border: '1px solid var(--border)' }}>
        <table className="tbl">
          <thead>
            <tr>
              <th style={{ width: 30 }}></th>
              <th>Investor</th>
              <th>Profile</th>
              <th>Allocation</th>
              <th>Sessions</th>
              <th>Time on room</th>
              <th>Engagement</th>
              <th>Last seen</th>
              <th>Status</th>
              <th></th>
            </tr>
          </thead>
          <tbody>
            {investors.map((inv, i) => (
              <tr key={inv.id} onClick={() => onOpen(inv.id)} style={{ cursor: 'default' }}>
                <td><span className="mono" style={{ fontSize: 9, color: 'var(--text-tertiary)' }}>{String(i+1).padStart(2,'0')}</span></td>
                <td>
                  <div style={{ fontSize: 13 }}>{inv.name}</div>
                  <div className="mono" style={{ fontSize: 10, color: 'var(--text-tertiary)', marginTop: 2 }}>{inv.firm}</div>
                </td>
                <td><span className="mono" style={{ fontSize: 11, color: 'var(--text-secondary)' }}>{inv.profile}</span></td>
                <td><span className="mono" style={{ fontSize: 11 }}>{inv.allocation}</span></td>
                <td><span className="mono" style={{ fontSize: 11 }}>{inv.sessions}</span></td>
                <td><span className="mono" style={{ fontSize: 11 }}>{fmtSec(inv.totalTime)}</span></td>
                <td>
                  <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
                    <div className="bar bar-gold" style={{ width: 60 }}><i style={{ width: `${inv.score}%` }} /></div>
                    <span className="mono" style={{ fontSize: 11, color: 'var(--text-secondary)', width: 30 }}>{inv.score}</span>
                  </div>
                </td>
                <td><span className="mono" style={{ fontSize: 11, color: 'var(--text-tertiary)' }}>{inv.lastSeen}</span></td>
                <td><span className={`badge b-${statusColor(inv.status)}`}>{inv.status}</span></td>
                <td><span style={{ color: 'var(--text-tertiary)' }}>→</span></td>
              </tr>
            ))}
          </tbody>
        </table>
      </Brackets>
    </div>
  );
}

function InvestorDetail({ investor, onBack }) {
  return (
    <div>
      <button className="btn btn-ghost btn-sm" onClick={onBack} style={{ marginBottom: 16, padding: 0 }}>← All investors</button>

      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', marginBottom: 32 }}>
        <div>
          <div className="section-num" style={{ marginBottom: 12 }}>
            <span>[ INVESTOR ]</span><span className="div" /><span>{investor.firm.toUpperCase()}</span>
          </div>
          <h1 style={{ fontSize: 34, letterSpacing: '-0.025em', fontWeight: 400, margin: '0 0 4px' }}>{investor.name}</h1>
          <div style={{ display: 'flex', gap: 16, alignItems: 'center', marginTop: 8 }}>
            <span className="mono" style={{ fontSize: 11, color: 'var(--text-secondary)' }}>{investor.email}</span>
            <span className={`badge b-${statusColor(investor.status)}`}>{investor.status}</span>
          </div>
        </div>
        <div style={{ display: 'flex', gap: 8 }}>
          <button className="btn btn-sm">↗ Email</button>
          <button className="btn btn-sm">⌕ Reset access</button>
          <button className="btn btn-sm btn-filled">⏵ Schedule call</button>
        </div>
      </div>

      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 12, marginBottom: 32 }}>
        <RoomStat label="ENGAGEMENT" value={`${investor.score}%`} />
        <RoomStat label="TIME_ON_ROOM" value={fmtSec(investor.totalTime)} />
        <RoomStat label="SESSIONS" value={investor.sessions} />
        <RoomStat label="DOWNLOADS" value={investor.docs.filter(d => d.downloaded).length} />
      </div>

      <div style={{ display: 'grid', gridTemplateColumns: '1fr 280px', gap: 24 }}>
        {/* Doc engagement */}
        <Brackets style={{ padding: 24, border: '1px solid var(--border)', background: 'var(--bg-card)' }}>
          <SectionNum n={1} label="PER_DOCUMENT_BREAKDOWN" />
          <div style={{ marginTop: 16 }}>
            {investor.docs.filter(d => ROOM_FILES.find(x => x.id === d.id)).map(d => {
              const f = ROOM_FILES.find(x => x.id === d.id);
              return (
                <div key={d.id} style={{
                  display: 'grid',
                  gridTemplateColumns: '24px 1fr 100px 90px 60px 60px',
                  gap: 16, alignItems: 'center',
                  padding: '14px 0', borderBottom: '1px solid var(--border)',
                }}>
                  <FileIcon kind={f.kind} size={20} />
                  <div>
                    <div style={{ fontSize: 13 }}>{f.title || f.name}</div>
                    <div className="mono" style={{ fontSize: 10, color: 'var(--text-tertiary)', marginTop: 4 }}>
                      {d.opens} {d.opens === 1 ? 'open' : 'opens'}
                    </div>
                  </div>
                  <div>
                    <div className="mono" style={{ fontSize: 10, color: 'var(--text-tertiary)', letterSpacing: '0.08em', marginBottom: 4 }}>SCROLL</div>
                    <div style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
                      <div className="bar bar-gold" style={{ flex: 1 }}>
                        <i style={{ width: `${d.scroll}%` }} />
                      </div>
                      <span className="mono" style={{ fontSize: 10, width: 26, textAlign: 'right' }}>{d.scroll}%</span>
                    </div>
                  </div>
                  <span className="mono" style={{ fontSize: 11, color: 'var(--text-secondary)', textAlign: 'right' }}>{fmtSec(d.time)}</span>
                  <span className="mono" style={{ fontSize: 11, color: d.downloaded ? 'var(--success)' : 'var(--text-tertiary)', textAlign: 'right' }}>
                    {d.downloaded ? '↓ YES' : '—'}
                  </span>
                  <span className="mono" style={{ fontSize: 11, color: d.opens > 0 ? 'var(--text-secondary)' : 'var(--text-tertiary)', textAlign: 'right' }}>
                    {d.opens > 0 ? '✓' : '○'}
                  </span>
                </div>
              );
            })}
          </div>

          <div style={{ marginTop: 32 }}>
            <SectionNum n={2} label="SESSION_TIMELINE" />
            <div style={{ marginTop: 16 }}>
              <div style={{ display: 'flex', alignItems: 'flex-end', gap: 3, height: 60, marginBottom: 6 }}>
                {investor.activity.map((v, i) => (
                  <div key={i} style={{
                    flex: 1, height: `${v * 18 + (v > 0 ? 4 : 0)}px`,
                    background: v > 0 ? 'var(--gold)' : 'var(--border)',
                    minHeight: 2,
                  }} />
                ))}
              </div>
              <div style={{ display: 'flex', justifyContent: 'space-between', fontFamily: 'var(--font-mono)', fontSize: 9, color: 'var(--text-tertiary)', letterSpacing: '0.08em' }}>
                <span>24H AGO</span><span>18H</span><span>12H</span><span>6H</span><span>NOW</span>
              </div>
            </div>
          </div>
        </Brackets>

        {/* Profile sidecar */}
        <div>
          <Brackets style={{ padding: 20, border: '1px solid var(--border)', background: 'var(--bg-card)', marginBottom: 16 }}>
            <div className="mono" style={{ fontSize: 9, letterSpacing: '0.14em', color: 'var(--text-tertiary)', marginBottom: 16 }}>ONBOARDING_ANSWERS</div>
            <ProfileRow label="PROFILE" value={investor.profile} />
            <ProfileRow label="ALLOCATION" value={investor.allocation} />
            <ProfileRow label="TIMELINE" value={investor.timeline} />
            <ProfileRow label="INVITED" value={`${investor.invitedDays}d ago`} last />
          </Brackets>

          <Brackets style={{ padding: 20, border: '1px solid var(--border)', background: 'var(--bg-card)' }}>
            <div className="mono" style={{ fontSize: 9, letterSpacing: '0.14em', color: 'var(--text-tertiary)', marginBottom: 12 }}>SUGGESTED_ACTION</div>
            <div style={{ fontSize: 13, lineHeight: 1.6, color: 'var(--text-secondary)', marginBottom: 16 }}>
              {investor.score >= 80
                ? `Hot — ${investor.name.split(' ')[0]} has reviewed all key docs. Reach out to schedule diligence.`
                : investor.score >= 50
                ? `Warm — partial review. Follow up with a specific question about their stated focus.`
                : `Cold — minimal engagement. Consider a re-engagement email or ping.`}
            </div>
            <button className="btn btn-sm btn-gold" style={{ width: '100%' }}>
              ↗ {investor.score >= 80 ? 'Schedule diligence' : investor.score >= 50 ? 'Send follow-up' : 'Re-engage'}
            </button>
          </Brackets>
        </div>
      </div>
    </div>
  );
}

function ProfileRow({ label, value, last }) {
  return (
    <div style={{ padding: '10px 0', borderBottom: last ? 'none' : '1px solid var(--border)' }}>
      <div className="mono" style={{ fontSize: 9, letterSpacing: '0.14em', color: 'var(--text-tertiary)', marginBottom: 4 }}>{label}</div>
      <div style={{ fontSize: 13 }}>{value}</div>
    </div>
  );
}

function DocsAnalytics() {
  return (
    <div>
      <div className="section-num" style={{ marginBottom: 12 }}>
        <span>[ ADMIN_VIEW ]</span><span className="div" /><span>DOCUMENTS</span>
      </div>
      <h1 style={{ fontSize: 34, letterSpacing: '-0.025em', fontWeight: 400, margin: '0 0 24px' }}>Documents</h1>

      <Brackets style={{ background: 'var(--bg-card)', border: '1px solid var(--border)' }}>
        <table className="tbl">
          <thead>
            <tr>
              <th></th>
              <th>Document</th>
              <th>Section</th>
              <th>Total opens</th>
              <th>Avg time</th>
              <th>Avg scroll</th>
              <th>Downloads</th>
              <th>Reach</th>
            </tr>
          </thead>
          <tbody>
            {ROOM_FILES.map(f => {
              const opens = FAKE_INVESTORS.reduce((s, i) => s + (i.docs.find(d => d.id === f.id)?.opens || 0), 0);
              const totalTime = FAKE_INVESTORS.reduce((s, i) => s + (i.docs.find(d => d.id === f.id)?.time || 0), 0);
              const avgTime = opens ? Math.round(totalTime / opens) : 0;
              const scrollSum = FAKE_INVESTORS.reduce((s, i) => s + (i.docs.find(d => d.id === f.id)?.scroll || 0), 0);
              const reach = FAKE_INVESTORS.filter(i => (i.docs.find(d => d.id === f.id)?.opens || 0) > 0).length;
              const avgScroll = reach ? Math.round(scrollSum / FAKE_INVESTORS.length) : 0;
              const dl = FAKE_INVESTORS.reduce((s, i) => s + (i.docs.find(d => d.id === f.id)?.downloaded ? 1 : 0), 0);
              return (
                <tr key={f.id}>
                  <td><FileIcon kind={f.kind} size={20} /></td>
                  <td style={{ fontSize: 13 }}>{f.title || f.name}</td>
                  <td><span className="mono" style={{ fontSize: 10, color: 'var(--text-tertiary)' }}>{f.section}</span></td>
                  <td><span className="mono" style={{ fontSize: 11 }}>{opens}</span></td>
                  <td><span className="mono" style={{ fontSize: 11 }}>{fmtSec(avgTime)}</span></td>
                  <td>
                    <div style={{ display: 'flex', alignItems: 'center', gap: 6, width: 120 }}>
                      <div className="bar bar-gold" style={{ flex: 1 }}><i style={{ width: `${avgScroll}%` }} /></div>
                      <span className="mono" style={{ fontSize: 10, width: 28, textAlign: 'right' }}>{avgScroll}%</span>
                    </div>
                  </td>
                  <td><span className="mono" style={{ fontSize: 11, color: dl ? 'var(--success)' : 'var(--text-tertiary)' }}>{dl}</span></td>
                  <td><span className="mono" style={{ fontSize: 11 }}>{reach}/{FAKE_INVESTORS.length}</span></td>
                </tr>
              );
            })}
          </tbody>
        </table>
      </Brackets>
    </div>
  );
}

function ActivityLog() {
  const events = [
    { who: 'Marcus Reed', firm: 'BWFO', what: 'opened', target: 'Returns Model & Sensitivities.xlsx', when: '14m ago', icon: '○' },
    { who: 'Marcus Reed', firm: 'BWFO', what: 'downloaded', target: 'Term Sheet — Series Seed.docx', when: '22m ago', icon: '↓' },
    { who: 'Jane Catalano', firm: 'Latticework', what: 'finished reading', target: 'Vault Architecture Memo.html', when: '2h ago', icon: '✓' },
    { who: 'Ravi Anand', firm: 'Self', what: 'opened', target: 'Investor Deck.pdf', when: '5h ago', icon: '○' },
    { who: 'Ravi Anand', firm: 'Self', what: 'scrolled to 60%', target: 'Returns Model & Sensitivities.xlsx', when: '5h ago', icon: '▼' },
    { who: 'Yuki Tanaka', firm: 'Octant DAO', what: 'opened', target: 'ArbVault.sol', when: '8h ago', icon: '○' },
    { who: 'Sara Lindqvist', firm: 'NSC', what: 'opened', target: 'Investor Deck.pdf', when: '1d ago', icon: '○' },
    { who: 'Marcus Reed', firm: 'BWFO', what: 'invited', target: '+ accepted invite', when: '1d ago', icon: '+' },
    { who: 'Eli Brooks', firm: 'Veridian', what: 'opened', target: 'Investor Deck.pdf', when: '6d ago', icon: '○' },
  ];
  return (
    <div>
      <div className="section-num" style={{ marginBottom: 12 }}>
        <span>[ ADMIN_VIEW ]</span><span className="div" /><span>ACTIVITY_LOG</span>
      </div>
      <h1 style={{ fontSize: 34, letterSpacing: '-0.025em', fontWeight: 400, margin: '0 0 24px' }}>Activity</h1>
      <Brackets style={{ background: 'var(--bg-card)', border: '1px solid var(--border)', padding: 0 }}>
        {events.map((e, i) => (
          <div key={i} style={{
            display: 'grid', gridTemplateColumns: '40px 1fr 100px',
            gap: 16, alignItems: 'center',
            padding: '16px 24px',
            borderBottom: i === events.length - 1 ? 'none' : '1px solid var(--border)',
          }}>
            <div style={{
              width: 28, height: 28, border: '1px solid var(--border)',
              display: 'flex', alignItems: 'center', justifyContent: 'center',
              fontFamily: 'var(--font-mono)', color: 'var(--gold-dark)',
            }}>{e.icon}</div>
            <div>
              <div style={{ fontSize: 13 }}>
                <strong style={{ fontWeight: 500 }}>{e.who}</strong>
                <span style={{ color: 'var(--text-tertiary)' }}> ({e.firm}) </span>
                <span style={{ color: 'var(--text-secondary)' }}>{e.what}</span>
                <span> {e.target}</span>
              </div>
            </div>
            <span className="mono" style={{ fontSize: 10, color: 'var(--text-tertiary)', textAlign: 'right' }}>{e.when}</span>
          </div>
        ))}
      </Brackets>
    </div>
  );
}

// ── Invites: live API-backed admin tab ────────────────────
const ADMIN_KEY_STORAGE = 'arbcap_admin_key';

function getAdminKey() {
  try { return localStorage.getItem(ADMIN_KEY_STORAGE) || ''; } catch (e) { return ''; }
}
function saveAdminKey(k) {
  try { localStorage.setItem(ADMIN_KEY_STORAGE, k); } catch (e) {}
}
function clearAdminKey() {
  try { localStorage.removeItem(ADMIN_KEY_STORAGE); } catch (e) {}
}

function relTime(iso) {
  if (!iso) return '—';
  const ms = Date.now() - new Date(iso).getTime();
  if (ms < 0 || isNaN(ms)) return '—';
  const s = Math.floor(ms / 1000);
  if (s < 60) return 'just now';
  const m = Math.floor(s / 60);
  if (m < 60) return `${m}m ago`;
  const h = Math.floor(m / 60);
  if (h < 24) return `${h}h ago`;
  const d = Math.floor(h / 24);
  if (d < 30) return `${d}d ago`;
  return new Date(iso).toISOString().slice(0, 10);
}

async function adminFetch(path, opts = {}) {
  const adminKey = getAdminKey();
  const headers = Object.assign({}, opts.headers || {}, { 'x-admin-key': adminKey });
  if (opts.body && !headers['Content-Type']) headers['Content-Type'] = 'application/json';
  const res = await fetch(path, Object.assign({}, opts, { headers, credentials: 'include' }));
  if (res.status === 401) {
    const e = new Error('admin_unauthorized');
    e.code = 401;
    throw e;
  }
  return res;
}

function InvitesTab() {
  const [list, setList] = React.useState([]);
  const [loading, setLoading] = React.useState(true);
  const [error, setError] = React.useState(null);
  const [keyPromptOpen, setKeyPromptOpen] = React.useState(!getAdminKey());
  const [keyDraft, setKeyDraft] = React.useState('');

  const [draftEmail, setDraftEmail] = React.useState('');
  const [draftName, setDraftName] = React.useState('');
  const [draftFirm, setDraftFirm] = React.useState('');
  const [busy, setBusy] = React.useState(false);
  const [lastCreated, setLastCreated] = React.useState(null);
  const [copied, setCopied] = React.useState(false);

  const valid = /^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(draftEmail);

  const refresh = React.useCallback(async () => {
    if (!getAdminKey()) { setKeyPromptOpen(true); setLoading(false); return; }
    setLoading(true);
    setError(null);
    try {
      const r = await adminFetch('/api/invite/list');
      if (!r.ok) {
        setError(`HTTP ${r.status}`); setLoading(false); return;
      }
      const data = await r.json();
      setList(data.invites || []);
    } catch (e) {
      if (e.code === 401) { clearAdminKey(); setKeyPromptOpen(true); }
      else setError(e.message);
    } finally {
      setLoading(false);
    }
  }, []);

  React.useEffect(() => { refresh(); }, [refresh]);

  const unlockAdmin = async () => {
    if (!keyDraft.trim()) return;
    saveAdminKey(keyDraft.trim());
    setKeyPromptOpen(false);
    setKeyDraft('');
    await refresh();
  };

  const create = async () => {
    if (!valid || busy) return;
    setBusy(true); setError(null);
    try {
      const r = await adminFetch('/api/invite/create', {
        method: 'POST',
        body: JSON.stringify({ email: draftEmail, name: draftName, firm: draftFirm }),
      });
      const data = await r.json();
      if (!r.ok) { setError(data.error || `HTTP ${r.status}`); return; }
      setLastCreated({ ...data.invite, url: data.url });
      setDraftEmail(''); setDraftName(''); setDraftFirm('');
      await refresh();
    } catch (e) {
      if (e.code === 401) { clearAdminKey(); setKeyPromptOpen(true); }
      else setError(e.message);
    } finally {
      setBusy(false);
    }
  };

  const copyUrl = (url) => {
    if (!url || typeof navigator === 'undefined' || !navigator.clipboard) return;
    navigator.clipboard.writeText(url).catch(() => {});
    setCopied(true);
    setTimeout(() => setCopied(false), 1400);
  };

  const revoke = async (id) => {
    if (!confirm('Revoke this invite? Active sessions on this link will be kicked.')) return;
    try {
      await adminFetch('/api/invite/revoke', { method: 'POST', body: JSON.stringify({ id }) });
      await refresh();
    } catch (e) {
      if (e.code === 401) { clearAdminKey(); setKeyPromptOpen(true); }
      else setError(e.message);
    }
  };

  if (keyPromptOpen) {
    return (
      <div>
        <div className="section-num" style={{ marginBottom: 12 }}>
          <span>[ ADMIN_VIEW ]</span><span className="div" /><span>UNLOCK</span>
        </div>
        <h1 style={{ fontSize: 34, letterSpacing: '-0.025em', fontWeight: 400, margin: '0 0 4px' }}>Admin key required</h1>
        <p style={{ fontSize: 14, color: 'var(--text-secondary)', marginBottom: 24 }}>
          Paste the <span className="mono">ADMIN_KEY</span> from your environment. Stored in this browser only.
        </p>
        <Brackets style={{ padding: 24, border: '1px solid var(--border)', background: 'var(--bg-card)', maxWidth: 540 }}>
          <input className="input mono" type="password" placeholder="paste admin key…"
            value={keyDraft} onChange={e => setKeyDraft(e.target.value)}
            onKeyDown={e => e.key === 'Enter' && unlockAdmin()}
            autoFocus />
          <div style={{ display: 'flex', gap: 8, marginTop: 16 }}>
            <button className="btn btn-filled" onClick={unlockAdmin} disabled={!keyDraft.trim()}
              style={{ opacity: keyDraft.trim() ? 1 : 0.4 }}>Unlock</button>
          </div>
        </Brackets>
      </div>
    );
  }

  return (
    <div>
      <div className="section-num" style={{ marginBottom: 12 }}>
        <span>[ ADMIN_VIEW ]</span><span className="div" /><span>INVITES</span>
      </div>
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', marginBottom: 24 }}>
        <div>
          <h1 style={{ fontSize: 34, letterSpacing: '-0.025em', fontWeight: 400, margin: '0 0 4px' }}>Invites</h1>
          <p style={{ fontSize: 14, color: 'var(--text-secondary)', margin: 0 }}>
            Each link is bound to one email. Drop in a cold email or share after a first call.
          </p>
        </div>
      </div>

      {/* Create */}
      <Brackets style={{ padding: 24, border: '1px solid var(--border)', background: 'var(--bg-card)', marginBottom: 24 }}>
        <SectionNum n={1} label="CREATE_INVITE" />
        <div style={{ display: 'grid', gridTemplateColumns: '1.2fr 1fr 1fr auto', gap: 12, alignItems: 'flex-end', marginTop: 16 }}>
          <div>
            <div className="mono" style={{ fontSize: 10, letterSpacing: '0.12em', color: 'var(--text-tertiary)', marginBottom: 8 }}>EMAIL <span style={{ color: 'var(--gold-dark)' }}>*</span></div>
            <input className="input" style={{ height: 36, fontSize: 13 }} type="email" placeholder="jane@firm.com"
              value={draftEmail} onChange={e => setDraftEmail(e.target.value)} />
          </div>
          <div>
            <div className="mono" style={{ fontSize: 10, letterSpacing: '0.12em', color: 'var(--text-tertiary)', marginBottom: 8 }}>NAME</div>
            <input className="input" style={{ height: 36, fontSize: 13 }} placeholder="Jane Catalano"
              value={draftName} onChange={e => setDraftName(e.target.value)} />
          </div>
          <div>
            <div className="mono" style={{ fontSize: 10, letterSpacing: '0.12em', color: 'var(--text-tertiary)', marginBottom: 8 }}>FIRM</div>
            <input className="input" style={{ height: 36, fontSize: 13 }} placeholder="Latticework Capital"
              value={draftFirm} onChange={e => setDraftFirm(e.target.value)} />
          </div>
          <button className="btn btn-filled" disabled={!valid || busy} style={{ opacity: (valid && !busy) ? 1 : 0.4, height: 36 }}
            onClick={create}>{busy ? '…' : '+ Generate link'}</button>
        </div>

        {error && (
          <div style={{ marginTop: 14, padding: 10, border: '1px solid var(--error)', color: 'var(--error)', fontFamily: 'var(--font-mono)', fontSize: 11 }}>
            {error}
          </div>
        )}

        {lastCreated && (
          <div style={{ marginTop: 18, padding: 14, border: '1px solid var(--border)', background: 'var(--bg)' }}>
            <div className="mono" style={{ fontSize: 9, letterSpacing: '0.14em', color: 'var(--success)', marginBottom: 8 }}>✓ LINK_READY — copy now (the URL is only shown at issuance)</div>
            <div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
              <input className="input mono" readOnly value={lastCreated.url}
                style={{ height: 32, fontSize: 11, flex: 1, background: 'var(--bg-card)' }}
                onFocus={e => e.target.select()} />
              <button className="btn btn-sm" onClick={() => copyUrl(lastCreated.url)}>
                {copied ? '✓ Copied' : '⎘ Copy'}
              </button>
            </div>
            <div className="mono" style={{ fontSize: 10, color: 'var(--text-tertiary)', letterSpacing: '0.06em', marginTop: 10 }}>
              Bound to <span style={{ color: 'var(--text-secondary)' }}>{lastCreated.email}</span> · expires {relTime(lastCreated.expires_at)} · re-issue from this form to share again
            </div>
          </div>
        )}
      </Brackets>

      {/* List */}
      <Brackets style={{ background: 'var(--bg-card)', border: '1px solid var(--border)' }}>
        {loading ? (
          <div style={{ padding: 40, textAlign: 'center', color: 'var(--text-tertiary)', fontFamily: 'var(--font-mono)', fontSize: 11, letterSpacing: '0.12em' }}>
            LOADING…
          </div>
        ) : list.length === 0 ? (
          <div style={{ padding: 40, textAlign: 'center', color: 'var(--text-tertiary)', fontSize: 13 }}>
            No invites yet. Mint one above.
          </div>
        ) : (
          <table className="tbl">
            <thead>
              <tr>
                <th style={{ width: 30 }}></th>
                <th>Recipient</th>
                <th>Firm</th>
                <th>Created</th>
                <th>Opens</th>
                <th>Last seen</th>
                <th>Status</th>
                <th></th>
              </tr>
            </thead>
            <tbody>
              {list.map((r, i) => (
                <tr key={r.id}>
                  <td><span className="mono" style={{ fontSize: 9, color: 'var(--text-tertiary)' }}>{String(i+1).padStart(2,'0')}</span></td>
                  <td>
                    <div style={{ fontSize: 13 }}>{r.name || r.email.split('@')[0]}</div>
                    <div className="mono" style={{ fontSize: 10, color: 'var(--text-tertiary)', marginTop: 2 }}>{r.email}</div>
                  </td>
                  <td><span className="mono" style={{ fontSize: 11, color: 'var(--text-secondary)' }}>{r.firm || '—'}</span></td>
                  <td><span className="mono" style={{ fontSize: 11, color: 'var(--text-tertiary)' }}>{relTime(r.created_at)}</span></td>
                  <td><span className="mono" style={{ fontSize: 11 }}>{r.opens || 0}</span></td>
                  <td><span className="mono" style={{ fontSize: 11, color: 'var(--text-tertiary)' }}>{relTime(r.last_seen)}</span></td>
                  <td>
                    <span className={`badge b-${r.status === 'ENTERED' ? 'success' : r.status === 'REVOKED' ? 'error' : r.status === 'PENDING' ? 'gold' : 'default'}`}>
                      {r.status}
                    </span>
                  </td>
                  <td style={{ whiteSpace: 'nowrap' }}>
                    <button className="btn btn-ghost btn-sm" style={{ padding: '0 8px', color: 'var(--text-tertiary)' }}
                      title="Revoke this invite link"
                      onClick={() => revoke(r.id)} disabled={r.status === 'REVOKED'}>×</button>
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        )}
      </Brackets>
    </div>
  );
}

Object.assign(window, { Admin, FAKE_INVESTORS, fmtSec });
