// Plugins (cogs) + Settings pages. Settings is focused on Discord-bot wiring only.

function PagePlugins() {
  const [state, setState] = React.useState(() => Object.fromEntries(COGS.map((c) => [c.key, c.status === 'loaded'])));
  const totalCmds = COGS.reduce((s, c) => s + c.commands, 0);
  const totalMem = COGS.reduce((s, c) => s + parseFloat(c.memory), 0).toFixed(1);

  return (
    <div className="page">
      <div className="page-head">
        <div>
          <h1 className="page-title">Plugins</h1>
          <div className="page-sub">{COGS.length} cogs · {totalCmds} commands · {totalMem} MB total</div>
        </div>
      </div>

      <div className="grid grid-3">
        {COGS.map((c) => {
          const on = state[c.key];
          return (
            <div key={c.key} className="card" style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
              <div className="row between">
                <div className="row">
                  <span style={{ width: 32, height: 32, borderRadius: 8, background: 'var(--surface-2)', display: 'grid', placeItems: 'center', color: on ? 'var(--accent)' : 'var(--text-dim)' }}>
                    <I.plug width="16" height="16"/>
                  </span>
                  <div>
                    <div style={{ fontWeight: 600, fontSize: 13.5 }}>{c.name}</div>
                    <div className="muted" style={{ fontSize: 11.5 }}>{c.desc}</div>
                  </div>
                </div>
              </div>
              <hr className="sep"/>
              <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr', gap: 6, fontSize: 11.5 }}>
                <div>
                  <div className="dim" style={{ fontSize: 10.5, textTransform: 'uppercase', letterSpacing: 0.04 }}>Commands</div>
                  <div className="mono" style={{ marginTop: 2 }}>{c.commands}</div>
                </div>
                <div>
                  <div className="dim" style={{ fontSize: 10.5, textTransform: 'uppercase', letterSpacing: 0.04 }}>Memory</div>
                  <div className="mono" style={{ marginTop: 2 }}>{c.memory}</div>
                </div>
                <div>
                  <div className="dim" style={{ fontSize: 10.5, textTransform: 'uppercase', letterSpacing: 0.04 }}>Loaded</div>
                  <div className="mono" style={{ marginTop: 2 }}>{c.loadedAt}</div>
                </div>
              </div>
              <div className="row" style={{ marginTop: 4, gap: 6 }}>
                {on
                  ? <span className="chip solid"><span className="dot" style={{ width: 5, height: 5, boxShadow: 'none' }}/>loaded</span>
                  : <span className="chip">disabled</span>}
              </div>
            </div>
          );
        })}
      </div>
    </div>
  );
}

// ────────────────────────────────────────────────────────────
// Settings — Discord bot only. Connection comes first.

function PageSettings() {
  const [tab, setTab] = React.useState('connection');
  const conn = useConn();
  const tabs = [
    { key: 'connection', label: 'Connection' },
    { key: 'bot', label: 'Bot' },
    { key: 'permissions', label: 'Permissions' },
    { key: 'alerts', label: 'Alerts' },
    { key: 'integrations', label: 'Integrations' },
    { key: 'advanced', label: 'Advanced' },
  ];

  return (
    <div className="page">
      <div className="page-head">
        <div>
          <h1 className="page-title">Settings</h1>
          <div className="page-sub">Configure the connection and behavior of your Discord bot · {conn.status === 'connected' ? <span style={{ color: 'var(--accent)' }}>● connected</span> : <span style={{ color: 'var(--text-muted)' }}>● not connected</span>}</div>
        </div>
      </div>

      <div className="tabs">
        {tabs.map((tt) => (
          <button key={tt.key} className="tab" aria-current={tab === tt.key} onClick={() => setTab(tt.key)}>
            {tt.label}
            {tt.key === 'connection' && conn.status !== 'connected' && (
              <span className="nav-badge danger" style={{ marginLeft: 6 }}>!</span>
            )}
          </button>
        ))}
      </div>

      {tab === 'connection' && <SettingsConnection/>}
      {tab === 'bot' && <SettingsBot/>}
      {tab === 'permissions' && <SettingsPermissions/>}
      {tab === 'alerts' && <SettingsAlerts/>}
      {tab === 'integrations' && <SettingsIntegrations/>}
      {tab === 'advanced' && <SettingsAdvanced/>}
    </div>
  );
}

