// MCP Hero — Admin portal (separate standalone app feel: dark sidebar, denser)
const { useState: useAdmState, useMemo: useAdmMemo } = React;

// ---------- tiny charts ----------
function BarChart({ data, height = 120, color = 'var(--accent)' }) {
  const max = Math.max(...data);
  return (
    <div style={{ display: 'flex', alignItems: 'flex-end', gap: 4, height }}>
      {data.map((v, i) => (
        <div key={i} title={String(v)} style={{
          flex: 1, borderRadius: '4px 4px 2px 2px', minHeight: 3,
          height: (v / max * 100) + '%',
          background: i === data.length - 1 ? color : 'color-mix(in oklch, ' + color + ' 38%, var(--bg-sunken))',
          transition: 'height .4s ease',
        }}></div>
      ))}
    </div>
  );
}

function LineChart({ data, height = 120, color = 'var(--accent)' }) {
  const max = Math.max(...data), min = Math.min(...data);
  const W = 100, H = 100;
  const pts = data.map((v, i) => `${(i / (data.length - 1)) * W},${H - ((v - min) / (max - min || 1)) * (H - 8) - 4}`);
  return (
    <svg viewBox={`0 0 ${W} ${H}`} preserveAspectRatio="none" style={{ width: '100%', height, display: 'block' }}>
      <polyline points={pts.join(' ')} fill="none" stroke={color} strokeWidth="2" vectorEffect="non-scaling-stroke" strokeLinejoin="round" strokeLinecap="round"></polyline>
      <polygon points={`0,${H} ${pts.join(' ')} ${W},${H}`} fill={`color-mix(in oklch, ${color} 14%, transparent)`}></polygon>
    </svg>
  );
}

function SplitBars({ items, color = 'var(--accent)' }) {
  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
      {items.map((s) => (
        <div key={s.name}>
          <div style={{ display: 'flex', justifyContent: 'space-between', fontSize: 12.5, fontWeight: 600, marginBottom: 4 }}>
            <span>{s.name}</span><span style={{ color: 'var(--text-3)' }}>{s.pct}%</span>
          </div>
          <div style={{ height: 7, borderRadius: 4, background: 'var(--bg-sunken)', overflow: 'hidden' }}>
            <div style={{ width: s.pct + '%', height: '100%', borderRadius: 4, background: color }}></div>
          </div>
        </div>
      ))}
    </div>
  );
}

function McpStatusBadge({ status }) {
  return status === 'active' ? <Badge tone="ok">Active</Badge> : status === 'draft' ? <Badge tone="warn">Draft</Badge> : <Badge tone="danger">Disabled</Badge>;
}

// ---------- Admin overview ----------
function AdminDash({ nav }) {
  const S = MH_ADMIN_STATS;
  return (
    <div className="mh-anim">
      <SectionHead title="Platform overview" sub="Tuesday, 10 June 2026"></SectionHead>
      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(200px, 1fr))', gap: 14, marginBottom: 22 }}>
        <StatCard label="Revenue · June" icon="wallet" value={'RM ' + S.mrr.toLocaleString()} sub={S.mrrDelta + ' vs May'} tone="accent"></StatCard>
        <StatCard label="Credits sold" icon="coin" value={S.creditsSold.toLocaleString()} sub={S.creditsSoldDelta + ' vs May'}></StatCard>
        <StatCard label="Active users" icon="users" value={S.activeUsers.toLocaleString()} sub={S.activeUsersDelta + ' vs May'}></StatCard>
        <StatCard label="Calls today" icon="zap" value={S.callsToday.toLocaleString()} sub={S.callsTodayDelta + ' vs yesterday'}></StatCard>
      </div>
      <div style={{ display: 'grid', gridTemplateColumns: 'minmax(0, 1.6fr) minmax(280px, 1fr)', gap: 18, alignItems: 'flex-start' }}>
        <Card style={{ padding: 22 }}>
          <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 16 }}>
            <span style={{ fontWeight: 700, fontFamily: 'var(--font-display)', fontSize: 15.5 }}>Gateway calls · last 30 days</span>
            <Badge tone="accent">1,601 today</Badge>
          </div>
          <BarChart data={S.callsByDay} height={150}></BarChart>
        </Card>
        <Card style={{ padding: 22 }}>
          <div style={{ fontWeight: 700, fontFamily: 'var(--font-display)', fontSize: 15.5, marginBottom: 14 }}>Top MCPs today</div>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
            {[...MH_MCPS].filter((m) => m.status === 'active').sort((a, b) => b.callsToday - a.callsToday).slice(0, 5).map((m) => (
              <div key={m.slug} style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
                <McpIcon mcp={m} size={28}></McpIcon>
                <span style={{ flex: 1, fontSize: 13.5, fontWeight: 600, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{m.name}</span>
                <span style={{ fontSize: 13, fontWeight: 700, color: 'var(--text-2)' }}>{m.callsToday}</span>
              </div>
            ))}
          </div>
          <Btn variant="ghost" size="sm" style={{ marginTop: 14 }} onClick={() => nav('/admin/analytics')}>Full analytics</Btn>
        </Card>
      </div>
    </div>
  );
}

