import { useState, useEffect, useRef, useCallback } from 'react';
import {
  Activity, Clock, FileText, AlertTriangle, Search, RefreshCw,
  RotateCcw, Box, BarChart2
} from 'lucide-react';
import { monitoringAPI, logsAPI, containerAPI } from '../services/api';

const API_SERVICES = ['ALL', 'network', 'wireguard', 'routing', 'email', 'calendar', 'files', 'vault', 'container', 'api'];
const LEVELS = ['ALL', 'DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL'];
const LEVEL_COLORS = {
  DEBUG: 'text-gray-500',
  INFO: 'text-blue-400',
  WARNING: 'text-yellow-400',
  ERROR: 'text-red-400',
  CRITICAL: 'text-red-500 font-bold',
};

function LevelBadge({ level }) {
  const cls = LEVEL_COLORS[level?.toUpperCase()] || 'text-gray-400';
  return <span className={`font-mono text-xs shrink-0 ${cls}`}>[{level || '?'}]</span>;
}

function LogLine({ entry }) {
  if (!entry || entry.raw_line !== undefined) {
    return <div className="font-mono text-xs text-gray-300 py-0.5 break-all">{entry?.raw_line || ''}</div>;
  }
  return (
    <div className="font-mono text-xs py-0.5 flex gap-2 flex-wrap">
      <span className="text-gray-500 shrink-0">{String(entry.timestamp || '').slice(0, 19)}</span>
      <LevelBadge level={entry.level} />
      {entry.service && <span className="text-purple-400 shrink-0">[{entry.service}]</span>}
      <span className="text-gray-200 break-all">{entry.message || ''}</span>
    </div>
  );
}

// ── Tab: API Service Logs ───────────────────────────────────────────────────
function ApiServiceLogsTab() {
  const [service, setService] = useState('ALL');
  const [level, setLevel] = useState('ALL');
  const [lines, setLines] = useState(100);
  const [query, setQuery] = useState('');
  const [logs, setLogs] = useState([]);
  const [loading, setLoading] = useState(false);
  const [autoRefresh, setAutoRefresh] = useState(false);
  const intervalRef = useRef(null);

  const doFetch = useCallback(async () => {
    setLoading(true);
    try {
      const allSvcs = API_SERVICES.filter(s => s !== 'ALL');
      if (service === 'ALL' || query) {
        const res = await logsAPI.searchLogs({
          query: query || '',
          services: service === 'ALL' ? allSvcs : [service],
          level: level === 'ALL' ? undefined : level,
        });
        setLogs(res.data.results || []);
      } else {
        const res = await logsAPI.getServiceLogs(service, level, lines);
        const raw = res.data.logs || [];
        const parsed = raw.map(line => {
          try { return JSON.parse(line); } catch { return { raw_line: line }; }
        });
        setLogs(parsed.reverse());
      }
    } catch (e) {
      setLogs([{ raw_line: `Error: ${e.message}` }]);
    } finally {
      setLoading(false);
    }
  }, [service, level, lines, query]);

  useEffect(() => { doFetch(); }, [service, level, lines]);

  useEffect(() => {
    if (autoRefresh) {
      intervalRef.current = setInterval(doFetch, 5000);
    } else {
      clearInterval(intervalRef.current);
    }
    return () => clearInterval(intervalRef.current);
  }, [autoRefresh, doFetch]);

  return (
    <div className="space-y-3">
      <p className="text-xs text-gray-500 bg-gray-50 rounded px-3 py-2">
        These are structured logs written by the API backend for each service manager (wireguard, network, routing, etc.).
        They are stored in <code>/app/data/logs/&lt;service&gt;.log</code> and can be rotated from the Statistics tab.
      </p>

      <div className="flex flex-wrap gap-2 items-center">
        <select className="border rounded px-2 py-1 text-sm" value={service} onChange={e => setService(e.target.value)}>
          {API_SERVICES.map(s => <option key={s} value={s}>{s === 'ALL' ? 'ALL services' : s}</option>)}
        </select>
        <select className="border rounded px-2 py-1 text-sm" value={level} onChange={e => setLevel(e.target.value)}>
          {LEVELS.map(l => <option key={l} value={l}>{l}</option>)}
        </select>
        {service !== 'ALL' && (
          <select className="border rounded px-2 py-1 text-sm" value={lines} onChange={e => setLines(Number(e.target.value))}>
            {[50, 100, 200, 500].map(n => <option key={n} value={n}>{n} lines</option>)}
          </select>
        )}
        <div className="flex gap-1 flex-1 min-w-40">
          <input
            className="border rounded px-2 py-1 text-sm flex-1"
            placeholder="Search…"
            value={query}
            onChange={e => setQuery(e.target.value)}
            onKeyDown={e => e.key === 'Enter' && doFetch()}
          />
          <button className="btn btn-secondary px-2 py-1 text-sm" onClick={doFetch}><Search className="h-4 w-4" /></button>
          {query && <button className="btn btn-secondary px-2 py-1 text-sm" onClick={() => { setQuery(''); }}>✕</button>}
        </div>
        <button
          className={`btn px-2 py-1 text-sm ${autoRefresh ? 'btn-primary' : 'btn-secondary'}`}
          title="Auto-refresh 5s"
          onClick={() => setAutoRefresh(v => !v)}
        >
          <RefreshCw className={`h-4 w-4 ${autoRefresh ? 'animate-spin' : ''}`} />
        </button>
        <button className="btn btn-secondary px-2 py-1 text-sm" onClick={doFetch}><RefreshCw className="h-4 w-4" /></button>
      </div>

      <div className="bg-gray-900 rounded-lg p-3 h-[500px] overflow-y-auto">
        {loading && logs.length === 0 ? (
          <div className="text-gray-400 text-sm">Loading…</div>
        ) : logs.length === 0 ? (
          <div className="text-gray-500 text-sm">No entries found.</div>
        ) : (
          logs.map((entry, i) => <LogLine key={i} entry={entry} />)
        )}
      </div>
      <div className="text-xs text-gray-400">{logs.length} entries</div>
    </div>
  );
}