// ── 1. Connection ──────────────────────────────────────────
function SettingsConnection() {
  const conn = useConn();
  const [endpoint, setEndpoint] = React.useState(conn.endpoint);
  const [token, setToken] = React.useState(conn.token);
  const [revealToken, setRevealToken] = React.useState(false);
  const [testing, setTesting] = React.useState(false);
  const [copied, setCopied] = React.useState(false);

  const statusMeta = {
    disconnected: { label: 'Not connected', color: 'var(--text-muted)' },
    connecting: { label: 'Connecting…', color: 'var(--warn)' },
    connected: { label: 'Connected', color: 'var(--accent)' },
    error: { label: 'Connection error', color: 'var(--danger)' },
  }[conn.status];

  const save = () => CONN.set({ endpoint, token });
  const test = async () => { save(); setTesting(true); await CONN.testConnection(); setTesting(false); };
  const disconnect = () => { CONN.set({ endpoint: '', token: '' }); setEndpoint(''); setToken(''); };
  const copySnippet = async () => {
    try { await navigator.clipboard.writeText(ADAPTER_SNIPPET); setCopied(true); setTimeout(() => setCopied(false), 1500); } catch {}
  };

  return (
    <div className="grid grid-8-4">
      <div className="col" style={{ gap: 'var(--gap-lg)' }}>
        <Card
          title="Bot endpoint"
          sub="Where this dashboard fetches live data from your running bot"
          action={<span className="chip" style={{ color: statusMeta.color, borderColor: 'transparent', background: `color-mix(in oklab, ${statusMeta.color} 14%, transparent)` }}>
            <span className="dot" style={{ width: 6, height: 6, boxShadow: 'none', background: statusMeta.color }}/>
            {statusMeta.label}
          </span>}
        >
          <div className="kv"><div className="kv-key">URL</div><div className="kv-val">
            <input className="settings-input mono" placeholder="http://localhost:3001" value={endpoint} onChange={(e) => setEndpoint(e.target.value)}/>
            <div className="muted" style={{ fontSize: 11.5, marginTop: 6, lineHeight: 1.6 }}>
              ที่อยู่ของ <span className="mono">adapter.js</span> ที่รันอยู่ในบอทของคุณ — ไม่ใช่ของ Discord
            </div>
          </div></div>
          <div className="kv"><div className="kv-key">API token</div><div className="kv-val">
            <div className="row" style={{ gap: 6 }}>
              <input
                className="settings-input mono"
                type={revealToken ? 'text' : 'password'}
                placeholder="Bearer token from your adapter config"
                value={token}
                onChange={(e) => setToken(e.target.value)}
              />
              <button className="btn" style={{ padding: '6px 10px' }} onClick={() => setRevealToken(!revealToken)}>{revealToken ? 'Hide' : 'Show'}</button>
            </div>
          </div></div>
          <div className="kv"><div className="kv-key">Auto-connect on load</div><div className="kv-val"><Switch on={conn.autoConnect} onChange={(v) => CONN.set({ autoConnect: v })}/></div></div>
          <div className="kv"><div className="kv-key">Last heartbeat</div><div className="kv-val mono">{conn.lastSeen ? conn.lastSeen.toLocaleTimeString() : '—'}</div></div>
          {conn.lastError && (
            <div className="kv"><div className="kv-key" style={{ color: 'var(--danger)' }}>Last error</div><div className="kv-val mono" style={{ color: 'var(--danger)' }}>{conn.lastError}</div></div>
          )}

          <div className="row" style={{ gap: 8, marginTop: 14 }}>
            <button className="btn primary" disabled={testing} onClick={test}>
              {testing ? 'Testing…' : 'Test & save connection'}
            </button>
            <button className="btn" onClick={save}>Save without test</button>
            <button className="btn danger" style={{ marginLeft: 'auto' }} onClick={disconnect}>Disconnect</button>
          </div>
        </Card>

        <Card
          title="Adapter snippet"
          sub="Drop this into your discord.js bot to expose /health · /metrics · /logs"
        >
          <div className="row" style={{ marginBottom: 8, gap: 8 }}>
            <span className="chip">discord.js 14</span>
            <span className="chip">express + cors</span>
            <span className="chip mono">~70 lines</span>
            <button className="btn" style={{ marginLeft: 'auto' }} onClick={copySnippet}>
              {copied ? '✓ Copied' : 'Copy snippet'}
            </button>
          </div>
          <pre className="code-block">{ADAPTER_SNIPPET}</pre>
          <div className="muted" style={{ fontSize: 12, marginTop: 10, lineHeight: 1.7 }}>
            1. <span className="mono">npm i express cors</span> ในโปรเจคบอท<br/>
            2. เซฟ snippet ข้างบนเป็น <span className="mono">adapter.js</span><br/>
            3. ใน entrypoint บอท: <span className="mono">require('./adapter')(client, {'{ port: 3001, token: process.env.DASH_TOKEN }'})</span><br/>
            4. ตั้ง <span className="mono">DASH_TOKEN</span> ใน env แล้วเอา URL + token มาใส่ด้านบน
          </div>
        </Card>

        <Card title="แล้ว URL ใส่อะไร?" sub="ขึ้นอยู่กับว่าบอทรันที่ไหน">
          <table className="tbl" style={{ marginTop: -4 }}>
            <thead><tr><th>บอทรันที่</th><th>URL</th></tr></thead>
            <tbody>
              <tr><td>เครื่องเดียวกับ browser</td><td className="mono" style={{ color: 'var(--accent)' }}>http://localhost:3001</td></tr>
              <tr><td>VPS / server (มี IP)</td><td className="mono">http://1.2.3.4:3001</td></tr>
              <tr><td>VPS + domain + reverse proxy <span className="chip solid" style={{ marginLeft: 6, fontSize: 10 }}>แนะนำ</span></td><td className="mono">https://bot.your-domain.com</td></tr>
              <tr><td>บ้าน / no public IP</td><td className="mono">https://abc.ngrok.app</td></tr>
              <tr><td>Replit / Railway / Render</td><td className="muted">URL ที่ host ให้</td></tr>
            </tbody>
          </table>
          <div className="muted" style={{ fontSize: 12, marginTop: 10, lineHeight: 1.6 }}>
            <strong style={{ color: 'var(--text)' }}>Token</strong> = ค่าที่ตั้งใน <span className="mono">DASH_TOKEN</span> ของบอท — ใส่ในช่อง API token ให้ตรงกัน
          </div>
        </Card>
      </div>

      <div className="col" style={{ gap: 'var(--gap-lg)' }}>
        <Card title="Health checklist">
          {[
            { ok: !!endpoint, label: 'Endpoint URL set' },
            { ok: !!token, label: 'API token set' },
            { ok: conn.status === 'connected', label: 'Reachable from browser' },
            { ok: conn.status === 'connected', label: 'CORS allows this origin' },
            { ok: conn.status === 'connected', label: 'Bearer auth accepted' },
            { ok: conn.status === 'connected', label: '/health returns 200 OK' },
          ].map((c, i) => (
            <div key={i} className="row" style={{ padding: '7px 0', borderBottom: i < 5 ? '1px solid var(--border)' : 0 }}>
              <span style={{
                width: 16, height: 16, borderRadius: 999,
                background: c.ok ? 'color-mix(in oklab, var(--accent) 22%, transparent)' : 'color-mix(in oklab, var(--text-dim) 22%, transparent)',
                color: c.ok ? 'var(--accent)' : 'var(--text-dim)',
                display: 'grid', placeItems: 'center', fontSize: 11, fontWeight: 700,
              }}>{c.ok ? '✓' : '·'}</span>
              <span style={{ fontSize: 12.5 }}>{c.label}</span>
            </div>
          ))}
        </Card>

        <Card title="Polling">
          <div className="kv"><div className="kv-key">/health</div><div className="kv-val mono">10 s</div></div>
          <div className="kv"><div className="kv-key">/metrics</div><div className="kv-val mono">15 s</div></div>
          <div className="kv"><div className="kv-key">/logs</div><div className="kv-val mono">5 s</div></div>
          <div className="kv"><div className="kv-key">Request timeout</div><div className="kv-val mono">3 s</div></div>
        </Card>

        <Card title="Security">
          <div style={{ fontSize: 12.5, color: 'var(--text-muted)', lineHeight: 1.7 }}>
            • Token is stored only in this browser's localStorage.<br/>
            • Never paste your <span className="mono">DISCORD_TOKEN</span> here.<br/>
            • Use HTTPS in production. Restrict CORS on the adapter to only this dashboard's origin.
          </div>
        </Card>
      </div>
    </div>
  );
}