// ---------- Admin MCP list ----------
function AdminMcps({ nav }) {
  const [q, setQ] = useAdmState('');
  const rows = MH_MCPS.filter((m) => !q || m.name.toLowerCase().includes(q.toLowerCase()));
  return (
    <div className="mh-anim">
      <SectionHead title="MCPs" sub={MH_MCPS.length + ' registered · ' + MH_MCPS.filter((m) => m.status === 'active').length + ' live on marketplace'}
        right={<Btn icon="plus" onClick={() => nav('/admin/mcps/new')}>Add MCP</Btn>}></SectionHead>
      <div style={{ marginBottom: 14, maxWidth: 360 }}>
        <TextInput value={q} onChange={setQ} placeholder="Search MCPs…"></TextInput>
      </div>
      <Table cols={[{ label: 'MCP' }, { label: 'Category' }, { label: 'Status' }, { label: 'Installs', align: 'right' }, { label: 'Revenue (cr)', align: 'right' }, { label: 'Calls today', align: 'right' }, { label: '', align: 'right' }]}>
        {rows.map((m) => (
          <Tr key={m.slug} onClick={() => nav('/admin/mcps/' + m.slug)}>
            <Td><span style={{ display: 'inline-flex', alignItems: 'center', gap: 10, fontWeight: 700, color: 'var(--text)' }}><McpIcon mcp={m} size={28}></McpIcon>{m.name}</span></Td>
            <Td><CategoryTag cat={m.category}></CategoryTag></Td>
            <Td><McpStatusBadge status={m.status}></McpStatusBadge></Td>
            <Td align="right">{m.installs.toLocaleString()}</Td>
            <Td align="right" style={{ fontWeight: 700, color: 'var(--text)' }}>{m.revenue.toLocaleString()}</Td>
            <Td align="right">{m.callsToday}</Td>
            <Td align="right"><Icon name="chevronRight" size={15} style={{ color: 'var(--text-3)' }}></Icon></Td>
          </Tr>
        ))}
      </Table>
    </div>
  );
}

// ---------- Admin MCP edit / create ----------
function AdminMcpEdit({ slug, nav }) {
  const existing = slug !== 'new' ? mhGetMcp(slug) : null;
  const toast = useToast();
  const [form, setForm] = useAdmState(existing ? {
    name: existing.name, slug: existing.slug, desc: existing.description, cat: existing.category,
    url: 'http://10.2.0.14:8821/mcp', status: existing.status,
    tools: existing.tools.map((t) => ({ ...t })),
  } : { name: '', slug: '', desc: '', cat: 'business-data', url: '', status: 'draft', tools: [{ name: '', desc: '', credits: 0 }] });
  const set = (k, v) => setForm((f) => ({ ...f, [k]: v }));
  const setTool = (i, k, v) => setForm((f) => ({ ...f, tools: f.tools.map((t, j) => j === i ? { ...t, [k]: v } : t) }));
  return (
    <div className="mh-anim" style={{ maxWidth: 860 }}>
      <button onClick={() => nav('/admin/mcps')} style={{ display: 'inline-flex', alignItems: 'center', gap: 6, border: 'none', background: 'transparent', cursor: 'pointer', color: 'var(--text-3)', fontSize: 13, fontWeight: 600, padding: 0, marginBottom: 16 }}>
        <Icon name="arrowLeft" size={14}></Icon> All MCPs
      </button>
      <SectionHead title={existing ? 'Edit · ' + existing.name : 'Add MCP'}
        sub={existing ? 'Changes to pricing take effect on the next tool call.' : 'New MCPs start as drafts — publish when ready.'}
        right={
          <div style={{ display: 'flex', gap: 9, alignItems: 'center' }}>
            <McpStatusBadge status={form.status}></McpStatusBadge>
            {form.status === 'draft' ? <Btn icon="zap" onClick={() => { set('status', 'active'); toast('Published to marketplace'); }}>Publish</Btn> : null}
            {form.status === 'active' ? <Btn variant="danger" icon="pause" onClick={() => { set('status', 'disabled'); toast('MCP taken offline — gateway now returns MCP_UNAVAILABLE', 'danger'); }}>Disable</Btn> : null}
            {form.status === 'disabled' ? <Btn icon="play" onClick={() => { set('status', 'active'); toast('MCP re-enabled'); }}>Re-enable</Btn> : null}
          </div>
        }></SectionHead>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 18 }}>
        <Card style={{ padding: 22 }}>
          <div style={{ fontWeight: 700, fontFamily: 'var(--font-display)', fontSize: 15, marginBottom: 16 }}>Listing details</div>
          <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 15 }}>
            <Field label="Name"><TextInput value={form.name} onChange={(v) => set('name', v)} placeholder="SSM Company Profile"></TextInput></Field>
            <Field label="Slug" hint={'Gateway: ' + MH_GATEWAY_URL + (form.slug || '…')}><TextInput mono value={form.slug} onChange={(v) => set('slug', v)} placeholder="ssm"></TextInput></Field>
            <Field label="Category" style={{ gridColumn: '1' }}>
              <Select value={form.cat} onChange={(v) => set('cat', v)} options={MH_CATEGORIES.filter((c) => c.id !== 'all').map((c) => ({ value: c.id, label: c.label }))}></Select>
            </Field>
            <Field label="Backend server URL" hint="Internal network — validated on save"><TextInput mono value={form.url} onChange={(v) => set('url', v)} placeholder="http://10.0.0.5:8821/mcp"></TextInput></Field>
          </div>
          <Field label="Description" style={{ marginTop: 15 }}>
            <textarea value={form.desc} onChange={(e) => set('desc', e.target.value)} rows={3} style={{
              padding: '10px 13px', fontSize: 14, borderRadius: 9, border: '1.5px solid var(--border-strong)',
              background: 'var(--bg-raised)', color: 'var(--text)', outline: 'none', resize: 'vertical', width: '100%', lineHeight: 1.5,
            }}></textarea>
          </Field>
        </Card>
        <Card style={{ padding: 22 }}>
          <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 6 }}>
            <div style={{ fontWeight: 700, fontFamily: 'var(--font-display)', fontSize: 15 }}>Tools &amp; per-call pricing</div>
            <Btn variant="secondary" size="sm" icon="plus" onClick={() => setForm((f) => ({ ...f, tools: [...f.tools, { name: '', desc: '', credits: 0 }] }))}>Add tool</Btn>
          </div>
          <p style={{ margin: '0 0 16px', fontSize: 12.5, color: 'var(--text-3)' }}>Set cost to 0 to make a tool free — free tools skip the credit check entirely.</p>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
            {form.tools.map((t, i) => (
              <div key={i} style={{ display: 'grid', gridTemplateColumns: 'minmax(140px, 1fr) minmax(180px, 2fr) 110px 34px', gap: 10, alignItems: 'center' }}>
                <TextInput mono value={t.name} onChange={(v) => setTool(i, 'name', v)} placeholder="tool_name" style={{ fontSize: 12.5 }}></TextInput>
                <TextInput value={t.desc} onChange={(v) => setTool(i, 'desc', v)} placeholder="What it does" style={{ fontSize: 13 }}></TextInput>
                <div style={{ position: 'relative' }}>
                  <TextInput type="number" value={t.credits} onChange={(v) => setTool(i, 'credits', Math.max(0, parseInt(v || 0)))} style={{ paddingRight: 36, fontSize: 13 }}></TextInput>
                  <span style={{ position: 'absolute', right: 11, top: '50%', transform: 'translateY(-50%)', fontSize: 11.5, color: 'var(--text-3)', fontWeight: 700 }}>cr</span>
                </div>
                <button onClick={() => setForm((f) => ({ ...f, tools: f.tools.filter((_, j) => j !== i) }))} style={{ border: 'none', background: 'transparent', cursor: 'pointer', color: 'var(--text-3)', padding: 6 }} title="Remove tool">
                  <Icon name="trash" size={15}></Icon>
                </button>
              </div>
            ))}
          </div>
        </Card>
        <div style={{ display: 'flex', gap: 10 }}>
          <Btn size="lg" icon="check" onClick={() => { toast('MCP saved'); nav('/admin/mcps'); }}>Save changes</Btn>
          <Btn variant="secondary" size="lg" onClick={() => nav('/admin/mcps')}>Cancel</Btn>
          {existing && form.status === 'draft' ? <Btn variant="danger" size="lg" icon="trash" style={{ marginLeft: 'auto' }} onClick={() => { toast('Draft deleted', 'danger'); nav('/admin/mcps'); }}>Delete draft</Btn> : null}
        </div>
      </div>
    </div>
  );
}

