// ── Workers Admin ─────────────────────────────────────────────────────

function WorkersAdminPage() {
  const [tab, setTab] = useState('overview');
  const [stats, setStats] = useState(null);
  const [settings, setSettings] = useState(null);
  const [allWorkers, setAllWorkers] = useState([]);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState('');
  const [saving, setSaving] = useState(false);
  const [globalCtx, setGlobalCtx] = useState([]);
  const [ctxForm, setCtxForm] = useState(null);

  const loadStats = async () => {
    try { setStats(await api('/api/workers-admin/stats')); } catch {}
  };
  const loadSettings = async () => {
    try { setSettings(await api('/api/workers-admin/settings')); } catch (e) { setError(e.message); }
  };
  const loadAllWorkers = async () => {
    setLoading(true);
    try { setAllWorkers(await api('/api/workers-admin/workers')); } catch (e) { setError(e.message); }
    finally { setLoading(false); }
  };

  const loadGlobalCtx = async () => {
    try { setGlobalCtx(await api('/api/workers-admin/global-ctx')); } catch (e) { setError(e.message); }
  };

  useEffect(() => { loadStats(); loadSettings(); loadAllWorkers(); loadGlobalCtx(); }, []);

  const saveSettings = async () => {
    if (!settings) return;
    setSaving(true);
    try {
      const updated = await api('/api/workers-admin/settings', { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ settings }) });
      setSettings(updated);
      setError('');
    } catch (e) { setError(e.message); }
    finally { setSaving(false); }
  };

  const toggleWorker = async (id) => {
    try {
      await api(`/api/workers-admin/workers/${id}/toggle`, { method: 'PUT' });
      loadAllWorkers();
      loadStats();
    } catch (e) { setError(e.message); }
  };

  const deleteWorker = async (id, name) => {
    if (!confirm(`Delete worker "${name}"? This is permanent.`)) return;
    try {
      await api(`/api/workers-admin/workers/${id}`, { method: 'DELETE' });
      loadAllWorkers();
      loadStats();
    } catch (e) { setError(e.message); }
  };

  const runCleanup = async () => {
    try {
      await api('/api/workers-admin/cleanup', { method: 'POST' });
      loadStats();
    } catch (e) { setError(e.message); }
  };

  const saveCtxEntry = async () => {
    if (!ctxForm) return;
    setSaving(true);
    setError('');
    try {
      if (ctxForm.id) {
        await api(`/api/workers-admin/global-ctx/${ctxForm.id}`, { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(ctxForm) });
      } else {
        await api('/api/workers-admin/global-ctx', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(ctxForm) });
      }
      setCtxForm(null);
      loadGlobalCtx();
    } catch (e) { setError(e.message); }
    finally { setSaving(false); }
  };

  const toggleCtxEntry = async (entry) => {
    try {
      await api(`/api/workers-admin/global-ctx/${entry.id}`, { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ enabled: !entry.enabled }) });
      loadGlobalCtx();
    } catch (e) { setError(e.message); }
  };

  const deleteCtxEntry = async (entry) => {
    if (!confirm(`Delete global ctx function "${entry.name}"?`)) return;
    try {
      await api(`/api/workers-admin/global-ctx/${entry.id}`, { method: 'DELETE' });
      loadGlobalCtx();
    } catch (e) { setError(e.message); }
  };

  const fmtTime = (t) => t ? t.replace('T', ' ').slice(0, 19) : '-';
  const fmtBytes = (b) => {
    if (!b) return '0 B';
    const u = ['B', 'KB', 'MB', 'GB'];
    const i = Math.floor(Math.log(b) / Math.log(1024));
    return (b / Math.pow(1024, i)).toFixed(i > 0 ? 1 : 0) + ' ' + u[i];
  };

  const settingLabels = {
    max_memory_mb: { label: 'Max Memory (MB)', desc: 'Per-worker V8 isolate memory limit' },
    max_cpu_timeout_ms: { label: 'Max CPU Time (ms)', desc: 'Per-invocation execution timeout' },
    max_workers_per_user: { label: 'Max Workers per User', desc: 'Limit on workers per invite code' },
    max_script_size_kb: { label: 'Max Script Size (KB)', desc: 'Maximum worker script size' },
    max_kv_entries: { label: 'Max KV Entries', desc: 'Per-worker KV entry limit' },
    max_kv_value_size_kb: { label: 'Max KV Value Size (KB)', desc: 'Maximum size per KV value' },
    runs_retention_days: { label: 'Runs Retention (days)', desc: 'How long to keep run history' },
  };

  return (
    <>
      <h2>Workers Admin</h2>
      <div className="page-sub">Global workers platform management</div>

      {error && <div style={{background:'rgba(255,69,58,0.1)',border:'1px solid var(--red)',borderRadius:8,padding:'8px 12px',marginBottom:12,fontSize:13,color:'var(--red)'}}>{error}</div>}

      <div style={{display:'flex',gap:8,marginBottom:16,flexWrap:'wrap'}}>
        {['overview','settings','workers','global-ctx'].map(t => (
          <button key={t} className={tab === t ? 'btn-sm' : 'btn-sm btn-ghost'} onClick={() => { setTab(t); if (t === 'workers') loadAllWorkers(); if (t === 'overview') loadStats(); if (t === 'global-ctx') loadGlobalCtx(); }}
            style={tab === t ? {background:'var(--accent)',color:'#fff'} : {}}>
            {t === 'overview' ? 'Overview' : t === 'settings' ? 'Global Settings' : t === 'workers' ? 'All Workers' : 'Global Context'}
          </button>
        ))}
      </div>

      {tab === 'overview' && stats && (
        <div style={{display:'grid',gridTemplateColumns:'repeat(auto-fill,minmax(180px,1fr))',gap:12}}>
          {[
            { label: 'Total Workers', value: stats.totalWorkers },
            { label: 'Active Workers', value: stats.activeWorkers },
            { label: 'Unique Owners', value: stats.uniqueOwners },
            { label: 'Total Runs', value: stats.totalRuns.toLocaleString() },
            { label: 'Total Errors', value: stats.totalErrors.toLocaleString() },
            { label: 'Runs Today', value: stats.runsToday.toLocaleString() },
            { label: 'Total Size', value: fmtBytes(stats.totalSize) },
            { label: 'Active Crons', value: stats.activeCrons },
          ].map(s => (
            <div key={s.label} className="profile-card" style={{padding:'16px',textAlign:'center'}}>
              <div style={{fontSize:24,fontWeight:700,color:'var(--text)'}}>{s.value}</div>
              <div style={{fontSize:12,color:'var(--text-dim)',marginTop:4}}>{s.label}</div>
            </div>
          ))}
          <div className="profile-card" style={{padding:'16px',textAlign:'center',cursor:'pointer'}} onClick={runCleanup}>
            <div style={{fontSize:24}}>🧹</div>
            <div style={{fontSize:12,color:'var(--text-dim)',marginTop:4}}>Clean Old Runs</div>
          </div>
        </div>
      )}

      {tab === 'settings' && settings && (
        <div className="profile-card" style={{maxWidth:600}}>
          <h3>Global Limits</h3>
          <p style={{fontSize:12,color:'var(--text-dim)',marginBottom:16}}>These limits apply to all workers across all users.</p>
          {Object.entries(settingLabels).map(([key, meta]) => (
            <div key={key} style={{marginBottom:16}}>
              <label style={{fontSize:13,fontWeight:600,display:'block',marginBottom:2}}>{meta.label}</label>
              <div style={{fontSize:11,color:'var(--text-dim)',marginBottom:4}}>{meta.desc}</div>
              <input type="number" value={settings[key] || ''} onChange={e => setSettings({...settings, [key]: e.target.value})}
                style={{width:200,padding:'6px 10px',background:'var(--bg)',border:'1px solid var(--border)',borderRadius:6,fontSize:14,color:'var(--text)'}} />
            </div>
          ))}
          <button className="btn-sm" onClick={saveSettings} disabled={saving}>{saving ? 'Saving...' : 'Save Settings'}</button>
        </div>
      )}

      {tab === 'workers' && (
        <div className="profile-card" style={{maxWidth:'none'}}>
          <div style={{display:'flex',justifyContent:'space-between',alignItems:'center',marginBottom:16}}>
            <h3 style={{margin:0}}>All Registered Workers ({allWorkers.length})</h3>
            <button className="btn-sm btn-ghost" onClick={loadAllWorkers} disabled={loading}>{loading ? 'Loading...' : 'Refresh'}</button>
          </div>
          {allWorkers.length === 0 && <p style={{color:'var(--text-dim)',fontSize:13}}>No workers registered yet.</p>}
          {allWorkers.length > 0 && (
            <div style={{overflowX:'auto'}}>
              <table style={{width:'100%',borderCollapse:'collapse',fontSize:13}}>
                <thead><tr style={{borderBottom:'1px solid var(--border)'}}>
                  <th style={{textAlign:'left',padding:'8px',color:'var(--text-dim)'}}>Name</th>
                  <th style={{textAlign:'left',padding:'8px',color:'var(--text-dim)'}}>Owner</th>
                  <th style={{textAlign:'left',padding:'8px',color:'var(--text-dim)'}}>Status</th>
                  <th style={{textAlign:'left',padding:'8px',color:'var(--text-dim)'}}>Runs</th>
                  <th style={{textAlign:'left',padding:'8px',color:'var(--text-dim)'}}>Errors</th>
                  <th style={{textAlign:'left',padding:'8px',color:'var(--text-dim)'}}>Size</th>
                  <th style={{textAlign:'left',padding:'8px',color:'var(--text-dim)'}}>Crons</th>
                  <th style={{textAlign:'left',padding:'8px',color:'var(--text-dim)'}}>KV</th>
                  <th style={{textAlign:'left',padding:'8px',color:'var(--text-dim)'}}>Mem/CPU</th>
                  <th style={{textAlign:'left',padding:'8px',color:'var(--text-dim)'}}>Last Run</th>
                  <th style={{textAlign:'left',padding:'8px',color:'var(--text-dim)'}}>Actions</th>
                </tr></thead>
                <tbody>{allWorkers.map(w => (
                  <tr key={w.id} style={{borderBottom:'1px solid var(--border)'}}>
                    <td style={{padding:'8px',fontWeight:600}}>{w.name}</td>
                    <td style={{padding:'8px',fontFamily:'monospace',fontSize:11,color:'var(--text-dim)'}}>{w.owner_code}</td>
                    <td style={{padding:'8px'}}><span style={{fontSize:11,padding:'2px 6px',borderRadius:4,background:w.enabled?'rgba(52,199,89,0.15)':'rgba(255,69,58,0.15)',color:w.enabled?'var(--green)':'var(--red)'}}>{w.enabled ? 'Active' : 'Disabled'}</span></td>
                    <td style={{padding:'8px'}}>{w.total_runs}</td>
                    <td style={{padding:'8px',color:w.total_errors > 0 ? 'var(--red)' : 'var(--text-dim)'}}>{w.total_errors}</td>
                    <td style={{padding:'8px'}}>{fmtBytes(w.size_bytes)}</td>
                    <td style={{padding:'8px'}}>{w.active_crons || 0}</td>
                    <td style={{padding:'8px'}}>{w.kv_count || 0}</td>
                    <td style={{padding:'8px',fontSize:11}}>{w.memory_limit_mb}MB / {w.cpu_timeout_ms}ms</td>
                    <td style={{padding:'8px',fontSize:12,color:'var(--text-dim)'}}>{fmtTime(w.last_run_at)}</td>
                    <td style={{padding:'8px'}}>
                      <div style={{display:'flex',gap:4}}>
                        <button className="btn-sm btn-ghost" onClick={() => toggleWorker(w.id)} style={{fontSize:11}}>{w.enabled ? 'Disable' : 'Enable'}</button>
                        <button className="btn-sm btn-ghost" onClick={() => deleteWorker(w.id, w.name)} style={{fontSize:11,color:'var(--red)'}}>Delete</button>
                      </div>
                    </td>
                  </tr>
                ))}</tbody>
              </table>
            </div>
          )}
        </div>
      )}

      {tab === 'global-ctx' && (
        <>
          <div className="profile-card" style={{maxWidth:'none'}}>
            <div style={{display:'flex',justifyContent:'space-between',alignItems:'center',marginBottom:12}}>
              <div>
                <h3 style={{margin:0}}>Global Context Functions</h3>
                <p style={{fontSize:12,color:'var(--text-dim)',margin:'4px 0 0'}}>Host-side functions exposed to all workers via the <code>ctx</code> object. These run in Node.js, not in the V8 isolate.</p>
              </div>
              <button className="btn-sm" onClick={() => setCtxForm({ name: '', args: '', code: '', description: '', public: true })}>+ Add Function</button>
            </div>

            {globalCtx.length === 0 && !ctxForm && <p style={{color:'var(--text-dim)',fontSize:13}}>No global context functions defined yet.</p>}

            {globalCtx.length > 0 && (
              <div style={{overflowX:'auto'}}>
                <table style={{width:'100%',borderCollapse:'collapse',fontSize:13}}>
                  <thead><tr style={{borderBottom:'1px solid var(--border)'}}>
                    <th style={{textAlign:'left',padding:'8px',color:'var(--text-dim)'}}>Name</th>
                    <th style={{textAlign:'left',padding:'8px',color:'var(--text-dim)'}}>Signature</th>
                    <th style={{textAlign:'left',padding:'8px',color:'var(--text-dim)'}}>Description</th>
                    <th style={{textAlign:'left',padding:'8px',color:'var(--text-dim)'}}>Status</th>
                    <th style={{textAlign:'left',padding:'8px',color:'var(--text-dim)'}}>Visibility</th>
                    <th style={{textAlign:'left',padding:'8px',color:'var(--text-dim)'}}>Actions</th>
                  </tr></thead>
                  <tbody>{globalCtx.map(e => (
                    <tr key={e.id} style={{borderBottom:'1px solid var(--border)'}}>
                      <td style={{padding:'8px',fontWeight:600,fontFamily:'SF Mono,Menlo,Consolas,monospace'}}>ctx.{e.name}</td>
                      <td style={{padding:'8px',fontFamily:'SF Mono,Menlo,Consolas,monospace',fontSize:12,color:'var(--text-dim)'}}>({e.args || ''})</td>
                      <td style={{padding:'8px',color:'var(--text-dim)',maxWidth:300}}>{e.description || '—'}</td>
                      <td style={{padding:'8px'}}><span style={{fontSize:11,padding:'2px 6px',borderRadius:4,background:e.enabled?'rgba(52,199,89,0.15)':'rgba(255,69,58,0.15)',color:e.enabled?'var(--green)':'var(--red)'}}>{e.enabled ? 'Active' : 'Disabled'}</span></td>
                      <td style={{padding:'8px'}}><span style={{fontSize:11,padding:'2px 6px',borderRadius:4,background:e.public?'rgba(100,210,255,0.15)':'rgba(255,255,255,0.06)',color:e.public?'#64d2ff':'var(--text-dim)'}}>{e.public ? 'Public' : 'Hidden'}</span></td>
                      <td style={{padding:'8px'}}>
                        <div style={{display:'flex',gap:4}}>
                          <button className="btn-sm btn-ghost" onClick={() => setCtxForm({ ...e })} style={{fontSize:11}}>Edit</button>
                          <button className="btn-sm btn-ghost" onClick={() => toggleCtxEntry(e)} style={{fontSize:11}}>{e.enabled ? 'Disable' : 'Enable'}</button>
                          <button className="btn-sm btn-ghost" onClick={() => deleteCtxEntry(e)} style={{fontSize:11,color:'var(--red)'}}>Delete</button>
                        </div>
                      </td>
                    </tr>
                  ))}</tbody>
                </table>
              </div>
            )}
          </div>

          {ctxForm && (
            <div className="profile-card" style={{maxWidth:700,marginTop:16}}>
              <h3>{ctxForm.id ? 'Edit' : 'New'} Global Context Function</h3>
              <div style={{marginBottom:12}}>
                <label style={{fontSize:12,color:'var(--text-dim)',display:'block',marginBottom:4}}>Function Name (valid JS identifier)</label>
                <input value={ctxForm.name} onChange={e => setCtxForm({...ctxForm, name: e.target.value})} placeholder="getRate"
                  style={{width:'100%',maxWidth:300,padding:'8px 12px',background:'var(--bg)',border:'1px solid var(--border)',borderRadius:8,fontSize:14,color:'var(--text)',fontFamily:'SF Mono,Menlo,Consolas,monospace'}} />
              </div>
              <div style={{marginBottom:12}}>
                <label style={{fontSize:12,color:'var(--text-dim)',display:'block',marginBottom:4}}>Arguments (comma-separated parameter names)</label>
                <input value={ctxForm.args} onChange={e => setCtxForm({...ctxForm, args: e.target.value})} placeholder="currency, format"
                  style={{width:'100%',maxWidth:400,padding:'8px 12px',background:'var(--bg)',border:'1px solid var(--border)',borderRadius:8,fontSize:14,color:'var(--text)',fontFamily:'SF Mono,Menlo,Consolas,monospace'}} />
              </div>
              <div style={{marginBottom:12}}>
                <label style={{fontSize:12,color:'var(--text-dim)',display:'block',marginBottom:4}}>Description (shown to workers users)</label>
                <input value={ctxForm.description} onChange={e => setCtxForm({...ctxForm, description: e.target.value})} placeholder="Convert currency using live rates"
                  style={{width:'100%',padding:'8px 12px',background:'var(--bg)',border:'1px solid var(--border)',borderRadius:8,fontSize:14,color:'var(--text)'}} />
              </div>
              <div style={{marginBottom:12}}>
                <div style={{fontSize:12,color:'var(--text-dim)',marginBottom:8}}>API reference</div>
                <label style={{display:'flex',alignItems:'center',gap:8,marginBottom:6,cursor:'pointer',fontSize:14}}>
                  <input type="radio" name="ctx-public" checked={ctxForm.public !== false && ctxForm.public !== 0} onChange={() => setCtxForm({...ctxForm, public: true})} style={{width:'auto',flexShrink:0}} />
                  Public function
                </label>
                <label style={{display:'flex',alignItems:'center',gap:8,cursor:'pointer',fontSize:14}}>
                  <input type="radio" name="ctx-public" checked={ctxForm.public === false || ctxForm.public === 0} onChange={() => setCtxForm({...ctxForm, public: false})} style={{width:'auto',flexShrink:0}} />
                  Hidden
                </label>
              </div>
              <div style={{marginBottom:12}}>
                <label style={{fontSize:12,color:'var(--text-dim)',display:'block',marginBottom:4}}>Function Body (Node.js — runs on host, not in isolate)</label>
                <ScriptEditor value={ctxForm.code} onChange={v => setCtxForm({...ctxForm, code: v})} minHeight={200} />
              </div>
              <div style={{fontSize:12,color:'var(--text-dim)',marginBottom:12,padding:'8px 12px',background:'rgba(255,255,255,0.03)',borderRadius:8,border:'1px solid var(--border)'}}>
                <strong>Preview:</strong> Workers will call this as <code>ctx.{ctxForm.name || '…'}({ctxForm.args || ''})</code>
              </div>
              <div style={{display:'flex',gap:8}}>
                <button className="btn-sm" onClick={saveCtxEntry} disabled={saving || !ctxForm.name || !ctxForm.code}>{saving ? 'Saving...' : ctxForm.id ? 'Update' : 'Create'}</button>
                <button className="btn-sm btn-ghost" onClick={() => setCtxForm(null)}>Cancel</button>
              </div>
            </div>
          )}
        </>
      )}
    </>
  );
}