// ── 2. Bot ─────────────────────────────────────────────────
function SettingsBot() {
  const [s, setS] = React.useState({
    name: BOT.name, prefix: SETTINGS.prefix, language: SETTINGS.language, timezone: SETTINGS.timezone,
    presence: 'Watching shift hours · /help', activity: 'watching', status: 'online',
    logChannel: SETTINGS.logChannel, errorChannel: SETTINGS.errorChannel, modChannel: '#mod-actions',
  });
  const set = (k, v) => setS({ ...s, [k]: v });

  return (
    <div className="grid grid-12-5">
      <div className="col" style={{ gap: 'var(--gap-lg)' }}>
        <Card title="Identity">
          <div className="kv"><div className="kv-key">Bot name</div><div className="kv-val"><input className="settings-input" value={s.name} onChange={(e) => set('name', e.target.value)}/></div></div>
          <div className="kv"><div className="kv-key">Default prefix</div><div className="kv-val"><input className="settings-input mono" style={{ width: 80 }} value={s.prefix} onChange={(e) => set('prefix', e.target.value)}/></div></div>
          <div className="kv"><div className="kv-key">Bot user ID</div><div className="kv-val mono">{BOT.id}</div></div>
          <div className="kv"><div className="kv-key">Owner ID</div><div className="kv-val mono">401123…</div></div>
        </Card>

        <Card title="Presence" sub="What the bot shows on its Discord profile">
          <div className="kv"><div className="kv-key">Status</div><div className="kv-val">
            <select className="settings-input" style={{ width: 160 }} value={s.status} onChange={(e) => set('status', e.target.value)}>
              <option value="online">● online</option>
              <option value="idle">◐ idle</option>
              <option value="dnd">● do not disturb</option>
              <option value="invisible">○ invisible</option>
            </select>
          </div></div>
          <div className="kv"><div className="kv-key">Activity type</div><div className="kv-val">
            <select className="settings-input" style={{ width: 160 }} value={s.activity} onChange={(e) => set('activity', e.target.value)}>
              <option>watching</option><option>playing</option><option>listening</option><option>competing</option>
            </select>
          </div></div>
          <div className="kv"><div className="kv-key">Activity text</div><div className="kv-val"><input className="settings-input" value={s.presence} onChange={(e) => set('presence', e.target.value)}/></div></div>
          <div className="kv"><div className="kv-key">Preview</div><div className="kv-val">
            <div style={{ display: 'inline-flex', alignItems: 'center', gap: 8, padding: '6px 10px', background: 'var(--bg-2)', border: '1px solid var(--border)', borderRadius: 6, fontSize: 12.5 }}>
              <div className="brand-mark" style={{ width: 22, height: 22, fontSize: 11, borderRadius: 6 }}>s</div>
              <span>{s.name}</span>
              <span className="muted">·</span>
              <span className="muted">{s.activity} {s.presence}</span>
            </div>
          </div></div>
        </Card>
      </div>

      <div className="col" style={{ gap: 'var(--gap-lg)' }}>
        <Card title="Locale">
          <div className="kv"><div className="kv-key">Language</div><div className="kv-val">
            <select className="settings-input" style={{ width: 180 }} value={s.language} onChange={(e) => set('language', e.target.value)}>
              <option value="th">ไทย (th)</option><option value="en">English (en)</option><option value="ja">日本語 (ja)</option>
            </select>
          </div></div>
          <div className="kv"><div className="kv-key">Timezone</div><div className="kv-val">
            <select className="settings-input" style={{ width: 220 }} value={s.timezone} onChange={(e) => set('timezone', e.target.value)}>
              <option>Asia/Bangkok</option><option>Asia/Tokyo</option><option>UTC</option>
            </select>
          </div></div>
          <div className="kv"><div className="kv-key">Date format</div><div className="kv-val mono">YYYY-MM-DD HH:mm</div></div>
        </Card>

        <Card title="Channels" sub="Where the bot writes ops messages">
          <div className="kv"><div className="kv-key">Logs</div><div className="kv-val mono">{s.logChannel}</div></div>
          <div className="kv"><div className="kv-key">Errors</div><div className="kv-val mono">{s.errorChannel}</div></div>
          <div className="kv"><div className="kv-key">Mod actions</div><div className="kv-val mono">{s.modChannel}</div></div>
          <div className="kv"><div className="kv-key">Weekly report</div><div className="kv-val mono">{SETTINGS.weeklyReportDay} {SETTINGS.weeklyReportTime}</div></div>
        </Card>
      </div>
    </div>
  );
}