// ---------- Admin users ----------
function AdminUsers({ nav }) {
  const [q, setQ] = useAdmState('');
  const [type, setType] = useAdmState('all');
  const [status, setStatus] = useAdmState('all');
  const rows = MH_ADMIN_USERS
    .filter((u) => type === 'all' || u.type === type)
    .filter((u) => status === 'all' || u.status === status)
    .filter((u) => !q || (u.name + u.email).toLowerCase().includes(q.toLowerCase()));
  return (
    <div className="mh-anim">
      <SectionHead title="Users" sub={MH_ADMIN_USERS.length + ' accounts · ' + MH_ADMIN_USERS.filter((u) => u.type === 'org').length + ' organizations'}></SectionHead>
      <div style={{ display: 'flex', gap: 10, marginBottom: 14, flexWrap: 'wrap', alignItems: 'center' }}>
        <div style={{ width: 280 }}><TextInput value={q} onChange={setQ} placeholder="Search by name or email…"></TextInput></div>
        <Segmented size="sm" value={type} onChange={setType} options={[{ value: 'all', label: 'All types' }, { value: 'personal', label: 'Personal' }, { value: 'org', label: 'Organization' }]}></Segmented>
        <Segmented size="sm" value={status} onChange={setStatus} options={[{ value: 'all', label: 'Any status' }, { value: 'active', label: 'Active' }, { value: 'suspended', label: 'Suspended' }]}></Segmented>
      </div>
      <Table cols={[{ label: 'Account' }, { label: 'Type' }, { label: 'Registered' }, { label: 'Balance', align: 'right' }, { label: 'Status' }, { label: '', align: 'right' }]}>
        {rows.map((u, i) => (
          <Tr key={i} onClick={() => nav('/admin/users/' + i)}>
            <Td>
              <span style={{ display: 'inline-flex', alignItems: 'center', gap: 10 }}>
                <Avatar initials={u.name.split(' ').map((w) => w[0]).slice(0, 2).join('').toUpperCase()} size={30} hue={(u.name.length * 53) % 360}></Avatar>
                <span>
                  <span style={{ display: 'block', fontWeight: 700, color: 'var(--text)' }}>{u.name}</span>
                  <span style={{ display: 'block', fontSize: 12, color: 'var(--text-3)' }}>{u.email}</span>
                </span>
              </span>
            </Td>
            <Td>{u.type === 'org' ? <Badge tone="accent">Org · {u.members}</Badge> : <Badge>Personal</Badge>}</Td>
            <Td style={{ whiteSpace: 'nowrap' }}>{u.registered}</Td>
            <Td align="right" style={{ fontWeight: 700, color: u.balance === 0 ? 'var(--text-3)' : 'var(--text)' }}>{u.balance.toLocaleString()} cr</Td>
            <Td>{u.status === 'active' ? <Badge tone="ok">Active</Badge> : <Badge tone="danger">Suspended</Badge>}</Td>
            <Td align="right"><Icon name="chevronRight" size={15} style={{ color: 'var(--text-3)' }}></Icon></Td>
          </Tr>
        ))}
      </Table>
    </div>
  );
}

