import { useState, useEffect, useMemo, useCallback, useRef } from 'react';
import { api } from '../api/client';
import { useWebSocket } from '../hooks/useWebSocket';
import type { Agent, HashrateSample, ServerInfo } from '../types';
import LatencyBadge from '../components/Fleet/LatencyBadge';
import HashrateChart from '../components/Charts/HashrateChart';
import NeonCard from '../components/NeonCard/NeonCard';
import AgentRemoteActions from '../components/Fleet/AgentRemoteActions';
import AgentListItem from '../components/Fleet/AgentListItem';
import FleetToolbar from '../components/Fleet/FleetToolbar';
import {
  DEFAULT_FLEET_FILTERS,
  filterFleetAgents,
  agentIsIdleMiner,
  formatHashrate,
  formatUptime,
} from '../help/fleetFilters';
import type { FleetFilterState } from '../help/fleetFilters';
import { downloadScreenshotFromBase64, sanitizeScreenshotBase64 } from '../help/screenshotDownload';
import { groupsForAgent } from '../help/fleetGroups';
import { useFleetGroups } from '../hooks/useFleetGroups';
import CreateGroupModal from '../components/Fleet/CreateGroupModal';
import FleetGroupsStrip from '../components/Fleet/FleetGroupsStrip';
import '../components/Fleet/FleetToolbar.css';
import './Pages.css';

function QuickDeployPanel({ serverInfo }: { serverInfo: ServerInfo | null }) {
  const [copied, setCopied] = useState<string | null>(null);

  const base = serverInfo?.suggested_url?.replace(/\/$/, '') ?? window.location.origin;

  const copy = (text: string, key: string) => {
    navigator.clipboard.writeText(text).then(() => {
      setCopied(key);
      setTimeout(() => setCopied(null), 2000);
    });
  };

  const ps1 = `iex (irm '${base}/install.ps1')`;
  const sh  = `curl -sL ${base}/install.sh | bash`;
  const dlWin  = `${base}/get?os=windows`;
  const dlLin  = `${base}/get?os=linux`;
  const dlMac  = `${base}/get?os=darwin`;

  const Row = ({ label, cmd, id }: { label: string; cmd: string; id: string }) => (
    <div style={{ display: 'flex', alignItems: 'center', gap: '0.5rem', marginBottom: '0.4rem' }}>
      <span className="font-tech" style={{ minWidth: '5rem', color: 'var(--clr-amber)', fontSize: '0.75rem' }}>{label}</span>
      <code style={{ flex: 1, background: 'rgba(0,0,0,0.4)', padding: '0.3rem 0.6rem', borderRadius: '4px', fontSize: '0.8rem', color: '#eee', overflowX: 'auto', whiteSpace: 'nowrap' }}>{cmd}</code>
      <button className="btn btn-sm" onClick={() => copy(cmd, id)} style={{ whiteSpace: 'nowrap', minWidth: '4.5rem' }}>
        {copied === id ? '✓ Copied' : 'Copy'}
      </button>
    </div>
  );

  return (
    <NeonCard accent="cyan" style={{ marginBottom: '1.25rem' }}>
      <div style={{ display: 'flex', alignItems: 'center', gap: '0.75rem', marginBottom: '0.75rem' }}>
        <span style={{ fontSize: '1.2rem' }}>⚡</span>
        <div>
          <strong className="font-display" style={{ fontSize: '1rem' }}>One-liner Quick Deploy</strong>
          <p className="form-hint" style={{ margin: 0 }}>
            Run any of these commands on a remote machine — the agent downloads itself and connects back automatically.
            No files to transfer manually.
          </p>
        </div>
      </div>

      <div style={{ marginBottom: '0.75rem' }}>
        <div className="font-tech" style={{ fontSize: '0.7rem', color: 'var(--clr-dim)', marginBottom: '0.4rem', textTransform: 'uppercase', letterSpacing: '0.08em' }}>Install &amp; run (auto-launches)</div>
        <Row label="Windows" cmd={ps1} id="ps1" />
        <Row label="Linux/Mac" cmd={sh} id="sh" />
      </div>

      <div>
        <div className="font-tech" style={{ fontSize: '0.7rem', color: 'var(--clr-dim)', marginBottom: '0.4rem', textTransform: 'uppercase', letterSpacing: '0.08em' }}>Direct download only (saves file)</div>
        <Row label="Windows" cmd={dlWin} id="dlw" />
        <Row label="Linux" cmd={dlLin} id="dll" />
        <Row label="macOS" cmd={dlMac} id="dlm" />
      </div>
    </NeonCard>
  );
}