// ── Tab: Container Logs ─────────────────────────────────────────────────────
function ContainerLogsTab() {
  const [containers, setContainers] = useState([]);
  const [selected, setSelected] = useState('cell-api');
  const [tail, setTail] = useState(100);
  const [lines, setLines] = useState([]);
  const [loading, setLoading] = useState(false);
  const [autoRefresh, setAutoRefresh] = useState(false);
  const intervalRef = useRef(null);

  useEffect(() => {
    containerAPI.listContainers()
      .then(res => {
        const names = (res.data || [])
          .map(c => c.name || c.Names?.[0]?.replace('/', ''))
          .filter(Boolean)
          .sort();
        setContainers(names);
        if (names.length > 0 && !names.includes(selected)) setSelected(names[0]);
      })
      .catch(() => {});
  }, []);

  const doFetch = useCallback(async () => {
    if (!selected) return;
    setLoading(true);
    try {
      const res = await logsAPI.getStoredContainerLogs(selected, tail);
      setLines(res.data.lines || []);
    } catch (e) {
      setLines([`Error: ${e.message}`]);
    } finally {
      setLoading(false);
    }
  }, [selected, tail]);

  useEffect(() => { doFetch(); }, [selected, tail]);

  useEffect(() => {
    if (autoRefresh) {
      intervalRef.current = setInterval(doFetch, 5000);
    } else {
      clearInterval(intervalRef.current);
    }
    return () => clearInterval(intervalRef.current);
  }, [autoRefresh, doFetch]);

  return (
    <div className="space-y-3">
      <p className="text-xs text-gray-500 bg-gray-50 rounded px-3 py-2">
        Container stdout/stderr collected from Docker and stored in <code>/app/data/logs/container_&lt;name&gt;.log</code>.
        Each fetch appends new lines since last collection. Rotate from the Statistics tab.
      </p>

      <div className="flex flex-wrap gap-2 items-center">
        <select className="border rounded px-2 py-1 text-sm" value={selected} onChange={e => setSelected(e.target.value)}>
          {(containers.length > 0 ? containers : ['cell-api']).map(c => (
            <option key={c} value={c}>{c}</option>
          ))}
        </select>
        <select className="border rounded px-2 py-1 text-sm" value={tail} onChange={e => setTail(Number(e.target.value))}>
          {[50, 100, 200, 500].map(n => <option key={n} value={n}>{n} lines</option>)}
        </select>
        <button
          className={`btn px-2 py-1 text-sm ${autoRefresh ? 'btn-primary' : 'btn-secondary'}`}
          title="Auto-refresh 5s"
          onClick={() => setAutoRefresh(v => !v)}
        >
          <RefreshCw className={`h-4 w-4 ${autoRefresh ? 'animate-spin' : ''}`} />
        </button>
        <button className="btn btn-secondary px-2 py-1 text-sm" onClick={doFetch}><RefreshCw className="h-4 w-4" /></button>
      </div>

      <div className="bg-gray-900 text-green-300 rounded-lg p-3 h-[500px] overflow-y-auto font-mono text-xs">
        {loading && lines.length === 0 ? (
          <span className="text-gray-400">Loading…</span>
        ) : lines.length === 0 ? (
          <span className="text-gray-500">No stored logs. Click refresh to collect.</span>
        ) : (
          lines.map((l, i) => <div key={i} className="py-0.5 break-all">{l}</div>)
        )}
      </div>
      <div className="text-xs text-gray-400">{lines.length} lines stored</div>
    </div>
  );
}