// ---------- Admin user detail ----------
function AdminUserDetail({ idx, nav }) {
  const u = MH_ADMIN_USERS[parseInt(idx)] || MH_ADMIN_USERS[0];
  const toast = useToast();
  const [adjustOpen, setAdjustOpen] = useAdmState(false);
  const [suspendOpen, setSuspendOpen] = useAdmState(false);
  const [amount, setAmount] = useAdmState('');
  const [reason, setReason] = useAdmState('');
  return (
    <div className="mh-anim" style={{ maxWidth: 920 }}>
      <button onClick={() => nav('/admin/users')} style={{ display: 'inline-flex', alignItems: 'center', gap: 6, border: 'none', background: 'transparent', cursor: 'pointer', color: 'var(--text-3)', fontSize: 13, fontWeight: 600, padding: 0, marginBottom: 16 }}>
        <Icon name="arrowLeft" size={14}></Icon> All users
      </button>
      <div style={{ display: 'flex', alignItems: 'center', gap: 16, marginBottom: 22, flexWrap: 'wrap' }}>
        <Avatar initials={u.name.split(' ').map((w) => w[0]).slice(0, 2).join('').toUpperCase()} size={52} hue={(u.name.length * 53) % 360}></Avatar>
        <div style={{ flex: 1 }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
            <h2 style={{ margin: 0, fontFamily: 'var(--font-display)', fontSize: 22, fontWeight: 800 }}>{u.name}</h2>
            {u.type === 'org' ? <Badge tone="accent">Organization · {u.members} members</Badge> : <Badge>Personal</Badge>}
            {u.status === 'suspended' ? <Badge tone="danger">Suspended</Badge> : null}
          </div>
          <div style={{ fontSize: 13.5, color: 'var(--text-3)' }}>{u.email} · registered {u.registered}</div>
        </div>
        <div style={{ display: 'flex', gap: 9 }}>
          <Btn variant="secondary" icon="coin" onClick={() => setAdjustOpen(true)}>Adjust credits</Btn>
          {u.status === 'active'
            ? <Btn variant="danger" icon="pause" onClick={() => setSuspendOpen(true)}>Suspend</Btn>
            : <Btn icon="play" onClick={() => toast('Account reactivated')}>Reactivate</Btn>}
        </div>
      </div>
      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(180px, 1fr))', gap: 14, marginBottom: 20 }}>
        <StatCard label="Credit balance" icon="wallet" value={u.balance.toLocaleString()} sub={u.type === 'org' ? 'org pool' : 'personal wallet'}></StatCard>
        <StatCard label="Total topped up" icon="coin" value="2,400" sub="RM 210 lifetime"></StatCard>
        <StatCard label="Calls · 30 days" icon="zap" value="412"></StatCard>
        <StatCard label="Active keys" icon="key" value={u.type === 'org' ? 9 : 3}></StatCard>
      </div>
      {u.type === 'org' ? (
        <Card style={{ padding: 0, overflow: 'hidden', marginBottom: 20 }}>
          <div style={{ padding: '14px 20px', borderBottom: '1px solid var(--border)', fontWeight: 700, fontFamily: 'var(--font-display)', fontSize: 15 }}>Members</div>
          {MH_TEAM.slice(0, u.members).map((m, i) => (
            <div key={i} style={{ display: 'flex', alignItems: 'center', gap: 11, padding: '11px 20px', borderBottom: i < u.members - 1 ? '1px solid var(--border)' : 'none' }}>
              <Avatar initials={m.initials} size={28} hue={(m.name.length * 47) % 360}></Avatar>
              <span style={{ flex: 1, fontSize: 13.5, fontWeight: 600 }}>{m.name} <span style={{ color: 'var(--text-3)', fontWeight: 400 }}>· {m.email}</span></span>
              <Badge tone={m.role === 'Admin' ? 'accent' : 'neutral'}>{m.role}</Badge>
            </div>
          ))}
        </Card>
      ) : null}

      {/* top-up & credit history */}
      <SectionHead title="Top-up &amp; credit history" sub="Credit purchases and manual adjustments on this account"
        right={<Btn variant="secondary" size="sm" icon="download" onClick={() => toast('Exporting credit history…')}>Export</Btn>}></SectionHead>
      <Table cols={[{ label: 'Date' }, { label: 'Source' }, { label: 'Paid', align: 'right' }, { label: 'Credits', align: 'right' }, { label: 'Status' }]}>
        {[
          { date: '2 Jun 2026', type: 'topup', label: 'Standard package', sub: 'Visa •••• 4242 · Stripe', paid: 'RM 50.00', credits: 550, status: 'paid' },
          { date: '28 May 2026', type: 'topup', label: 'Pro package', sub: 'iPay88 · FPX', paid: 'RM 100.00', credits: 1200, status: 'paid' },
          { date: '19 May 2026', type: 'adjust', label: 'Manual adjustment', sub: 'Refund · failed SSM call #482 · by Agmo Staff', paid: '—', credits: 25, status: 'adjustment' },
          { date: '3 May 2026', type: 'topup', label: 'Starter package', sub: 'Stripe', paid: 'RM 10.00', credits: 100, status: 'paid' },
          { date: '3 May 2026', type: 'topup', label: 'Starter package', sub: 'Stripe · payment not completed', paid: 'RM 10.00', credits: 0, status: 'abandoned' },
          { date: '14 Apr 2026', type: 'topup', label: 'Standard package', sub: 'Razorpay', paid: 'RM 50.00', credits: 550, status: 'paid' },
        ].map((tx, i) => {
          const isAdjust = tx.type === 'adjust';
          const failed = tx.status === 'abandoned';
          return (
            <Tr key={i}>
              <Td style={{ whiteSpace: 'nowrap', color: 'var(--text-3)' }}>{tx.date}</Td>
              <Td>
                <span style={{ display: 'inline-flex', alignItems: 'center', gap: 11 }}>
                  <span style={{
                    width: 30, height: 30, borderRadius: 9, flexShrink: 0, display: 'flex', alignItems: 'center', justifyContent: 'center',
                    background: isAdjust ? 'color-mix(in oklch, var(--accent) 14%, transparent)' : failed ? 'var(--bg-sunken)' : 'color-mix(in oklch, var(--ok) 15%, transparent)',
                    color: isAdjust ? 'var(--accent)' : failed ? 'var(--text-3)' : 'var(--ok)',
                  }}>
                    <Icon name={isAdjust ? 'settings' : 'coin'} size={15}></Icon>
                  </span>
                  <span>
                    <span style={{ display: 'block', fontWeight: 700, color: 'var(--text)' }}>{tx.label}</span>
                    <span style={{ display: 'block', fontSize: 12, color: 'var(--text-3)' }}>{tx.sub}</span>
                  </span>
                </span>
              </Td>
              <Td align="right" style={{ whiteSpace: 'nowrap', fontWeight: 600, color: failed ? 'var(--text-3)' : 'var(--text-2)', textDecoration: failed ? 'line-through' : 'none' }}>{tx.paid}</Td>
              <Td align="right" style={{ fontWeight: 700, color: tx.credits > 0 ? 'var(--ok)' : 'var(--text-3)' }}>{tx.credits > 0 ? '+' + tx.credits.toLocaleString() : '—'}</Td>
              <Td>{tx.status === 'paid' ? <Badge tone="ok">Paid</Badge> : tx.status === 'adjustment' ? <Badge tone="accent">Adjustment</Badge> : <Badge tone="danger">Abandoned</Badge>}</Td>
            </Tr>
          );
        })}
      </Table>

      <SectionHead title="Recent usage"></SectionHead>
      <Table cols={[{ label: 'When' }, { label: 'MCP' }, { label: 'Tool' }, { label: 'Credits', align: 'right' }]}>
        {MH_USAGE.slice(0, 6).map((g, i) => (
          <Tr key={i}>
            <Td style={{ whiteSpace: 'nowrap', color: 'var(--text-3)' }}>{g.ts}</Td>
            <Td style={{ fontWeight: 600, color: 'var(--text)' }}>{mhGetMcp(g.mcp).name}</Td>
            <Td><code style={{ fontFamily: 'var(--font-mono)', fontSize: 12.5 }}>{g.tool}</code></Td>
            <Td align="right" style={{ fontWeight: 700 }}>{g.credits === 0 ? 'Free' : '−' + g.credits}</Td>
          </Tr>
        ))}
      </Table>
      <Modal open={adjustOpen} onClose={() => setAdjustOpen(false)} title="Manual credit adjustment">
        <div style={{ display: 'flex', flexDirection: 'column', gap: 15 }}>
          <Field label="Amount" hint="Use a negative number to deduct. Deductions cannot bring the balance below 0.">
            <TextInput type="number" value={amount} onChange={setAmount} placeholder="e.g. 100 or -50"></TextInput>
          </Field>
          <Field label="Reason (required, logged)">
            <TextInput value={reason} onChange={setReason} placeholder="Refund for failed SSM call · ticket #482"></TextInput>
          </Field>
          <p style={{ margin: 0, fontSize: 12.5, color: 'var(--text-3)' }}>The adjustment is added to the transaction history and the user is notified by email.</p>
          <Btn size="lg" disabled={!amount || !reason} icon="check" onClick={() => { setAdjustOpen(false); toast('Adjusted ' + u.name + ' by ' + amount + ' credits'); setAmount(''); setReason(''); }} style={{ justifyContent: 'center' }}>Apply adjustment</Btn>
        </div>
      </Modal>
      <Modal open={suspendOpen} onClose={() => setSuspendOpen(false)} title={'Suspend ' + u.name + '?'}>
        <p style={{ margin: '0 0 14px', fontSize: 14, color: 'var(--text-2)', lineHeight: 1.55 }}>
          They can't log in and the gateway rejects all their API keys with 403. {u.type === 'org' ? <strong>All {u.members} members are suspended too. </strong> : null}You can reactivate at any time.
        </p>
        <Field label="Suspension reason (required, logged)">
          <TextInput value={reason} onChange={setReason} placeholder="Chargeback dispute · case #119"></TextInput>
        </Field>
        <div style={{ display: 'flex', gap: 10, marginTop: 16 }}>
          <Btn variant="danger" icon="pause" disabled={!reason} onClick={() => { setSuspendOpen(false); toast(u.name + ' suspended', 'danger'); setReason(''); }} style={{ flex: 1, justifyContent: 'center' }}>Suspend account</Btn>
          <Btn variant="secondary" onClick={() => setSuspendOpen(false)}>Cancel</Btn>
        </div>
      </Modal>
    </div>
  );
}