// ── 3. Permissions ─────────────────────────────────────────
function SettingsPermissions() {
  const gates = [
    { cmd: '/ban',       roles: ['Owner', 'Admin'], gate: '2FA' },
    { cmd: '/kick',      roles: ['Owner', 'Admin', 'Moderator'], gate: null },
    { cmd: '/timeout',   roles: ['Owner', 'Admin', 'Moderator'], gate: null },
    { cmd: '/clear',     roles: ['Owner', 'Admin', 'Moderator'], gate: null },
    { cmd: '/role',      roles: ['Owner', 'Admin'], gate: null },
    { cmd: '/restart',   roles: ['Owner'], gate: 'owner-only' },
    { cmd: '/sheetstyle',roles: ['Owner'], gate: 'owner-only' },
    { cmd: '/shiftreset',roles: ['Owner'], gate: 'owner-only · 2FA' },
  ];
  return (
    <div className="grid grid-12-5">
      <Card title="Command gates" sub="Which Discord roles can invoke which commands" padding={0}>
        <table className="tbl">
          <thead><tr><th>Command</th><th>Allowed roles</th><th>Gate</th></tr></thead>
          <tbody>
            {gates.map((g) => (
              <tr key={g.cmd}>
                <td className="mono">{g.cmd}</td>
                <td>
                  <div className="row" style={{ gap: 4, flexWrap: 'wrap' }}>
                    {g.roles.map((r) => <span key={r} className="chip">{r}</span>)}
                  </div>
                </td>
                <td>{g.gate ? <span className="chip warn">{g.gate}</span> : <span className="muted" style={{ fontSize: 11.5 }}>—</span>}</td>
              </tr>
            ))}
          </tbody>
        </table>
      </Card>

      <div className="col" style={{ gap: 'var(--gap-lg)' }}>
        <Card title="Owners">
          <div className="kv"><div className="kv-key">Primary</div><div className="kv-val mono">401123…</div></div>
          <div className="kv"><div className="kv-key">Co-owners</div><div className="kv-val">
            <div className="row" style={{ gap: 4, flexWrap: 'wrap' }}>
              <span className="chip mono">552901…</span>
              <span className="chip mono">661044…</span>
            </div>
          </div></div>
        </Card>
      </div>
    </div>
  );
}