// ── Tab: Statistics & Rotation ──────────────────────────────────────────────
function StatisticsTab() {
  const [files, setFiles] = useState([]);
  const [loading, setLoading] = useState(false);
  const [rotating, setRotating] = useState(null);
  const [msg, setMsg] = useState('');

  const doFetch = async () => {
    setLoading(true);
    try {
      const res = await logsAPI.getLogFiles();
      setFiles(res.data || []);
    } catch (e) {
      console.error(e);
    } finally {
      setLoading(false);
    }
  };

  useEffect(() => { doFetch(); }, []);

  const rotate = async (file) => {
    const label = file ? file.label : 'all log files';
    if (!window.confirm(`Rotate logs for ${label}?\nThe current file will be archived and a new one started.`)) return;
    const key = file ? file.name : 'all';
    setRotating(key);
    setMsg('');
    try {
      if (file) {
        await logsAPI.rotateLogs(file.name, file.kind);
      } else {
        // Rotate all: service logs via old endpoint, container logs individually
        await Promise.all(files.map(f => logsAPI.rotateLogs(f.name, f.kind)));
      }
      setMsg('Rotation complete.');
      await doFetch();
    } catch (e) {
      setMsg(`Error: ${e.message}`);
    } finally {
      setRotating(null);
    }
  };

  const fmtSize = bytes => {
    if (!bytes) return '0 B';
    if (bytes < 1024) return `${bytes} B`;
    if (bytes < 1024 ** 2) return `${(bytes / 1024).toFixed(1)} KB`;
    return `${(bytes / 1024 ** 2).toFixed(2)} MB`;
  };

  const serviceFiles = files.filter(f => f.kind === 'service');
  const containerFiles = files.filter(f => f.kind === 'container');

  const FileTable = ({ rows, title }) => (
    <div>
      <h4 className="font-medium text-gray-700 mb-2">{title}</h4>
      {rows.length === 0 ? (
        <p className="text-sm text-gray-400">No files yet.</p>
      ) : (
        <table className="min-w-full text-sm border rounded mb-4">
          <thead>
            <tr className="bg-gray-100">
              <th className="px-3 py-2 text-left">Name</th>
              <th className="px-3 py-2 text-right">Size</th>
              <th className="px-3 py-2 text-left">Last Modified</th>
              <th className="px-3 py-2 text-center">Rotate</th>
            </tr>
          </thead>
          <tbody>
            {rows.map(f => (
              <tr key={f.name} className="border-t hover:bg-gray-50">
                <td className="px-3 py-2 font-mono text-xs">{f.label}</td>
                <td className="px-3 py-2 text-right font-mono text-xs">{fmtSize(f.size)}</td>
                <td className="px-3 py-2 text-xs text-gray-500">{f.modified?.slice(0, 19)}</td>
                <td className="px-3 py-2 text-center">
                  <button
                    className="btn btn-secondary text-xs px-2 py-0.5"
                    onClick={() => rotate(f)}
                    disabled={rotating === f.name}
                  >
                    <RotateCcw className={`h-3 w-3 inline ${rotating === f.name ? 'animate-spin' : ''}`} />
                  </button>
                </td>
              </tr>
            ))}
          </tbody>
        </table>
      )}
    </div>
  );

  return (
    <div className="space-y-4">
      <div className="flex justify-between items-center">
        <h3 className="text-lg font-medium text-gray-900">Log Files & Rotation</h3>
        <div className="flex gap-2">
          <button className="btn btn-secondary text-sm" onClick={doFetch}>
            <RefreshCw className="h-4 w-4 mr-1 inline" /> Refresh
          </button>
          <button
            className="btn btn-secondary text-sm"
            onClick={() => rotate(null)}
            disabled={rotating === 'all'}
          >
            <RotateCcw className="h-4 w-4 mr-1 inline" /> Rotate All
          </button>
        </div>
      </div>

      {msg && <div className="text-sm text-green-700 bg-green-50 rounded px-3 py-2">{msg}</div>}

      {loading ? <div className="text-gray-500 text-sm">Loading…</div> : (
        <>
          <FileTable rows={serviceFiles} title="API Service Logs" />
          <FileTable rows={containerFiles} title="Container Logs (stored)" />
        </>
      )}
    </div>
  );
}