// ---------- Admin analytics ----------
function AdminAnalytics() {
  const S = MH_ADMIN_STATS;
  const [granularity, setGranularity] = useAdmState('weekly');
  return (
    <div className="mh-anim">
      <SectionHead title="Analytics" sub="Revenue, usage and growth across the platform."
        right={<Btn variant="secondary" size="sm" icon="download">Export CSV</Btn>}></SectionHead>
      <div style={{ display: 'grid', gridTemplateColumns: 'minmax(0, 1.5fr) minmax(260px, 1fr)', gap: 18, marginBottom: 18, alignItems: 'flex-start' }}>
        <Card style={{ padding: 22 }}>
          <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 14 }}>
            <span style={{ fontWeight: 700, fontFamily: 'var(--font-display)', fontSize: 15.5 }}>Revenue (RM)</span>
            <Segmented size="sm" value={granularity} onChange={setGranularity} options={['weekly', 'monthly']}></Segmented>
          </div>
          <LineChart data={S.revenueByWeek} height={150}></LineChart>
          <div style={{ display: 'flex', justifyContent: 'space-between', fontSize: 11.5, color: 'var(--text-3)', marginTop: 6 }}>
            <span>Mar</span><span>Apr</span><span>May</span><span>Jun</span>
          </div>
        </Card>
        <div style={{ display: 'flex', flexDirection: 'column', gap: 18 }}>
          <Card style={{ padding: 20 }}>
            <div style={{ fontWeight: 700, fontFamily: 'var(--font-display)', fontSize: 14.5, marginBottom: 12 }}>By package</div>
            <SplitBars items={S.packageSplit}></SplitBars>
          </Card>
          <Card style={{ padding: 20 }}>
            <div style={{ fontWeight: 700, fontFamily: 'var(--font-display)', fontSize: 14.5, marginBottom: 12 }}>By gateway</div>
            <SplitBars items={S.gatewaySplit} color="var(--ok)"></SplitBars>
          </Card>
        </div>
      </div>
      <div style={{ display: 'grid', gridTemplateColumns: 'minmax(0, 1.5fr) minmax(260px, 1fr)', gap: 18, alignItems: 'flex-start' }}>
        <Card style={{ padding: 22 }}>
          <div style={{ fontWeight: 700, fontFamily: 'var(--font-display)', fontSize: 15.5, marginBottom: 14 }}>New registrations · weekly</div>
          <BarChart data={S.signupsByWeek} height={130} color="var(--ok)"></BarChart>
          <div style={{ display: 'flex', gap: 16, marginTop: 12, fontSize: 12.5, color: 'var(--text-3)' }}>
            <span><strong style={{ color: 'var(--text)' }}>78%</strong> personal</span>
            <span><strong style={{ color: 'var(--text)' }}>22%</strong> organization</span>
          </div>
        </Card>
        <Card style={{ padding: 22 }}>
          <div style={{ fontWeight: 700, fontFamily: 'var(--font-display)', fontSize: 15.5, marginBottom: 14 }}>Conversion funnel</div>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 9 }}>
            {S.funnel.map((f, i) => {
              const pct = Math.round((f.n / S.funnel[0].n) * 100);
              return (
                <div key={f.stage}>
                  <div style={{ display: 'flex', justifyContent: 'space-between', fontSize: 12.5, fontWeight: 600, marginBottom: 3 }}>
                    <span>{f.stage}</span><span style={{ color: 'var(--text-3)' }}>{f.n.toLocaleString()} · {pct}%</span>
                  </div>
                  <div style={{ height: 22, borderRadius: 6, background: 'var(--bg-sunken)', overflow: 'hidden' }}>
                    <div style={{ width: pct + '%', height: '100%', borderRadius: 6, background: `color-mix(in oklch, var(--accent) ${100 - i * 18}%, var(--bg-sunken))`, transition: 'width .5s ease' }}></div>
                  </div>
                </div>
              );
            })}
          </div>
        </Card>
      </div>
    </div>
  );
}