// ── 4. Alerts ──────────────────────────────────────────────
function SettingsAlerts() {
  const [chans, setChans] = React.useState({ errors: true, latency: true, newGuild: true, weekly: true, modActions: false });
  const set = (k, v) => setChans({ ...chans, [k]: v });
  return (
    <div className="grid grid-12-5">
      <Card title="Alert rules" sub="What triggers a notification">
        {[
          { k: 'errors', label: 'Unhandled errors', sub: 'Any uncaught exception in a command handler' },
          { k: 'latency', label: 'Latency spike', sub: 'Gateway p99 > 150 ms for 1 minute' },
          { k: 'newGuild', label: 'New guild joined', sub: 'Bot added to a new server' },
          { k: 'weekly', label: 'Weekly report digest', sub: 'Every Sunday at 20:00 ICT' },
          { k: 'modActions', label: 'Mod actions', sub: 'Any ban / kick / timeout fires an alert' },
        ].map((r) => (
          <div key={r.k} className="kv">
            <div>
              <div style={{ fontSize: 13 }}>{r.label}</div>
              <div className="muted" style={{ fontSize: 11.5 }}>{r.sub}</div>
            </div>
            <div className="kv-val" style={{ justifySelf: 'end' }}><Switch on={chans[r.k]} onChange={(v) => set(r.k, v)}/></div>
          </div>
        ))}
      </Card>

      <div className="col" style={{ gap: 'var(--gap-lg)' }}>
        <Card title="Discord webhook" sub="Where alerts get delivered">
          <div className="kv"><div className="kv-key">URL</div><div className="kv-val"><input className="settings-input mono" defaultValue="https://discord.com/api/webhooks/****/****"/></div></div>
          <div className="kv"><div className="kv-key">Embed color</div><div className="kv-val mono" style={{ color: 'var(--accent)' }}>#7cffb2</div></div>
        </Card>

        <Card title="Quiet hours">
          <div className="kv"><div className="kv-key">From</div><div className="kv-val mono">23:00</div></div>
          <div className="kv"><div className="kv-key">To</div><div className="kv-val mono">07:00</div></div>
          <div className="kv"><div className="kv-key">Skip for</div><div className="kv-val">
            <div className="row" style={{ gap: 4, flexWrap: 'wrap' }}>
              <span className="chip danger">errors</span>
              <span className="chip warn">latency</span>
            </div>
          </div></div>
        </Card>
      </div>
    </div>
  );
}