// ── Tab: Health History ─────────────────────────────────────────────────────
function HealthHistoryTab() {
  const [healthHistory, setHealthHistory] = useState([]);
  const [loading, setLoading] = useState(false);

  const doFetch = async () => {
    setLoading(true);
    try {
      const res = await monitoringAPI.getHealthHistory();
      setHealthHistory(res.data || []);
    } catch (e) {
      console.error(e);
    } finally {
      setLoading(false);
    }
  };

  useEffect(() => { doFetch(); }, []);

  const SvcCol = ({ data }) => (data?.status === 'online' || data?.running === true)
    ? <span className="text-green-600">OK</span>
    : <span className="text-red-600 font-bold">Down</span>;

  return (
    <div className="space-y-4">
      <div className="flex justify-between items-center">
        <h3 className="text-lg font-medium text-gray-900">Health History</h3>
        <button className="btn btn-secondary text-sm" onClick={doFetch}>
          <RefreshCw className="h-4 w-4 mr-1 inline" /> Refresh
        </button>
      </div>
      {loading ? <div className="text-gray-500 text-sm">Loading…</div> : (
        <div className="overflow-x-auto">
          <table className="min-w-full text-sm">
            <thead>
              <tr className="bg-gray-100">
                {['Timestamp', 'Network', 'WireGuard', 'Email', 'Calendar', 'Files', 'Routing', 'Vault', 'Alerts'].map(h => (
                  <th key={h} className="px-2 py-1 text-left">{h}</th>
                ))}
              </tr>
            </thead>
            <tbody>
              {healthHistory.map((h, i) => (
                <tr key={i} className={h.alerts?.length > 0 ? 'bg-red-50' : ''}>
                  <td className="px-2 py-1 font-mono text-xs">{h.timestamp}</td>
                  <td className="px-2 py-1"><SvcCol data={h.network} /></td>
                  <td className="px-2 py-1"><SvcCol data={h.wireguard} /></td>
                  <td className="px-2 py-1"><SvcCol data={h.email} /></td>
                  <td className="px-2 py-1"><SvcCol data={h.calendar} /></td>
                  <td className="px-2 py-1"><SvcCol data={h.files} /></td>
                  <td className="px-2 py-1"><SvcCol data={h.routing} /></td>
                  <td className="px-2 py-1"><SvcCol data={h.vault} /></td>
                  <td className="px-2 py-1">
                    {h.alerts?.length > 0
                      ? h.alerts.map((a, j) => (
                          <span key={j} className="text-red-700 font-semibold flex items-center gap-1">
                            <AlertTriangle className="h-3 w-3 text-red-500" />{a}
                          </span>
                        ))
                      : <span className="text-green-600">—</span>}
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      )}
    </div>
  );
}

// ── Main ────────────────────────────────────────────────────────────────────
const TABS = [
  { id: 'api', label: 'API Service Logs', icon: FileText },
  { id: 'container', label: 'Container Logs', icon: Box },
  { id: 'statistics', label: 'Statistics & Rotation', icon: BarChart2 },
  { id: 'health', label: 'Health History', icon: Activity },
];

function Logs() {
  const [tab, setTab] = useState('api');

  return (
    <div>
      <div className="mb-6">
        <h1 className="text-2xl font-bold text-gray-900">Logs & Monitoring</h1>
        <p className="mt-1 text-gray-600">API service logs, container stdout/stderr, rotation, and health history.</p>
      </div>

      <div className="mb-4 flex gap-2 border-b">
        {TABS.map(({ id, label, icon: Icon }) => (
          <button
            key={id}
            className={`px-4 py-2 text-sm font-medium flex items-center gap-1 border-b-2 transition-colors ${
              tab === id ? 'border-primary-600 text-primary-700' : 'border-transparent text-gray-600 hover:text-gray-900'
            }`}
            onClick={() => setTab(id)}
          >
            <Icon className="h-4 w-4" />
            {label}
          </button>
        ))}
      </div>

      <div className="card">
        {tab === 'api' && <ApiServiceLogsTab />}
        {tab === 'container' && <ContainerLogsTab />}
        {tab === 'statistics' && <StatisticsTab />}
        {tab === 'health' && <HealthHistoryTab />}
      </div>
    </div>
  );
}

export default Logs;