// ---------- Admin team & access ----------
function PermPip({ level }) {
  const map = {
    full: { label: 'Edit & update', color: 'var(--accent)', bg: 'color-mix(in oklch, var(--accent) 14%, transparent)' },
    view: { label: 'View only', color: 'var(--text-2)', bg: 'var(--bg-sunken)' },
    none: { label: 'No access', color: 'var(--text-3)', bg: 'transparent' },
  };
  const c = map[level] || map.none;
  return (
    <span style={{ display: 'inline-flex', alignItems: 'center', gap: 6, fontSize: 12.5, fontWeight: 600, color: c.color }}>
      <span style={{ width: 8, height: 8, borderRadius: '50%', background: level === 'none' ? 'var(--border-strong)' : c.color, flexShrink: 0 }}></span>
      {c.label}
    </span>
  );
}

function RoleOption({ role, selected, onClick, disabled }) {
  return (
    <button type="button" onClick={disabled ? undefined : onClick} disabled={disabled} style={{
      display: 'block', width: '100%', textAlign: 'left', cursor: disabled ? 'not-allowed' : 'pointer',
      padding: '13px 15px', borderRadius: 12, marginBottom: 9,
      border: '1.5px solid ' + (selected ? 'var(--accent)' : 'var(--border-strong)'),
      background: selected ? 'color-mix(in oklch, var(--accent) 8%, var(--surface))' : 'var(--surface)',
      opacity: disabled ? 0.5 : 1, transition: 'all .13s ease',
    }}>
      <div style={{ display: 'flex', alignItems: 'center', gap: 9, marginBottom: 4 }}>
        <span style={{
          width: 16, height: 16, borderRadius: '50%', flexShrink: 0,
          border: '1.5px solid ' + (selected ? 'var(--accent)' : 'var(--border-strong)'),
          background: selected ? 'var(--accent)' : 'transparent',
          display: 'flex', alignItems: 'center', justifyContent: 'center',
        }}>{selected ? <span style={{ width: 6, height: 6, borderRadius: '50%', background: '#fff' }}></span> : null}</span>
        <span style={{ fontWeight: 700, fontSize: 14, color: 'var(--text)' }}>{role.label}</span>
        {role.id === 'editor' ? <Badge tone="ok">Edit &amp; update</Badge> : null}
      </div>
      <div style={{ fontSize: 12.5, color: 'var(--text-3)', lineHeight: 1.5, paddingLeft: 25 }}>{role.desc}</div>
    </button>
  );
}