// ── 5. Integrations ────────────────────────────────────────
function SettingsIntegrations() {
  const integrations = [
    { name: 'Google Sheets', desc: 'Mirror shift / duty logs to a spreadsheet', status: 'connected', icon: '📄', detail: SETTINGS.sheets.spreadsheet },
    { name: 'PM2', desc: 'Process manager · restart bot from dashboard', status: 'connected', icon: '⚡', detail: 'pid 18402' },
    { name: 'GitHub', desc: 'Auto-pull on push to main · view source from /restart', status: 'connected', icon: '⌥', detail: 'org/shift-bot' },
    { name: 'Custom webhook', desc: 'POST bot events to your URL', status: 'idle', icon: '↗', detail: 'not configured' },
  ];
  return (
    <div className="grid grid-2">
      {integrations.map((i) => (
        <Card key={i.name}
          title={<span style={{ display: 'inline-flex', alignItems: 'center', gap: 8 }}><span style={{ fontSize: 16 }}>{i.icon}</span>{i.name}</span>}
          sub={i.desc}
        >
          <div className="kv"><div className="kv-key">Status</div><div className="kv-val">
            {i.status === 'connected'
              ? <span className="chip solid"><span className="dot" style={{ width: 5, height: 5, boxShadow: 'none' }}/>connected</span>
              : <span className="chip">not connected</span>}
          </div></div>
          <div className="kv"><div className="kv-key">Detail</div><div className="kv-val mono ellipsis" style={{ maxWidth: 260 }}>{i.detail}</div></div>
        </Card>
      ))}
    </div>
  );
}

