import { useState, useEffect, useMemo, useCallback } from 'react';
import { api } from '../api/client';
import { useWebSocket } from '../hooks/useWebSocket';
import type { Agent, HashrateSample } from '../types';
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 '../components/Fleet/FleetPanels.css';
import '../components/Fleet/FleetToolbar.css';
import '../components/Fleet/AgentRemoteActions.css';
import './Pages.css';

export default function AgentsPage() {
  const { agents: liveAgents, isConnected, agentLogs, latestMessage } = 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 [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('');

  useEffect(() => {
    api.listAgents()
      .then(setAgents)
      .catch((err) => setLoadError(err instanceof Error ? err.message : 'Failed to load agents'))
      .finally(() => setLoading(false));
  }, []);

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

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

  const filteredAgents = useMemo(
    () => filterFleetAgents(agents, filters),
    [agents, 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);
    }
  };

  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 handleBulkAction = async (action: string) => {
    const ids = [...selectedIds];
    if (ids.length === 0) 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 === 'stop' && !window.confirm(`Stop miner on ${onlineIds.length} agent(s)?`)) return;

    setBulkBusy(true);
    try {
      await api.sendBulkCommand(onlineIds, action);
    } catch (err) {
      console.error(err);
    } 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>

      {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 miner to a Windows machine 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}
              onBulkAction={handleBulkAction}
              bulkBusy={bulkBusy}
            />
            <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))}
                  latestWsMessage={latestMessage}
                />
              ))}
              {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)}
                />
                <button type="button" className="btn btn-outline btn-sm" disabled={metaSaving} onClick={() => void saveMeta()}>
                  {metaSaving ? 'Saving…' : 'Save notes & tags'}
                </button>
                {metaMsg && <span className="form-hint">{metaMsg}</span>}
              </div>

              <div className="agent-detail-grid">
                <div className="detail-item">
                  <span className="detail-label">Status</span>
                  <span className={`status-badge ${selectedAgent.status}`}>{selectedAgent.status}</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>
                <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'}
                  latestWsMessage={latestMessage}
                  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>
      )}
      <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>
  );
}