function AdminTeam({ nav }) {
  const toast = useToast();
  const [inviteOpen, setInviteOpen] = useAdmState(false);
  const [editStaff, setEditStaff] = useAdmState(null);
  const [email, setEmail] = useAdmState('');
  const [role, setRole] = useAdmState('editor');
  const active = MH_ADMIN_STAFF.filter((s) => s.status === 'active').length;

  const sendInvite = () => {
    setInviteOpen(false);
    toast('Invitation sent to ' + email + ' · ' + mhAdminRole(role).label);
    setEmail(''); setRole('editor');
  };

  return (
    <div className="mh-anim">
      <SectionHead title="Admins &amp; access" sub={MH_ADMIN_STAFF.length + ' admins · ' + active + ' active · ' + MH_ADMIN_INVITES.length + ' pending invite'}
        right={<Btn icon="plus" onClick={() => { setRole('editor'); setEmail(''); setInviteOpen(true); }}>Invite admin</Btn>}></SectionHead>

      {/* role permission reference */}
      <Card style={{ padding: 0, overflow: 'hidden', marginBottom: 22 }}>
        <div style={{ padding: '15px 20px', borderBottom: '1px solid var(--border)', display: 'flex', alignItems: 'center', gap: 9 }}>
          <Icon name="shield" size={16} style={{ color: 'var(--accent)' }}></Icon>
          <span style={{ fontWeight: 700, fontFamily: 'var(--font-display)', fontSize: 15 }}>Roles &amp; permissions</span>
        </div>
        <div style={{ overflowX: 'auto' }}>
          <table style={{ width: '100%', borderCollapse: 'collapse', fontSize: 13.5, minWidth: 760 }}>
            <thead>
              <tr>
                <th style={{ textAlign: 'left', padding: '11px 20px', fontSize: 11.5, fontWeight: 700, textTransform: 'uppercase', letterSpacing: '.05em', color: 'var(--text-3)', background: 'var(--bg-sunken)' }}>Access area</th>
                {MH_ADMIN_ROLES.map((r) => (
                  <th key={r.id} style={{ textAlign: 'left', padding: '11px 16px', fontSize: 12.5, fontWeight: 700, color: 'var(--text)', background: 'var(--bg-sunken)', whiteSpace: 'nowrap' }}>{r.label}</th>
                ))}
              </tr>
            </thead>
            <tbody>
              {MH_ADMIN_SCOPES.map((sc) => (
                <tr key={sc.id}>
                  <td style={{ padding: '13px 20px', borderBottom: '1px solid var(--border)', verticalAlign: 'top' }}>
                    <div style={{ fontWeight: 700, color: 'var(--text)' }}>{sc.label}</div>
                    <div style={{ fontSize: 12, color: 'var(--text-3)', marginTop: 2, maxWidth: 230 }}>{sc.desc}</div>
                  </td>
                  {MH_ADMIN_ROLES.map((r) => (
                    <td key={r.id} style={{ padding: '13px 16px', borderBottom: '1px solid var(--border)', verticalAlign: 'top' }}>
                      <PermPip level={r.perms[sc.id]}></PermPip>
                    </td>
                  ))}
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      </Card>

      {/* current admins */}
      <SectionHead title="Admin accounts"></SectionHead>
      <Table cols={[{ label: 'Admin' }, { label: 'Role' }, { label: 'Last active' }, { label: 'Status' }, { label: '', align: 'right' }]}>
        {MH_ADMIN_STAFF.map((s, i) => {
          const r = mhAdminRole(s.role);
          return (
            <Tr key={i} onClick={s.you ? undefined : () => { setEditStaff(s); setRole(s.role); }}>
              <Td>
                <span style={{ display: 'inline-flex', alignItems: 'center', gap: 11 }}>
                  <Avatar initials={s.initials} size={32} hue={(s.name.length * 51) % 360}></Avatar>
                  <span>
                    <span style={{ display: 'block', fontWeight: 700, color: 'var(--text)' }}>{s.name}{s.you ? <span style={{ color: 'var(--text-3)', fontWeight: 500 }}> (you)</span> : null}</span>
                    <span style={{ display: 'block', fontSize: 12, color: 'var(--text-3)' }}>{s.email}</span>
                  </span>
                </span>
              </Td>
              <Td><Badge tone={r.tone}>{r.label}</Badge></Td>
              <Td style={{ whiteSpace: 'nowrap', color: s.lastActive === 'Active now' ? 'var(--ok)' : 'var(--text-2)', fontWeight: s.lastActive === 'Active now' ? 700 : 400 }}>{s.lastActive}</Td>
              <Td>{s.status === 'active' ? <Badge tone="ok">Active</Badge> : <Badge tone="danger">Suspended</Badge>}</Td>
              <Td align="right">{s.you ? <span style={{ fontSize: 12, color: 'var(--text-3)' }}>—</span> : <Icon name="chevronRight" size={15} style={{ color: 'var(--text-3)' }}></Icon>}</Td>
            </Tr>
          );
        })}
      </Table>

      {/* pending invites */}
      {MH_ADMIN_INVITES.length ? (
        <div style={{ marginTop: 26 }}>
          <SectionHead title="Pending invites"></SectionHead>
          <Table cols={[{ label: 'Email' }, { label: 'Role' }, { label: 'Invited' }, { label: 'Expires' }, { label: '', align: 'right' }]}>
            {MH_ADMIN_INVITES.map((inv, i) => (
              <Tr key={i}>
                <Td><span style={{ display: 'inline-flex', alignItems: 'center', gap: 9, fontWeight: 600, color: 'var(--text)' }}><Icon name="mail" size={15} style={{ color: 'var(--text-3)' }}></Icon>{inv.email}</span></Td>
                <Td><Badge tone={mhAdminRole(inv.role).tone}>{mhAdminRole(inv.role).label}</Badge></Td>
                <Td style={{ whiteSpace: 'nowrap' }}>{inv.invited}</Td>
                <Td style={{ whiteSpace: 'nowrap', color: 'var(--text-3)' }}>{inv.expires}</Td>
                <Td align="right">
                  <span style={{ display: 'inline-flex', gap: 6, justifyContent: 'flex-end' }}>
                    <Btn variant="ghost" size="sm" onClick={() => toast('Invitation resent to ' + inv.email)}>Resend</Btn>
                    <Btn variant="ghost" size="sm" onClick={() => toast('Invitation revoked', 'danger')}>Revoke</Btn>
                  </span>
                </Td>
              </Tr>
            ))}
          </Table>
        </div>
      ) : null}

      {/* invite modal */}
      <Modal open={inviteOpen} onClose={() => setInviteOpen(false)} title="Invite an admin" width={540}>
        <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
          <Field label="Work email" hint="They’ll get a secure link to set a password and 2FA.">
            <TextInput value={email} onChange={setEmail} placeholder="name@agmogroup.com" type="email"></TextInput>
          </Field>
          <div>
            <div style={{ fontSize: 13, fontWeight: 700, color: 'var(--text-2)', marginBottom: 9 }}>Role &amp; access</div>
            {MH_ADMIN_ROLES.filter((r) => !r.system).map((r) => (
              <RoleOption key={r.id} role={r} selected={role === r.id} onClick={() => setRole(r.id)}></RoleOption>
            ))}
          </div>
          <Btn size="lg" icon="mail" disabled={!email} onClick={sendInvite} style={{ justifyContent: 'center' }}>Send invitation</Btn>
        </div>
      </Modal>

      {/* edit / manage admin modal */}
      <Modal open={!!editStaff} onClose={() => setEditStaff(null)} title={editStaff ? 'Manage ' + editStaff.name : ''} width={540}>
        {editStaff ? (
          <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
            <div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
              <Avatar initials={editStaff.initials} size={40} hue={(editStaff.name.length * 51) % 360}></Avatar>
              <div>
                <div style={{ fontWeight: 700, color: 'var(--text)' }}>{editStaff.name}</div>
                <div style={{ fontSize: 12.5, color: 'var(--text-3)' }}>{editStaff.email} · joined {editStaff.joined}</div>
              </div>
            </div>
            <div>
              <div style={{ fontSize: 13, fontWeight: 700, color: 'var(--text-2)', marginBottom: 9 }}>Change role</div>
              {MH_ADMIN_ROLES.filter((r) => !r.system).map((r) => (
                <RoleOption key={r.id} role={r} selected={role === r.id} onClick={() => setRole(r.id)}></RoleOption>
              ))}
            </div>
            <div style={{ display: 'flex', gap: 10, alignItems: 'center' }}>
              <Btn icon="check" onClick={() => { toast(editStaff.name + ' is now ' + mhAdminRole(role).label); setEditStaff(null); }}>Save role</Btn>
              {editStaff.status === 'active'
                ? <Btn variant="danger" icon="pause" onClick={() => { toast(editStaff.name + ' suspended', 'danger'); setEditStaff(null); }}>Suspend</Btn>
                : <Btn icon="play" onClick={() => { toast(editStaff.name + ' reactivated'); setEditStaff(null); }}>Reactivate</Btn>}
              <Btn variant="ghost" icon="trash" style={{ marginLeft: 'auto', color: 'var(--danger)' }} onClick={() => { toast('Admin access revoked', 'danger'); setEditStaff(null); }}>Revoke access</Btn>
            </div>
          </div>
        ) : null}
      </Modal>
    </div>
  );
}

// ---------- Admin shell ----------
const ADMIN_NAV = [
  { path: '/admin', label: 'Overview', icon: 'grid' },
  { path: '/admin/mcps', label: 'MCPs', icon: 'box' },
  { path: '/admin/users', label: 'Users', icon: 'users' },
  { path: '/admin/analytics', label: 'Analytics', icon: 'chart' },
  { path: '/admin/team', label: 'Admins', icon: 'shield' },
];

function AdminShell({ route, nav }) {
  let screen = <AdminDash nav={nav}></AdminDash>;
  const mcpMatch = route.match(/^\/admin\/mcps\/([\w-]+)$/);
  const userMatch = route.match(/^\/admin\/users\/(\d+)$/);
  if (route === '/admin/mcps') screen = <AdminMcps nav={nav}></AdminMcps>;
  else if (mcpMatch) screen = <AdminMcpEdit slug={mcpMatch[1]} nav={nav}></AdminMcpEdit>;
  else if (route === '/admin/users') screen = <AdminUsers nav={nav}></AdminUsers>;
  else if (userMatch) screen = <AdminUserDetail idx={userMatch[1]} nav={nav}></AdminUserDetail>;
  else if (route === '/admin/analytics') screen = <AdminAnalytics></AdminAnalytics>;
  else if (route === '/admin/team') screen = <AdminTeam nav={nav}></AdminTeam>;
  return (
    <div data-screen-label={'Admin — ' + route} style={{ display: 'flex', minHeight: '100vh' }}>
      <aside style={{
        width: 224, flexShrink: 0, background: 'var(--bg-inverse)', color: 'var(--bg)',
        display: 'flex', flexDirection: 'column', padding: '20px 14px', position: 'sticky', top: 0, height: '100vh',
      }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 9, padding: '0 10px 18px', borderBottom: '1px solid rgba(255,255,255,.1)', marginBottom: 14 }}>
          <Logo size={26} withWord={false}></Logo>
          <div>
            <div style={{ fontFamily: 'var(--font-display)', fontWeight: 800, fontSize: 15, lineHeight: 1.1 }}>MCP Hero</div>
            <div style={{ fontSize: 10.5, fontWeight: 700, letterSpacing: '.1em', textTransform: 'uppercase', opacity: .55 }}>Admin portal</div>
          </div>
        </div>
        {ADMIN_NAV.map((n) => {
          const active = route === n.path || (n.path !== '/admin' && route.startsWith(n.path));
          return (
            <button key={n.path} onClick={() => nav(n.path)} style={{
              display: 'flex', alignItems: 'center', gap: 11, padding: '9px 12px', borderRadius: 9, marginBottom: 2,
              border: 'none', cursor: 'pointer', fontSize: 13.5, fontWeight: 600, textAlign: 'left',
              background: active ? 'rgba(255,255,255,.12)' : 'transparent',
              color: active ? '#fff' : 'rgba(255,255,255,.6)', transition: 'all .13s ease',
            }}>
              <Icon name={n.icon} size={15}></Icon>{n.label}
            </button>
          );
        })}
        <div style={{ marginTop: 'auto', padding: '12px 10px', borderTop: '1px solid rgba(255,255,255,.1)', display: 'flex', alignItems: 'center', gap: 9 }}>
          <button onClick={() => nav('/admin/team')} title="Admins & access" style={{ display: 'flex', alignItems: 'center', gap: 9, flex: 1, minWidth: 0, border: 'none', background: 'transparent', cursor: 'pointer', padding: 0, textAlign: 'left', color: 'inherit' }}>
            <Avatar initials="AG" size={28} hue={20}></Avatar>
            <div style={{ minWidth: 0, flex: 1 }}>
              <div style={{ fontSize: 12.5, fontWeight: 700, color: '#fff' }}>Agmo Staff</div>
              <div style={{ fontSize: 11, opacity: .5 }}>Owner · manage admins</div>
            </div>
          </button>
          <button onClick={() => nav('/')} title="Exit admin" style={{ border: 'none', background: 'transparent', cursor: 'pointer', color: 'rgba(255,255,255,.5)', padding: 4 }}>
            <Icon name="logout" size={15}></Icon>
          </button>
        </div>
      </aside>
      <main style={{ flex: 1, minWidth: 0, padding: '28px 32px 80px', maxWidth: 1100 }}>{screen}</main>
    </div>
  );
}

Object.assign(window, { AdminShell });