export default function AgentsPage() {
  const { agents: liveAgents, isConnected, agentLogs, commandResults } = useWebSocket();
  const [agents, setAgents] = useState<Agent[]>([]);
  const [selectedAgent, setSelectedAgent] = useState<Agent | null>(null);
  const [expandedId, setExpandedId] = useState<string | null>(null);
  const [selectedIds, setSelectedIds] = useState<Set<string>>(new Set());
  const [filters, setFilters] = useState<FleetFilterState>(DEFAULT_FLEET_FILTERS);
  const [bulkBusy, setBulkBusy] = useState(false);
  const [hashrateHistory, setHashrateHistory] = useState<HashrateSample[]>([]);
  const [loading, setLoading] = useState(true);
  const [serverInfo, setServerInfo] = useState<ServerInfo | null>(null);
  const [loadError, setLoadError] = useState('');
  const [logContent, setLogContent] = useState('');
  const [logLoading, setLogLoading] = useState(false);
  const [notesDraft, setNotesDraft] = useState('');
  const [tagsDraft, setTagsDraft] = useState('');
  const [metaSaving, setMetaSaving] = useState(false);
  const [metaMsg, setMetaMsg] = useState('');
  const isConnectedRef = useRef(isConnected);
  isConnectedRef.current = isConnected;
  const screenshotWatchId = useRef<string | null>(null);
  const screenshotSeqRef = useRef(0);
  const [showGroupModal, setShowGroupModal] = useState(false);
  const { groups, addGroup, removeGroup } = useFleetGroups();

  const onlineAgentIds = useMemo(
    () => new Set(agents.filter((a) => a.status === 'online').map((a) => a.id)),
    [agents]
  );

  useEffect(() => {
    if (!commandResults?.length || !screenshotWatchId.current) return;
    const watch = screenshotWatchId.current;
    for (const r of commandResults) {
      if (r._seq <= screenshotSeqRef.current) continue;
      if (r.agent_id !== watch || r.action !== 'screenshot') continue;
      screenshotSeqRef.current = r._seq;
      screenshotWatchId.current = null;
      const label = agents.find((a) => a.id === watch)?.name ?? watch.slice(0, 8);
      if (r.success && r.message) {
        const ok = downloadScreenshotFromBase64(sanitizeScreenshotBase64(r.message), label);
        if (!ok) alert(`Screenshot from ${label} failed — empty or invalid image.`);
      } else {
        alert(`Screenshot failed on ${label}: ${r.message ?? 'unknown error'}`);
      }
      break;
    }
  }, [commandResults, agents]);

  useEffect(() => {
    let cancelled = false;
    api.listAgents()
      .then((data) => {
        if (!cancelled && !isConnectedRef.current) setAgents(data);
      })
      .catch((err) => {
        if (!cancelled) setLoadError(err instanceof Error ? err.message : 'Failed to load agents');
      })
      .finally(() => {
        if (!cancelled) setLoading(false);
      });
    api.getServerInfo().then(setServerInfo).catch(() => {});
    return () => {
      cancelled = true;
    };
  }, []);

  useEffect(() => {
    if (!selectedAgent) return;
    setNotesDraft(selectedAgent.notes || '');
    setTagsDraft((selectedAgent.tags || []).join(', '));
  }, [selectedAgent?.id]);

  useEffect(() => {
    if (!isConnected) return;
    setAgents(liveAgents);
    if (!selectedAgent) return;
    const updated = liveAgents.find((a) => a.id === selectedAgent.id);
    if (updated) {
      setSelectedAgent(updated);
    } else {
      setSelectedAgent(null);
      setLogContent('');
    }
  }, [liveAgents, isConnected, selectedAgent?.id]);

  useEffect(() => {
    if (selectedAgent && agentLogs[selectedAgent.id]) {
      setLogContent(agentLogs[selectedAgent.id]);
    }
  }, [selectedAgent?.id, agentLogs]);

  // Sort: online first, then by last_seen desc, then alphabetical
  const sortedAgents = useMemo(() => [...agents].sort((a, b) => {
    if (a.status === 'online' && b.status !== 'online') return -1;
    if (a.status !== 'online' && b.status === 'online') return 1;
    const ta = a.last_seen ? new Date(a.last_seen).getTime() : 0;
    const tb = b.last_seen ? new Date(b.last_seen).getTime() : 0;
    if (tb !== ta) return tb - ta;
    return a.name.localeCompare(b.name);
  }), [agents]);

  const filteredAgents = useMemo(
    () => filterFleetAgents(sortedAgents, filters),
    [sortedAgents, filters]
  );

  const refreshLog = async (refresh = false) => {
    if (!selectedAgent) return;
    setLogLoading(true);
    try {
      const res = await api.getAgentLog(selectedAgent.id, refresh);
      setLogContent(res.content || '');
    } catch (err) {
      setLogContent(err instanceof Error ? err.message : 'Failed to load log');
    } finally {
      setLogLoading(false);
    }
  };

  const selectAgent = async (agent: Agent) => {
    setSelectedAgent(agent);
    setNotesDraft(agent.notes || '');
    setTagsDraft((agent.tags || []).join(', '));
    setMetaMsg('');
    setLogContent('');
    try {
      const history = await api.getAgentStats(agent.id, 60);
      setHashrateHistory(history);
    } catch (err) {
      console.error(err);
    }
    // Auto-fetch sysinfo so the terminal is pre-populated immediately
    if (agent.status === 'online') {
      setTimeout(() => {
        api.sendAgentCommand(agent.id, 'sysinfo').catch(() => {});
      }, 300);
    }
  };

  const saveMeta = async () => {
    if (!selectedAgent) return;
    setMetaSaving(true);
    setMetaMsg('');
    const tags = tagsDraft.split(',').map((t) => t.trim()).filter(Boolean);
    try {
      const res = await api.updateAgentMeta(selectedAgent.id, notesDraft, tags);
      const updated = res.agent;
      setAgents((prev) => prev.map((a) => (a.id === updated.id ? { ...a, ...updated } : a)));
      setSelectedAgent((prev) => (prev?.id === updated.id ? { ...prev, ...updated } : prev));
      setMetaMsg('Saved');
      setTimeout(() => setMetaMsg(''), 2000);
    } catch (err) {
      setMetaMsg(err instanceof Error ? err.message : 'Save failed');
    } finally {
      setMetaSaving(false);
    }
  };

  const toggleSelect = useCallback((id: string, on: boolean) => {
    setSelectedIds((prev) => {
      const next = new Set(prev);
      if (on) next.add(id);
      else next.delete(id);
      return next;
    });
  }, []);

  const handleDeleteAgent = async (agentId: string) => {
    if (!window.confirm('Remove this machine from the fleet roster? This cannot be undone.')) return;
    try {
      await api.deleteAgent(agentId);
      setAgents((prev) => prev.filter((a) => a.id !== agentId));
      if (selectedAgent?.id === agentId) setSelectedAgent(null);
      setSelectedIds((prev) => { const next = new Set(prev); next.delete(agentId); return next; });
    } catch (err) {
      alert(err instanceof Error ? err.message : 'Delete failed');
    }
  };

  const handleUninstallAndDelete = async (agent: Agent) => {
    const label = agent.status === 'online'
      ? `Uninstall the miner from "${agent.name}" and remove it from the roster?`
      : `"${agent.name}" is offline — it cannot be remotely uninstalled. Remove from roster only?`;
    if (!window.confirm(label)) return;
    if (agent.status === 'online') {
      try {
        await api.sendAgentCommand(agent.id, 'uninstall', {});
      } catch {
        // Non-fatal — proceed to delete the record regardless
      }
    }
    try {
      await api.deleteAgent(agent.id);
      setAgents((prev) => prev.filter((a) => a.id !== agent.id));
      if (selectedAgent?.id === agent.id) setSelectedAgent(null);
      setSelectedIds((prev) => { const next = new Set(prev); next.delete(agent.id); return next; });
    } catch (err) {
      alert(err instanceof Error ? err.message : 'Delete failed');
    }
  };

  const handleBulkAction = async (action: string) => {
    const ids = [...selectedIds];
    if (ids.length === 0) return;

    if (action === 'delete') {
      if (!window.confirm(`Permanently remove ${ids.length} machine(s) from the fleet roster?`)) return;
      setBulkBusy(true);
      try {
        await api.bulkDeleteAgents(ids);
        setAgents((prev) => prev.filter((a) => !ids.includes(a.id)));
        if (selectedAgent && ids.includes(selectedAgent.id)) setSelectedAgent(null);
        setSelectedIds(new Set());
      } catch (err) {
        alert(err instanceof Error ? err.message : 'Bulk delete failed');
      } finally {
        setBulkBusy(false);
      }
      return;
    }

    let targetIds = ids;
    if (action === 'restart_idle') {
      targetIds = agents.filter((a) => ids.includes(a.id) && agentIsIdleMiner(a)).map((a) => a.id);
      if (targetIds.length === 0) {
        alert('No selected online agents with idle hashrate (< 100 H/s).');
        return;
      }
      action = 'restart';
    }

    const onlineIds = targetIds.filter((id) => agents.find((a) => a.id === id)?.status === 'online');
    if (onlineIds.length === 0) {
      alert('No online agents in selection.');
      return;
    }

    if (action === 'screenshot') {
      if (onlineIds.length !== 1) {
        alert('Select exactly one online machine (checkbox) for screenshot.');
        return;
      }
      const id = onlineIds[0];
      const label = agents.find((a) => a.id === id)?.name ?? 'agent';
      screenshotWatchId.current = id;
      if (commandResults?.length) {
        screenshotSeqRef.current = commandResults[commandResults.length - 1]._seq;
      }
      setBulkBusy(true);
      try {
        const res = await api.sendAgentCommand(id, 'screenshot');
        if (res.success === false) {
          screenshotWatchId.current = null;
          alert(res.error ?? 'Screenshot command rejected');
        }
      } catch (err) {
        screenshotWatchId.current = null;
        alert(err instanceof Error ? err.message : 'Screenshot failed');
      } finally {
        setBulkBusy(false);
      }
      return;
    }

    if (action === 'stop' && !window.confirm(`Stop miner on ${onlineIds.length} agent(s)?`)) return;

    setBulkBusy(true);
    try {
      await api.sendBulkCommand(onlineIds, action);
    } catch (err) {
      console.error(err);
      alert(err instanceof Error ? err.message : 'Bulk command failed');
    } finally {
      setBulkBusy(false);
    }
  };

  return (
    <div className="page fade-in command-deck">
      <header className="deck-hero">
        <div className="deck-hero-text">
          <p className="deck-eyebrow font-tech">FLEET REGISTRY</p>
          <h1>Fleet Roster</h1>
          <p className="page-subtitle">Compact list — click a row to expand quick actions or inspect full telemetry on the right.</p>
        </div>
        <span className="header-count font-tech">{filteredAgents.length}/{agents.length} NODES</span>
      </header>

      <QuickDeployPanel serverInfo={serverInfo} />

      {loadError && (
        <NeonCard accent="amber" className="empty-state">
          <p>{loadError}</p>
        </NeonCard>
      )}

      {loading ? (
        <NeonCard accent="brass" className="empty-state">
          <p>Scanning network...</p>
        </NeonCard>
      ) : agents.length === 0 ? (
        <NeonCard accent="brass" className="empty-state">
          <div className="empty-icon">⚙</div>
          <h3>No agents registered</h3>
          <p>Deploy a worker to any machine (Windows, Linux, or macOS) using the Forge and it will appear here automatically.</p>
        </NeonCard>
      ) : (
        <div className="agents-layout">
          <div className="agents-list-panel">
            <FleetToolbar
              agents={agents}
              filters={filters}
              onChange={setFilters}
              selectedCount={selectedIds.size}
              filteredCount={filteredAgents.length}
              onSelectAllFiltered={() => setSelectedIds(new Set(filteredAgents.map((a) => a.id)))}
              onBulkAction={handleBulkAction}
              onCreateGroup={() => setShowGroupModal(true)}
              bulkBusy={bulkBusy}
            />
            <FleetGroupsStrip
              groups={groups}
              liveAgentIds={onlineAgentIds}
              selectedCount={selectedIds.size}
              onSelectGroup={(g) => setSelectedIds(new Set(g.agentIds))}
              onDeleteGroup={removeGroup}
              onCreateGroup={() => setShowGroupModal(true)}
            />
            <div className="agents-list">
              {filteredAgents.map((agent) => (
                <AgentListItem
                  key={agent.id}
                  agent={agent}
                  selected={selectedAgent?.id === agent.id}
                  expanded={expandedId === agent.id}
                  selectable
                  checked={selectedIds.has(agent.id)}
                  onCheck={(on) => toggleSelect(agent.id, on)}
                  onSelect={() => void selectAgent(agent)}
                  onToggleExpand={() => setExpandedId((prev) => (prev === agent.id ? null : agent.id))}
                  commandResults={commandResults}
                  memberGroups={groupsForAgent(groups, agent.id)}
                />
              ))}
              {filteredAgents.length === 0 && (
                <p className="form-hint">No agents match filters.</p>
              )}
            </div>
          </div>

          {selectedAgent && (
            <NeonCard accent="cyan" className="agent-detail" hud>
              <h2 className="font-display">{selectedAgent.name}</h2>
              {(selectedAgent.tags?.length ?? 0) > 0 && (
                <div style={{ marginBottom: '0.5rem' }}>
                  {selectedAgent.tags!.map((t) => (
                    <span key={t} className="agent-tag-chip">{t}</span>
                  ))}
                </div>
              )}

              <div className="detail-section agent-meta-editor">
                <h3>Notes &amp; Tags</h3>
                <p className="form-hint">Labels like &quot;Living room PC&quot; or &quot;Rack B&quot; — stored on the server, shown on list cards.</p>
                <textarea
                  className="input"
                  rows={2}
                  placeholder="Notes about this machine…"
                  value={notesDraft}
                  onChange={(e) => setNotesDraft(e.target.value)}
                />
                <input
                  type="text"
                  className="input mono agent-meta-tags-input"
                  placeholder="Tags: living-room, rack-b (comma separated)"
                  value={tagsDraft}
                  onChange={(e) => setTagsDraft(e.target.value)}
                />
                <div style={{ display: 'flex', gap: '0.5rem', alignItems: 'center', flexWrap: 'wrap' }}>
                  <button type="button" className="btn btn-outline btn-sm" disabled={metaSaving} onClick={() => void saveMeta()}>
                    {metaSaving ? 'Saving…' : 'Save notes & tags'}
                  </button>
                  {selectedAgent.status === 'online' && (
                    <button
                      type="button"
                      className="btn btn-sm"
                      style={{ background: 'rgba(255,100,0,0.15)', border: '1px solid #ff8844', color: '#ffaa66' }}
                      onClick={() => void handleUninstallAndDelete(selectedAgent)}
                      title="Send uninstall command to agent, then remove from roster"
                    >
                      ⚡ Uninstall + Delete
                    </button>
                  )}
                  <button
                    type="button"
                    className="btn btn-sm"
                    style={{ background: 'rgba(255,40,40,0.15)', border: '1px solid #ff4444', color: '#ff6666' }}
                    onClick={() => void handleDeleteAgent(selectedAgent.id)}
                    title="Remove this machine from the fleet roster permanently"
                  >
                    🗑 Delete from Roster
                  </button>
                </div>
                {metaMsg && <span className="form-hint">{metaMsg}</span>}
              </div>

              <div className="agent-detail-grid">
                <div className="detail-item">
                  <span className="detail-label">Status</span>
                  <span style={{ display: 'flex', alignItems: 'center', gap: '0.5rem' }}>
                    <span className={`status-badge ${selectedAgent.status}`}>{selectedAgent.status}</span>
                    {selectedAgent.status === 'online' && (
                      <LatencyBadge ms={selectedAgent.latency_ms} />
                    )}
                  </span>
                </div>
                {selectedAgent.hostname && selectedAgent.hostname !== selectedAgent.name && (
                  <div className="detail-item">
                    <span className="detail-label">Hostname</span>
                    <span className="detail-value mono">{selectedAgent.hostname}</span>
                  </div>
                )}
                <div className="detail-item">
                  <span className="detail-label">Last Seen</span>
                  <span className="detail-value" title={selectedAgent.last_seen}>
                    {selectedAgent.last_seen
                      ? new Date(selectedAgent.last_seen).toLocaleString()
                      : '—'}
                  </span>
                </div>
                <div className="detail-item">
                  <span className="detail-label">Wallet</span>
                  <span className="detail-value mono">{selectedAgent.wallet?.substring(0, 20)}...</span>
                </div>
                <div className="detail-item">
                  <span className="detail-label">IP Address</span>
                  <span className="detail-value">{selectedAgent.ip}</span>
                </div>
                <div className="detail-item">
                  <span className="detail-label">Version</span>
                  <span className="detail-value">{selectedAgent.version || 'Unknown'}</span>
                </div>
                {(selectedAgent.platform || selectedAgent.os_version) && (
                  <div className="detail-item">
                    <span className="detail-label">Platform</span>
                    <span className="detail-value">
                      {[selectedAgent.platform, selectedAgent.arch].filter(Boolean).join(' / ')}
                      {selectedAgent.os_version ? ` — ${selectedAgent.os_version}` : ''}
                    </span>
                  </div>
                )}
                <div className="detail-item">
                  <span className="detail-label">CPU Cores</span>
                  <span className="detail-value">{selectedAgent.cpu_cores}</span>
                </div>
                <div className="detail-item">
                  <span className="detail-label">Memory</span>
                  <span className="detail-value">{selectedAgent.memory_gb} GB</span>
                </div>
                <div className="detail-item">
                  <span className="detail-label">CPU Usage</span>
                  <span className="detail-value">{selectedAgent.cpu_usage_pct.toFixed(1)}%</span>
                </div>
                <div className="detail-item">
                  <span className="detail-label">Uptime</span>
                  <span className="detail-value">{formatUptime(selectedAgent.uptime_seconds)}</span>
                </div>
              </div>

              <div className="detail-section">
                <h3>Hashrate</h3>
                <div className="hashrate-detail-grid">
                  <div className="hashrate-item">
                    <span className="detail-label">15s</span>
                    <span className="hashrate-value">{formatHashrate(selectedAgent.hashrate_15s)}</span>
                  </div>
                  <div className="hashrate-item">
                    <span className="detail-label">1m</span>
                    <span className="hashrate-value">{formatHashrate(selectedAgent.hashrate_1m)}</span>
                  </div>
                  <div className="hashrate-item">
                    <span className="detail-label">15m</span>
                    <span className="hashrate-value">{formatHashrate(selectedAgent.hashrate_15m)}</span>
                  </div>
                </div>
              </div>

              <div className="detail-section">
                <h3>Shares</h3>
                <div className="shares-detail-grid">
                  <div className="share-stat good">
                    <span className="share-count">{selectedAgent.shares_good}</span>
                    <span className="share-label">Accepted</span>
                  </div>
                  <div className="share-stat bad">
                    <span className="share-count">{selectedAgent.shares_bad}</span>
                    <span className="share-label">Rejected</span>
                  </div>
                  <div className="share-stat total">
                    <span className="share-count">{selectedAgent.shares_total}</span>
                    <span className="share-label">Total</span>
                  </div>
                </div>
              </div>

              {hashrateHistory.length > 0 && (
                <div className="detail-section">
                  <h3 className="font-tech">HASHRATE TELEMETRY</h3>
                  <HashrateChart
                    title=""
                    color="#00f5ff"
                    unit="H/s"
                    height={240}
                    data={[...hashrateHistory].reverse().map((s) => ({
                      time: new Date(s.timestamp).toLocaleTimeString(),
                      value: s.hashrate,
                    }))}
                  />
                </div>
              )}

              <div className="detail-section">
                <h3>Remote Control</h3>
                {selectedAgent.status !== 'online' && (
                  <p className="form-hint">Agent is offline — remote actions are disabled until it reconnects.</p>
                )}
                <AgentRemoteActions
                  agent={selectedAgent}
                  online={selectedAgent.status === 'online'}
                  commandResults={commandResults}
                  showLiveStats
                  onCommandSent={(action: string) => {
                    if (action === 'get_log') refreshLog(true);
                  }}
                />
              </div>

              <div className="detail-section">
                <h3>Agent Log <button type="button" className="agent-action-btn" onClick={() => refreshLog(true)} disabled={logLoading || selectedAgent.status !== 'online'}>{logLoading ? '…' : 'Refresh'}</button></h3>
                <p className="form-hint">Streams miner.log when file_logging is enabled (non-stealth builds).</p>
                <pre className="log-viewer">{logContent || (selectedAgent.status === 'online' ? 'Click Fetch Log or Refresh' : 'Agent offline')}</pre>
              </div>
            </NeonCard>
          )}
        </div>
      )}
      <CreateGroupModal
        open={showGroupModal}
        agentCount={selectedIds.size}
        onClose={() => setShowGroupModal(false)}
        onCreate={(name, color) => {
          addGroup(name, color, [...selectedIds]);
          setShowGroupModal(false);
        }}
      />

      <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>
  );
}
