function AdminPanel({ go, user, token }) {
  const wide = useWide();

  // Redirect if not admin
  React.useEffect(() => {
    if (user === null) go('login');
    else if (user && user.role !== 'admin') go('landing');
  }, [user]);

  const [view,   setView]   = React.useState('list'); // 'list' | 'edit'
  const [memos,  setMemos]  = React.useState([]);
  const [editing, setEditing] = React.useState(null);  // memo object or null (new)
  const [saving,  setSaving]  = React.useState(false);
  const [msg,     setMsg]     = React.useState('');

  const headers = { 'Content-Type': 'application/json', Authorization: 'Bearer ' + token };

  const loadMemos = () => fetch('/api/memos', { headers }).then(r => r.json()).then(setMemos);
  React.useEffect(() => { loadMemos(); }, []);

  const newMemo = () => {
    setEditing({ slug: '', title: '', date: new Date().toLocaleDateString('en-US',{month:'short',day:'numeric',year:'numeric'}), category: 'MARKETS', read_min: 7, free: false, summary: '', body: [], published: false });
    setView('edit');
  };

  const editMemo = (m) => { setEditing({ ...m, body: m.body || [] }); setView('edit'); };

  const deleteMemo = async (slug) => {
    if (!confirm('Delete ' + slug + '?')) return;
    await fetch('/api/memos/' + slug, { method: 'DELETE', headers });
    loadMemos();
  };

  const togglePublish = async (m) => {
    await fetch('/api/memos/' + m.slug, { method: 'PATCH', headers, body: JSON.stringify({ published: !m.published }) });
    loadMemos();
  };

  const saveMemo = async () => {
    setSaving(true); setMsg('');
    const isNew = !memos.find(m => m.slug === editing.slug);
    const method = isNew ? 'POST' : 'PATCH';
    const url    = isNew ? '/api/memos' : '/api/memos/' + editing.slug;
    try {
      const res = await fetch(url, { method, headers, body: JSON.stringify({ ...editing, body: editing.body }) });
      const data = await res.json();
      if (!res.ok) { setMsg('Error: ' + (data.error || 'Save failed')); return; }
      setMsg('Saved!');
      loadMemos();
      setTimeout(() => { setView('list'); setEditing(null); setMsg(''); }, 800);
    } catch { setMsg('Network error'); }
    finally { setSaving(false); }
  };

  const addBlock = (type) => setEditing(e => ({ ...e, body: [...e.body, { t: type, s: type === 'bullets' ? [''] : '' }] }));
  const updateBlock = (i, val) => setEditing(e => { const b = [...e.body]; b[i] = { ...b[i], s: val }; return { ...e, body: b }; });
  const removeBlock = (i) => setEditing(e => ({ ...e, body: e.body.filter((_, j) => j !== i) }));
  const moveBlock = (i, dir) => setEditing(e => {
    const b = [...e.body]; const j = i + dir;
    if (j < 0 || j >= b.length) return e;
    [b[i], b[j]] = [b[j], b[i]]; return { ...e, body: b };
  });
  const updateBullet = (bi, li, val) => setEditing(e => {
    const b = [...e.body]; const bullets = [...b[bi].s]; bullets[li] = val;
    b[bi] = { ...b[bi], s: bullets }; return { ...e, body: b };
  });
  const addBullet    = (bi) => setEditing(e => { const b = [...e.body]; b[bi] = { ...b[bi], s: [...b[bi].s, ''] }; return { ...e, body: b }; });
  const removeBullet = (bi, li) => setEditing(e => { const b = [...e.body]; b[bi] = { ...b[bi], s: b[bi].s.filter((_,j)=>j!==li) }; return { ...e, body: b }; });

  const inp = (style={}) => ({ style: { width: '100%', background: '#0d0d0a', border: '1px solid #2a2a22', color: '#e8e4d6', fontFamily: 'JetBrains Mono, monospace', fontSize: 12, padding: '8px 10px', outline: 'none', boxSizing: 'border-box', ...style } });
  const lbl = (text) => <div style={{ fontFamily: 'JetBrains Mono, monospace', fontSize: 10, color: '#7a7a6e', letterSpacing: 1.5, textTransform: 'uppercase', marginBottom: 5 }}>{text}</div>;
  const row = (children, style={}) => <div style={{ marginBottom: 12, ...style }}>{children}</div>;

  if (view === 'edit' && editing) return (
    <div style={{ background: '#13130f', color: '#e8e4d6', minHeight: '100vh', padding: wide ? '32px' : '16px', fontFamily: 'Inter, sans-serif' }}>
      <div style={{ maxWidth: 820, margin: '0 auto' }}>
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 24 }}>
          <div style={{ fontFamily: 'JetBrains Mono, monospace', fontSize: 11, color: TH.accent, letterSpacing: 2 }}>
            <span onClick={() => { setView('list'); setEditing(null); }} style={{ cursor: 'pointer' }}>← MEMOS</span>
            <span style={{ marginLeft: 12, color: '#7a7a6e' }}>{editing.slug ? 'EDIT · ' + editing.slug : 'NEW MEMO'}</span>
          </div>
          {msg && <div style={{ fontFamily: 'JetBrains Mono, monospace', fontSize: 11, color: msg.startsWith('Error') ? '#c86a5a' : TH.accent }}>{msg}</div>}
          <button onClick={saveMemo} disabled={saving} style={{ background: TH.accent, color: '#13130f', border: 'none', fontFamily: 'JetBrains Mono, monospace', fontSize: 11, padding: '8px 16px', cursor: 'pointer', letterSpacing: 1 }}>{saving ? 'SAVING…' : 'SAVE'}</button>
        </div>

        <div style={{ display: 'grid', gridTemplateColumns: wide ? '1fr 1fr' : '1fr', gap: 12, marginBottom: 12 }}>
          {row(<>{lbl('Title')}<input {...inp()} value={editing.title} onChange={e => setEditing(v=>({...v,title:e.target.value}))}/></>)}
          {row(<>{lbl('Slug')}<input {...inp()} value={editing.slug} onChange={e => setEditing(v=>({...v,slug:e.target.value}))}/></>)}
          {row(<>{lbl('Date')}<input {...inp()} value={editing.date} onChange={e => setEditing(v=>({...v,date:e.target.value}))}/></>)}
          {row(<>{lbl('Category')}<select value={editing.category} onChange={e => setEditing(v=>({...v,category:e.target.value}))} style={{ ...inp().style, cursor: 'pointer' }}>{['MARKETS','METHODS','TOOLS','COMMUNITY'].map(c=><option key={c}>{c}</option>)}</select></>)}
          {row(<>{lbl('Read min')}<input {...inp()} type="number" value={editing.read_min} onChange={e => setEditing(v=>({...v,read_min:+e.target.value}))}/></>)}
          {row(<div style={{ display: 'flex', gap: 20, alignItems: 'center', paddingTop: 20 }}>
            <label style={{ display: 'flex', gap: 8, alignItems: 'center', cursor: 'pointer', fontFamily: 'JetBrains Mono, monospace', fontSize: 11 }}>
              <input type="checkbox" checked={editing.free} onChange={e => setEditing(v=>({...v,free:e.target.checked}))}/> FREE
            </label>
            <label style={{ display: 'flex', gap: 8, alignItems: 'center', cursor: 'pointer', fontFamily: 'JetBrains Mono, monospace', fontSize: 11 }}>
              <input type="checkbox" checked={editing.published} onChange={e => setEditing(v=>({...v,published:e.target.checked}))}/> PUBLISHED
            </label>
          </div>)}
        </div>

        {row(<>{lbl('Summary')}<textarea {...inp({ height: 80, resize: 'vertical' })} value={editing.summary} onChange={e => setEditing(v=>({...v,summary:e.target.value}))}/></>)}

        <div style={{ fontFamily: 'JetBrains Mono, monospace', fontSize: 10, color: '#7a7a6e', letterSpacing: 1.5, marginBottom: 10, marginTop: 8 }}>BODY BLOCKS</div>
        {editing.body.map((block, i) => (
          <div key={i} style={{ background: '#0d0d0a', border: '1px solid #2a2a22', padding: 12, marginBottom: 8 }}>
            <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 8 }}>
              <select value={block.t} onChange={e => setEditing(v => { const b=[...v.body]; b[i]={...b[i],t:e.target.value,s:e.target.value==='bullets'?['']:''}; return {...v,body:b}; })} style={{ ...inp({width:'auto',padding:'4px 8px'}).style }}>
                {['p','h','callout','bullets'].map(t=><option key={t} value={t}>{t}</option>)}
              </select>
              <div style={{ display: 'flex', gap: 6 }}>
                <button onClick={() => moveBlock(i,-1)} style={{ ...inp({width:'auto',padding:'2px 8px'}).style, cursor:'pointer', border:'1px solid #2a2a22' }}>↑</button>
                <button onClick={() => moveBlock(i,1)}  style={{ ...inp({width:'auto',padding:'2px 8px'}).style, cursor:'pointer', border:'1px solid #2a2a22' }}>↓</button>
                <button onClick={() => removeBlock(i)}  style={{ ...inp({width:'auto',padding:'2px 8px'}).style, cursor:'pointer', color:'#c86a5a', border:'1px solid #c86a5a44' }}>✕</button>
              </div>
            </div>
            {block.t === 'bullets' ? (
              <div>
                {(Array.isArray(block.s) ? block.s : ['']).map((item, li) => (
                  <div key={li} style={{ display: 'flex', gap: 6, marginBottom: 6 }}>
                    <input {...inp({flex:1})} value={item} onChange={e => updateBullet(i, li, e.target.value)}/>
                    <button onClick={() => removeBullet(i,li)} style={{ ...inp({width:28,padding:'0'}).style, cursor:'pointer', color:'#c86a5a' }}>✕</button>
                  </div>
                ))}
                <button onClick={() => addBullet(i)} style={{ fontFamily:'JetBrains Mono, monospace', fontSize:10, color:TH.accent, background:'none', border:'none', cursor:'pointer', padding:'4px 0' }}>+ ADD BULLET</button>
              </div>
            ) : (
              <textarea {...inp({ height: block.t === 'p' ? 80 : 48, resize: 'vertical' })} value={block.s} onChange={e => updateBlock(i, e.target.value)}/>
            )}
          </div>
        ))}
        <div style={{ display: 'flex', gap: 8, marginTop: 8 }}>
          {['p','h','callout','bullets'].map(t => (
            <button key={t} onClick={() => addBlock(t)} style={{ fontFamily:'JetBrains Mono, monospace', fontSize:10, color:TH.accent, background:'#0d0d0a', border:`1px solid ${TH.accent}44`, padding:'6px 12px', cursor:'pointer', letterSpacing:1 }}>+ {t}</button>
          ))}
        </div>
      </div>
    </div>
  );

  return (
    <div style={{ background: '#13130f', color: '#e8e4d6', minHeight: '100vh', padding: wide ? '32px' : '16px', fontFamily: 'Inter, sans-serif' }}>
      <div style={{ maxWidth: 1100, margin: '0 auto' }}>
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 24 }}>
          <div style={{ fontFamily: 'JetBrains Mono, monospace', fontSize: 11, color: TH.accent, letterSpacing: 2 }}>ADMIN · MEMOS</div>
          <button onClick={newMemo} style={{ background: TH.accent, color: '#13130f', border: 'none', fontFamily: 'JetBrains Mono, monospace', fontSize: 11, padding: '8px 16px', cursor: 'pointer', letterSpacing: 1 }}>+ NEW MEMO</button>
        </div>
        <div style={{ background: '#0d0d0a', border: '1px solid #2a2a22' }}>
          {memos.map((m, i) => (
            <div key={m.slug} style={{ display: 'grid', gridTemplateColumns: wide ? '1fr 100px 80px 80px 140px' : '1fr 80px 100px', gap: 12, padding: '14px 16px', borderBottom: i < memos.length - 1 ? '1px solid #1e1e18' : 'none', alignItems: 'center' }}>
              <div>
                <div style={{ fontFamily: 'JetBrains Mono, monospace', fontSize: 10, color: '#7a7a6e', letterSpacing: 1, marginBottom: 3 }}>{m.slug}</div>
                <div style={{ fontSize: 14, color: '#e8e4d6' }}>{m.title}</div>
              </div>
              {wide && <div style={{ fontFamily: 'JetBrains Mono, monospace', fontSize: 10, color: '#7a7a6e' }}>{m.category}</div>}
              {wide && <div style={{ fontFamily: 'JetBrains Mono, monospace', fontSize: 10, color: m.free ? '#7ba15c' : '#7a7a6e' }}>{m.free ? 'FREE' : 'MEMBER'}</div>}
              <div onClick={() => togglePublish(m)} style={{ fontFamily: 'JetBrains Mono, monospace', fontSize: 10, color: m.published ? '#7ba15c' : '#7a7a6e', cursor: 'pointer' }}>
                ● {m.published ? 'LIVE' : 'DRAFT'}
              </div>
              <div style={{ display: 'flex', gap: 8 }}>
                <button onClick={() => editMemo(m)} style={{ fontFamily:'JetBrains Mono, monospace', fontSize:10, background:'none', border:`1px solid ${TH.accent}44`, color:TH.accent, padding:'4px 10px', cursor:'pointer' }}>EDIT</button>
                <button onClick={() => deleteMemo(m.slug)} style={{ fontFamily:'JetBrains Mono, monospace', fontSize:10, background:'none', border:'1px solid #c86a5a44', color:'#c86a5a', padding:'4px 10px', cursor:'pointer' }}>DEL</button>
              </div>
            </div>
          ))}
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { AdminPanel });