// ── 6. Advanced ────────────────────────────────────────────
function SettingsAdvanced() {
  const conn = useConn();
  const live = conn.status === 'connected';
  const [busy, setBusy] = React.useState(null);

  // Fire an owner action against the real bot. `confirmText` → toastConfirm gate.
  const runAction = async (name, body, confirmText) => {
    if (!live) return;
    if (confirmText && !(await toastConfirm(confirmText, { danger: true }))) return;
    setBusy(name);
    try {
      await REALDATA.doAction(name, body);
      toast('สำเร็จ: ' + name, 'success');
      REALDATA.refreshAll().catch(() => {});
    } catch (e) {
      toast('ล้มเหลว: ' + (e && e.message ? e.message : e), 'error');
    } finally {
      setBusy(null);
    }
  };

  return (
    <div className="grid grid-12-5">
      <div className="col" style={{ gap: 'var(--gap-lg)' }}>
        <Card title="Rate limits">
          <div className="kv"><div className="kv-key">Per-user cooldown</div><div className="kv-val mono">3 s</div></div>
          <div className="kv"><div className="kv-key">Per-guild burst</div><div className="kv-val mono">30 / min</div></div>
          <div className="kv"><div className="kv-key">Slash commands</div><div className="kv-val mono">120 / min global</div></div>
        </Card>

        <Card title="Logging">
          <div className="kv"><div className="kv-key">Retention</div><div className="kv-val mono">14 days</div></div>
          <div className="kv"><div className="kv-key">Format</div><div className="kv-val mono">json</div></div>
        </Card>
      </div>

      <div className="col" style={{ gap: 'var(--gap-lg)' }}>
        <Card title="Bot actions" sub={live ? 'ส่งคำสั่ง owner ไปยังบอทจริง' : 'เชื่อมต่อบอทก่อนเพื่อใช้งาน'}>
          <div className="muted" style={{ fontSize: 12, marginBottom: 12, lineHeight: 1.6 }}>
            {live
              ? 'คำสั่งเหล่านี้ทำงานกับบอทที่กำลังรันอยู่ทันที'
              : 'ปุ่มจะใช้ได้เมื่อเชื่อมต่อบอทแล้ว (Settings → Connection)'}
          </div>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
            <button className="btn" disabled={!live || busy} onClick={() => runAction('weeklyreport')}>{busy === 'weeklyreport' ? '…' : 'Send weekly report'}</button>
            <button className="btn" disabled={!live || busy} onClick={() => runAction('sheetstyle')}>{busy === 'sheetstyle' ? '…' : 'Restyle Google Sheet'}</button>
            <button className="btn" disabled={!live || busy} onClick={() => runAction('reload')}>{busy === 'reload' ? '…' : 'Hot-reload all commands'}</button>
            <button className="btn danger" disabled={!live || busy} onClick={() => runAction('restart', null, 'รีสตาร์ทบอทตอนนี้? บอทจะออฟไลน์ชั่วครู่')}>{busy === 'restart' ? '…' : 'Restart bot (PM2)'}</button>
          </div>
        </Card>

        <Card title="Danger zone">
          <div className="muted" style={{ fontSize: 12, marginBottom: 12, lineHeight: 1.6 }}>
            These actions are irreversible and affect the live bot.
          </div>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
            <button className="btn danger" disabled={!live || busy} onClick={() => runAction('shiftreset', { mode: 'active' }, 'ล้าง shift ที่กำลังเปิดอยู่ทั้งหมด?')}>{busy === 'shiftreset' ? '…' : 'Reset active shifts'}</button>
            <button className="btn danger" disabled={!live || busy} onClick={() => runAction('shiftreset', { mode: 'history' }, 'ล้างประวัติ shift ทั้งหมด? กู้คืนไม่ได้')}>Reset shift history</button>
            <button className="btn danger" disabled={!live || busy} onClick={() => runAction('shiftreset', { mode: 'panels' }, 'ล้าง duty panels ทั้งหมด?')}>Reset duty panels</button>
            <button className="btn danger" disabled={!live || busy} onClick={() => runAction('shiftreset', { mode: 'all' }, 'ล้างข้อมูล shift ทั้งหมด (active + history + panels)? กู้คืนไม่ได้')}>Reset ALL shift data</button>
          </div>
        </Card>
      </div>
    </div>
  );
}

Object.assign(window, { PagePlugins, PageSettings });
