"use client";

import { FormEvent, useCallback, useEffect, useMemo, useState } from "react";
import { useRouter } from "next/navigation";
import { EVENT } from "@/lib/event";
import { INDIAN_STATES } from "@/lib/constants";
import type { AdminVisitor } from "@/lib/admin-reports";

type Tab =
  | "registrations"
  | "by-state"
  | "by-date"
  | "activity"
  | "website-audit"
  | "security"
  | "network"
  | "infra";

type Summary = {
  total: number;
  states: number;
  earliest_arrival: string;
  latest_arrival: string;
};

type StateRow = { state: string; count: number };
type DateRow = { arrival_date: string; count: number };

type ActivityLog = {
  id: number;
  admin_id: number | null;
  username: string | null;
  action: string;
  resource: string | null;
  outcome: string;
  ip: string | null;
  created_at: string;
};

type AuditLog = {
  id: number;
  step: string;
  channel: string;
  outcome: string;
  ip: string | null;
  created_at: string;
};

type SecurityEvent = {
  id: number;
  category: string;
  severity: string;
  title: string;
  source_ip: string | null;
  status: string;
  created_at: string;
};

type NetworkData = {
  summary: {
    last_hour_requests: number;
    last_hour_throttled_or_blocked: number;
    approx_rps: number;
    by_app: { app: string; c: number }[];
  };
  top_ips: { client_ip: string; request_count: number; errors: number }[];
  top_paths: { path_norm: string; request_count: number; avg_latency: number }[];
  blocklist: {
    id: number;
    client_ip: string;
    reason: string;
    source: string;
    expires_at: string | null;
    created_at: string;
  }[];
  recent_blocks: {
    client_ip: string;
    path_norm: string;
    status_code: number;
    created_at: string;
    rate_limit_action: string;
  }[];
};

type InfraData = {
  process: {
    uptime_seconds: number;
    node_version: string;
    memory: {
      rss: number;
      heap_total: number;
      heap_used: number;
    };
  };
  host: {
    hostname: string;
    platform: string;
    uptime_seconds: number;
    loadavg: number[];
    cpus: number;
    freemem: number;
    totalmem: number;
  };
  mysql: { ok: boolean; latency_ms: number | null; error?: string };
  disk: { available: boolean; note?: string; freemem_bytes?: number; totalmem_bytes?: number };
  snmp: unknown[];
};

const TABS: [Tab, string][] = [
  ["registrations", "All registrations"],
  ["by-state", "Report by state"],
  ["by-date", "Report by visit date"],
  ["activity", "Activity"],
  ["website-audit", "Website audit"],
  ["security", "Security"],
  ["network", "Network"],
  ["infra", "Infra health"],
];

function formatDisplayDate(iso: string) {
  if (!iso) return "—";
  const d = new Date(iso + "T00:00:00");
  if (Number.isNaN(d.getTime())) return iso;
  return d.toLocaleDateString("en-IN", {
    day: "numeric",
    month: "short",
    year: "numeric",
  });
}

function formatDateTime(value: string) {
  if (!value) return "—";
  const d = new Date(value);
  if (Number.isNaN(d.getTime())) return value;
  return d.toLocaleString("en-IN", {
    day: "numeric",
    month: "short",
    year: "numeric",
    hour: "2-digit",
    minute: "2-digit",
  });
}

function formatBytes(n: number) {
  if (!n && n !== 0) return "—";
  const units = ["B", "KB", "MB", "GB"];
  let v = n;
  let i = 0;
  while (v >= 1024 && i < units.length - 1) {
    v /= 1024;
    i += 1;
  }
  return `${v.toFixed(i === 0 ? 0 : 1)} ${units[i]}`;
}

function formatUptime(seconds: number) {
  const h = Math.floor(seconds / 3600);
  const m = Math.floor((seconds % 3600) / 60);
  const s = Math.floor(seconds % 60);
  if (h > 48) return `${Math.floor(h / 24)}d ${h % 24}h`;
  if (h > 0) return `${h}h ${m}m`;
  return `${m}m ${s}s`;
}

function severityClass(sev: string) {
  switch (sev) {
    case "critical":
      return "text-[var(--danger)]";
    case "high":
      return "text-[#e8a060]";
    case "medium":
      return "text-[var(--gold)]";
    default:
      return "text-[var(--muted)]";
  }
}

export function AdminDashboard() {
  const router = useRouter();
  const [tab, setTab] = useState<Tab>("registrations");
  const [summary, setSummary] = useState<Summary | null>(null);
  const [byState, setByState] = useState<StateRow[]>([]);
  const [byDate, setByDate] = useState<DateRow[]>([]);
  const [visitors, setVisitors] = useState<AdminVisitor[]>([]);
  const [total, setTotal] = useState(0);
  const [page, setPage] = useState(1);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState("");

  const [q, setQ] = useState("");
  const [state, setState] = useState("");
  const [arrivalFrom, setArrivalFrom] = useState("");
  const [arrivalTo, setArrivalTo] = useState("");
  const [applied, setApplied] = useState({
    q: "",
    state: "",
    arrivalFrom: "",
    arrivalTo: "",
  });

  const [activityLogs, setActivityLogs] = useState<ActivityLog[]>([]);
  const [auditLogs, setAuditLogs] = useState<AuditLog[]>([]);
  const [securityEvents, setSecurityEvents] = useState<SecurityEvent[]>([]);
  const [network, setNetwork] = useState<NetworkData | null>(null);
  const [infra, setInfra] = useState<InfraData | null>(null);
  const [sectionLoading, setSectionLoading] = useState(false);
  const [blockIp, setBlockIp] = useState("");
  const [blockReason, setBlockReason] = useState("");
  const [blockMsg, setBlockMsg] = useState("");

  const pageSize = 25;
  const totalPages = Math.max(1, Math.ceil(total / pageSize));

  const maxStateCount = useMemo(
    () => Math.max(1, ...byState.map((r) => r.count)),
    [byState],
  );
  const maxDateCount = useMemo(
    () => Math.max(1, ...byDate.map((r) => r.count)),
    [byDate],
  );

  const ensureAuth = useCallback(
    (res: Response) => {
      if (res.status === 401) {
        router.replace("/login");
        return false;
      }
      return true;
    },
    [router],
  );

  const loadReports = useCallback(async () => {
    const res = await fetch("/api/reports");
    if (!ensureAuth(res)) return;
    const data = await res.json();
    if (!data.ok) throw new Error(data.error || "Failed to load reports");
    setSummary(data.summary);
    setByState(data.by_state || []);
    setByDate(data.by_arrival_date || []);
  }, [ensureAuth]);

  const loadVisitors = useCallback(async () => {
    const params = new URLSearchParams({
      page: String(page),
      page_size: String(pageSize),
    });
    if (applied.q) params.set("q", applied.q);
    if (applied.state) params.set("state", applied.state);
    if (applied.arrivalFrom) params.set("arrival_from", applied.arrivalFrom);
    if (applied.arrivalTo) params.set("arrival_to", applied.arrivalTo);

    const res = await fetch(`/api/visitors?${params}`);
    if (!ensureAuth(res)) return;
    const data = await res.json();
    if (!data.ok) throw new Error(data.error || "Failed to load visitors");
    setVisitors(data.visitors || []);
    setTotal(data.total || 0);
  }, [applied, ensureAuth, page]);

  const loadActivity = useCallback(async () => {
    const res = await fetch("/api/activity?limit=100");
    if (!ensureAuth(res)) return;
    const data = await res.json();
    if (!data.ok) throw new Error(data.error || "Failed to load activity");
    setActivityLogs(data.logs || []);
  }, [ensureAuth]);

  const loadAudit = useCallback(async () => {
    const res = await fetch("/api/website-audit?limit=100");
    if (!ensureAuth(res)) return;
    const data = await res.json();
    if (!data.ok) throw new Error(data.error || "Failed to load audit");
    setAuditLogs(data.logs || []);
  }, [ensureAuth]);

  const loadSecurity = useCallback(async () => {
    const res = await fetch("/api/security?limit=100");
    if (!ensureAuth(res)) return;
    const data = await res.json();
    if (!data.ok) throw new Error(data.error || "Failed to load security");
    setSecurityEvents(data.events || []);
  }, [ensureAuth]);

  const loadNetwork = useCallback(async () => {
    const res = await fetch("/api/network");
    if (!ensureAuth(res)) return;
    const data = await res.json();
    if (!data.ok) throw new Error(data.error || "Failed to load network");
    setNetwork(data);
  }, [ensureAuth]);

  const loadInfra = useCallback(async () => {
    const res = await fetch("/api/infra");
    if (!ensureAuth(res)) return;
    const data = await res.json();
    if (!data.ok) throw new Error(data.error || "Failed to load infra");
    setInfra(data);
  }, [ensureAuth]);

  useEffect(() => {
    let cancelled = false;
    (async () => {
      setLoading(true);
      setError("");
      try {
        await Promise.all([loadReports(), loadVisitors()]);
      } catch (e) {
        if (!cancelled) {
          setError(e instanceof Error ? e.message : "Something went wrong");
        }
      } finally {
        if (!cancelled) setLoading(false);
      }
    })();
    return () => {
      cancelled = true;
    };
  }, [loadReports, loadVisitors]);

  useEffect(() => {
    if (
      tab === "registrations" ||
      tab === "by-state" ||
      tab === "by-date"
    ) {
      return;
    }
    let cancelled = false;
    (async () => {
      setSectionLoading(true);
      setError("");
      try {
        if (tab === "activity") await loadActivity();
        if (tab === "website-audit") await loadAudit();
        if (tab === "security") await loadSecurity();
        if (tab === "network") await loadNetwork();
        if (tab === "infra") await loadInfra();
      } catch (e) {
        if (!cancelled) {
          setError(e instanceof Error ? e.message : "Something went wrong");
        }
      } finally {
        if (!cancelled) setSectionLoading(false);
      }
    })();
    return () => {
      cancelled = true;
    };
  }, [tab, loadActivity, loadAudit, loadSecurity, loadNetwork, loadInfra]);

  function applyFilters(e: FormEvent) {
    e.preventDefault();
    setPage(1);
    setApplied({
      q: q.trim(),
      state,
      arrivalFrom,
      arrivalTo,
    });
  }

  function clearFilters() {
    setQ("");
    setState("");
    setArrivalFrom("");
    setArrivalTo("");
    setPage(1);
    setApplied({ q: "", state: "", arrivalFrom: "", arrivalTo: "" });
  }

  const siteUrl =
    process.env.NEXT_PUBLIC_SITE_URL?.replace(/\/$/, "") ||
    "http://localhost:3001";

  async function logout() {
    await fetch("/api/logout", { method: "POST" });
    router.replace("/login");
  }

  async function updateSecurityStatus(
    id: number,
    status: "acknowledged" | "resolved",
  ) {
    setBlockMsg("");
    const res = await fetch("/api/security", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ id, status }),
    });
    if (!ensureAuth(res)) return;
    const data = await res.json();
    if (!data.ok) {
      setError(data.error || "Could not update event");
      return;
    }
    await loadSecurity();
  }

  async function addBlock(e: FormEvent) {
    e.preventDefault();
    setBlockMsg("");
    const res = await fetch("/api/network/blocklist", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({
        client_ip: blockIp.trim(),
        reason: blockReason.trim() || "Manual block from admin",
      }),
    });
    if (!ensureAuth(res)) return;
    const data = await res.json();
    if (!data.ok) {
      setBlockMsg(data.error || "Could not block IP");
      return;
    }
    setBlockIp("");
    setBlockReason("");
    setBlockMsg("IP blocked.");
    await loadNetwork();
  }

  async function removeBlock(id: number) {
    setBlockMsg("");
    const res = await fetch(`/api/network/blocklist?id=${id}`, {
      method: "DELETE",
    });
    if (!ensureAuth(res)) return;
    const data = await res.json();
    if (!data.ok) {
      setBlockMsg(data.error || "Could not unblock");
      return;
    }
    setBlockMsg("IP unblocked.");
    await loadNetwork();
  }

  return (
    <div className="mx-auto max-w-6xl px-5 py-8">
      <div className="flex flex-wrap items-start justify-between gap-4">
        <div>
          <p className="text-xs font-semibold uppercase tracking-[0.16em] text-[var(--gold)]">
            Admin · {EVENT.shortName} {EVENT.year}
          </p>
          <h1 className="font-display mt-1 text-3xl font-semibold md:text-4xl">
            Registrations, reports & security
          </h1>
          <p className="mt-2 max-w-xl text-sm text-[var(--muted)]">
            Visit window: {EVENT.dateRangeEn}. Multi-admin DB login with
            activity, security, network, and infra observability.
          </p>
        </div>
        <div className="flex gap-2">
          <a
            href={siteUrl}
            target="_blank"
            rel="noreferrer"
            className="btn btn-secondary !py-2 !px-4 !text-sm"
          >
            Public site
          </a>
          <button
            type="button"
            onClick={logout}
            className="btn btn-ghost !py-2 !px-4 !text-sm"
          >
            Sign out
          </button>
        </div>
      </div>

      <div className="mt-8 grid gap-4 sm:grid-cols-2 lg:grid-cols-4">
        {[
          { label: "Total registrations", value: summary?.total ?? "—" },
          { label: "States represented", value: summary?.states ?? "—" },
          {
            label: "Earliest planned visit",
            value: summary?.earliest_arrival
              ? formatDisplayDate(summary.earliest_arrival)
              : "—",
          },
          {
            label: "Latest planned visit",
            value: summary?.latest_arrival
              ? formatDisplayDate(summary.latest_arrival)
              : "—",
          },
        ].map((card) => (
          <div
            key={card.label}
            className="rounded-2xl border border-[var(--line)] bg-[var(--bg-elevated)] px-5 py-4"
          >
            <p className="text-xs font-semibold uppercase tracking-[0.12em] text-[var(--muted)]">
              {card.label}
            </p>
            <p className="font-display mt-2 text-2xl font-semibold text-[var(--ink)]">
              {card.value}
            </p>
          </div>
        ))}
      </div>

      <div className="mt-8 flex flex-wrap gap-2 border-b border-[var(--line)] pb-3">
        {TABS.map(([id, label]) => (
          <button
            key={id}
            type="button"
            onClick={() => setTab(id)}
            className={`rounded-full px-4 py-2 text-sm font-semibold transition ${
              tab === id
                ? "bg-[var(--gold)] text-[#0b0e14]"
                : "bg-[rgba(238,241,245,0.06)] text-[var(--muted)] hover:text-[var(--ink)]"
            }`}
          >
            {label}
          </button>
        ))}
      </div>

      {error ? <p className="alert-error mt-6">{error}</p> : null}

      {tab === "registrations" ? (
        <section className="mt-6 space-y-5">
          <form
            onSubmit={applyFilters}
            className="grid gap-4 rounded-2xl border border-[var(--line)] bg-[var(--bg-elevated)] p-4 md:grid-cols-2 lg:grid-cols-5"
          >
            <div className="field lg:col-span-2">
              <label htmlFor="q">Search</label>
              <input
                id="q"
                value={q}
                onChange={(e) => setQ(e.target.value)}
                placeholder="Pass no, name, mobile, city, PIN, address"
              />
            </div>
            <div className="field">
              <label htmlFor="state">State</label>
              <select
                id="state"
                value={state}
                onChange={(e) => setState(e.target.value)}
              >
                <option value="">All states</option>
                {INDIAN_STATES.map((s) => (
                  <option key={s} value={s}>
                    {s}
                  </option>
                ))}
              </select>
            </div>
            <div className="field">
              <label htmlFor="from">Visit from</label>
              <input
                id="from"
                type="date"
                min={EVENT.startDate}
                max={EVENT.endDate}
                value={arrivalFrom}
                onChange={(e) => setArrivalFrom(e.target.value)}
              />
            </div>
            <div className="field">
              <label htmlFor="to">Visit to</label>
              <input
                id="to"
                type="date"
                min={EVENT.startDate}
                max={EVENT.endDate}
                value={arrivalTo}
                onChange={(e) => setArrivalTo(e.target.value)}
              />
            </div>
            <div className="flex flex-wrap items-end gap-2 lg:col-span-5">
              <button type="submit" className="btn btn-primary !py-2 !px-4 !text-sm">
                Apply filters
              </button>
              <button
                type="button"
                onClick={clearFilters}
                className="btn btn-secondary !py-2 !px-4 !text-sm"
              >
                Clear
              </button>
              <p className="ml-auto text-sm text-[var(--muted)]">
                {total} registration{total === 1 ? "" : "s"}
              </p>
            </div>
          </form>

          <div className="overflow-x-auto rounded-2xl border border-[var(--line)]">
            <table className="admin-table w-full min-w-[980px] text-left text-sm">
              <thead>
                <tr>
                  <th>Pass</th>
                  <th>Name</th>
                  <th>Mobile</th>
                  <th>Home address</th>
                  <th>Visit date</th>
                  <th>Travel / Stay</th>
                  <th>Registered</th>
                </tr>
              </thead>
              <tbody>
                {loading && !visitors.length ? (
                  <tr>
                    <td colSpan={7} className="!text-center text-[var(--muted)]">
                      Loading…
                    </td>
                  </tr>
                ) : null}
                {!loading && !visitors.length ? (
                  <tr>
                    <td colSpan={7} className="!text-center text-[var(--muted)]">
                      No registrations match these filters.
                    </td>
                  </tr>
                ) : null}
                {visitors.map((v) => (
                  <tr key={v.id}>
                    <td>
                      <a
                        href={`${siteUrl}/pass/${v.pass_no}`}
                        target="_blank"
                        rel="noreferrer"
                        className="font-semibold text-[var(--gold)] hover:underline"
                      >
                        {v.pass_no}
                      </a>
                      <div className="text-xs text-[var(--muted)]">
                        ****{v.aadhaar_last4}
                      </div>
                    </td>
                    <td>
                      <div>{v.name}</div>
                      <div className="text-xs text-[var(--muted)]">
                        {[v.gender, v.age ? `${v.age} yrs` : null]
                          .filter(Boolean)
                          .join(" · ") || "—"}
                      </div>
                    </td>
                    <td>
                      <div>{v.mobile}</div>
                      <div className="text-xs text-[var(--muted)]">
                        Emg: {v.emergency_contact || "—"}
                      </div>
                    </td>
                    <td className="max-w-[280px]">
                      <div className="leading-snug">
                        {v.home_address || v.state || "—"}
                      </div>
                      {v.post_office ? (
                        <div className="text-xs text-[var(--muted)]">
                          PO: {v.post_office}
                        </div>
                      ) : null}
                    </td>
                    <td>{formatDisplayDate(v.arrival_date)}</td>
                    <td>
                      <div>{v.transport_mode}</div>
                      <div className="text-xs text-[var(--muted)]">
                        {v.stay_type}
                      </div>
                    </td>
                    <td>{formatDateTime(v.registration_time)}</td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>

          <div className="flex items-center justify-between gap-3">
            <button
              type="button"
              className="btn btn-secondary !py-2 !px-4 !text-sm"
              disabled={page <= 1}
              onClick={() => setPage((p) => Math.max(1, p - 1))}
            >
              Previous
            </button>
            <p className="text-sm text-[var(--muted)]">
              Page {page} of {totalPages}
            </p>
            <button
              type="button"
              className="btn btn-secondary !py-2 !px-4 !text-sm"
              disabled={page >= totalPages}
              onClick={() => setPage((p) => p + 1)}
            >
              Next
            </button>
          </div>
        </section>
      ) : null}

      {tab === "by-state" ? (
        <section className="mt-6">
          <p className="mb-4 text-sm text-[var(--muted)]">
            Registrations grouped by home state.
          </p>
          {!byState.length ? (
            <p className="text-[var(--muted)]">No data yet.</p>
          ) : (
            <div className="overflow-x-auto rounded-2xl border border-[var(--line)]">
              <table className="admin-table w-full text-left text-sm">
                <thead>
                  <tr>
                    <th>#</th>
                    <th>State</th>
                    <th>Registrations</th>
                    <th>Share</th>
                  </tr>
                </thead>
                <tbody>
                  {byState.map((row, i) => (
                    <tr key={row.state}>
                      <td className="text-[var(--muted)]">{i + 1}</td>
                      <td className="font-medium">{row.state}</td>
                      <td>{row.count}</td>
                      <td className="w-[40%] min-w-[140px]">
                        <div className="flex items-center gap-3">
                          <div className="h-2 flex-1 overflow-hidden rounded-full bg-[rgba(238,241,245,0.08)]">
                            <div
                              className="h-full rounded-full bg-[var(--gold)]"
                              style={{
                                width: `${(row.count / maxStateCount) * 100}%`,
                              }}
                            />
                          </div>
                          <span className="w-12 text-right text-xs text-[var(--muted)]">
                            {summary?.total
                              ? `${Math.round((row.count / summary.total) * 100)}%`
                              : "—"}
                          </span>
                        </div>
                      </td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>
          )}
        </section>
      ) : null}

      {tab === "by-date" ? (
        <section className="mt-6">
          <p className="mb-4 text-sm text-[var(--muted)]">
            Planned arrival dates within {EVENT.dateRangeEn}.
          </p>
          {!byDate.length ? (
            <p className="text-[var(--muted)]">No data yet.</p>
          ) : (
            <div className="overflow-x-auto rounded-2xl border border-[var(--line)]">
              <table className="admin-table w-full text-left text-sm">
                <thead>
                  <tr>
                    <th>Visit date</th>
                    <th>Registrations</th>
                    <th>Load</th>
                  </tr>
                </thead>
                <tbody>
                  {byDate.map((row) => (
                    <tr key={row.arrival_date}>
                      <td className="font-medium">
                        {formatDisplayDate(row.arrival_date)}
                      </td>
                      <td>{row.count}</td>
                      <td className="w-[50%] min-w-[160px]">
                        <div className="h-2 overflow-hidden rounded-full bg-[rgba(238,241,245,0.08)]">
                          <div
                            className="h-full rounded-full bg-[var(--neela)]"
                            style={{
                              width: `${(row.count / maxDateCount) * 100}%`,
                            }}
                          />
                        </div>
                      </td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>
          )}
        </section>
      ) : null}

      {tab === "activity" ? (
        <section className="mt-6 space-y-4">
          <p className="text-sm text-[var(--muted)]">
            Admin actions from <code>admin_activity_logs</code>.
          </p>
          {sectionLoading ? (
            <p className="text-[var(--muted)]">Loading…</p>
          ) : (
            <div className="overflow-x-auto rounded-2xl border border-[var(--line)]">
              <table className="admin-table w-full min-w-[720px] text-left text-sm">
                <thead>
                  <tr>
                    <th>When</th>
                    <th>Admin</th>
                    <th>Action</th>
                    <th>Resource</th>
                    <th>Outcome</th>
                    <th>IP</th>
                  </tr>
                </thead>
                <tbody>
                  {!activityLogs.length ? (
                    <tr>
                      <td colSpan={6} className="!text-center text-[var(--muted)]">
                        No activity yet.
                      </td>
                    </tr>
                  ) : null}
                  {activityLogs.map((row) => (
                    <tr key={row.id}>
                      <td>{formatDateTime(row.created_at)}</td>
                      <td>{row.username || "—"}</td>
                      <td className="font-medium">{row.action}</td>
                      <td className="max-w-[200px] truncate text-[var(--muted)]">
                        {row.resource || "—"}
                      </td>
                      <td>{row.outcome}</td>
                      <td className="text-[var(--muted)]">{row.ip || "—"}</td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>
          )}
        </section>
      ) : null}

      {tab === "website-audit" ? (
        <section className="mt-6 space-y-4">
          <p className="text-sm text-[var(--muted)]">
            Registration funnel events from <code>audit_logs</code>.
          </p>
          {sectionLoading ? (
            <p className="text-[var(--muted)]">Loading…</p>
          ) : (
            <div className="overflow-x-auto rounded-2xl border border-[var(--line)]">
              <table className="admin-table w-full min-w-[720px] text-left text-sm">
                <thead>
                  <tr>
                    <th>When</th>
                    <th>Step</th>
                    <th>Channel</th>
                    <th>Outcome</th>
                    <th>IP</th>
                  </tr>
                </thead>
                <tbody>
                  {!auditLogs.length ? (
                    <tr>
                      <td colSpan={5} className="!text-center text-[var(--muted)]">
                        No audit rows yet.
                      </td>
                    </tr>
                  ) : null}
                  {auditLogs.map((row) => (
                    <tr key={row.id}>
                      <td>{formatDateTime(row.created_at)}</td>
                      <td className="font-medium">{row.step}</td>
                      <td>{row.channel}</td>
                      <td>{row.outcome}</td>
                      <td className="text-[var(--muted)]">{row.ip || "—"}</td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>
          )}
        </section>
      ) : null}

      {tab === "security" ? (
        <section className="mt-6 space-y-4">
          <p className="text-sm text-[var(--muted)]">
            Open and historical security threats from <code>security_events</code>.
          </p>
          {sectionLoading ? (
            <p className="text-[var(--muted)]">Loading…</p>
          ) : (
            <div className="overflow-x-auto rounded-2xl border border-[var(--line)]">
              <table className="admin-table w-full min-w-[800px] text-left text-sm">
                <thead>
                  <tr>
                    <th>When</th>
                    <th>Severity</th>
                    <th>Title</th>
                    <th>Category</th>
                    <th>IP</th>
                    <th>Status</th>
                    <th />
                  </tr>
                </thead>
                <tbody>
                  {!securityEvents.length ? (
                    <tr>
                      <td colSpan={7} className="!text-center text-[var(--muted)]">
                        No security events yet.
                      </td>
                    </tr>
                  ) : null}
                  {securityEvents.map((row) => (
                    <tr key={row.id}>
                      <td>{formatDateTime(row.created_at)}</td>
                      <td className={`font-semibold uppercase ${severityClass(row.severity)}`}>
                        {row.severity}
                      </td>
                      <td className="font-medium">{row.title}</td>
                      <td>{row.category}</td>
                      <td className="text-[var(--muted)]">{row.source_ip || "—"}</td>
                      <td>{row.status}</td>
                      <td className="whitespace-nowrap">
                        {row.status === "open" ? (
                          <button
                            type="button"
                            className="btn btn-secondary !py-1 !px-3 !text-xs"
                            onClick={() => updateSecurityStatus(row.id, "acknowledged")}
                          >
                            Ack
                          </button>
                        ) : null}{" "}
                        {row.status !== "resolved" ? (
                          <button
                            type="button"
                            className="btn btn-primary !py-1 !px-3 !text-xs"
                            onClick={() => updateSecurityStatus(row.id, "resolved")}
                          >
                            Resolve
                          </button>
                        ) : null}
                      </td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>
          )}
        </section>
      ) : null}

      {tab === "network" ? (
        <section className="mt-6 space-y-6">
          <p className="text-sm text-[var(--muted)]">
            HTTP traffic aggregates from <code>http_request_events</code> and
            manual blocklist controls.
          </p>
          {sectionLoading && !network ? (
            <p className="text-[var(--muted)]">Loading…</p>
          ) : null}
          {network ? (
            <>
              <div className="grid gap-4 sm:grid-cols-3">
                {[
                  {
                    label: "Last hour requests",
                    value: network.summary.last_hour_requests,
                  },
                  {
                    label: "Approx RPS (1h)",
                    value: network.summary.approx_rps,
                  },
                  {
                    label: "Throttled / blocked (1h)",
                    value: network.summary.last_hour_throttled_or_blocked,
                  },
                ].map((card) => (
                  <div
                    key={card.label}
                    className="rounded-2xl border border-[var(--line)] bg-[var(--bg-elevated)] px-5 py-4"
                  >
                    <p className="text-xs font-semibold uppercase tracking-[0.12em] text-[var(--muted)]">
                      {card.label}
                    </p>
                    <p className="font-display mt-2 text-2xl font-semibold">
                      {card.value}
                    </p>
                  </div>
                ))}
              </div>

              <div className="grid gap-6 lg:grid-cols-2">
                <div className="overflow-x-auto rounded-2xl border border-[var(--line)]">
                  <table className="admin-table w-full text-left text-sm">
                    <thead>
                      <tr>
                        <th colSpan={3}>Top IPs (24h)</th>
                      </tr>
                      <tr>
                        <th>IP</th>
                        <th>Requests</th>
                        <th>Errors</th>
                      </tr>
                    </thead>
                    <tbody>
                      {!network.top_ips.length ? (
                        <tr>
                          <td colSpan={3} className="!text-center text-[var(--muted)]">
                            No request telemetry yet.
                          </td>
                        </tr>
                      ) : null}
                      {network.top_ips.map((row) => (
                        <tr key={row.client_ip}>
                          <td className="font-medium">{row.client_ip}</td>
                          <td>{row.request_count}</td>
                          <td>{row.errors}</td>
                        </tr>
                      ))}
                    </tbody>
                  </table>
                </div>
                <div className="overflow-x-auto rounded-2xl border border-[var(--line)]">
                  <table className="admin-table w-full text-left text-sm">
                    <thead>
                      <tr>
                        <th colSpan={3}>Top paths (24h)</th>
                      </tr>
                      <tr>
                        <th>Path</th>
                        <th>Requests</th>
                        <th>Avg ms</th>
                      </tr>
                    </thead>
                    <tbody>
                      {!network.top_paths.length ? (
                        <tr>
                          <td colSpan={3} className="!text-center text-[var(--muted)]">
                            No path data yet.
                          </td>
                        </tr>
                      ) : null}
                      {network.top_paths.map((row) => (
                        <tr key={row.path_norm}>
                          <td className="font-medium">{row.path_norm}</td>
                          <td>{row.request_count}</td>
                          <td>{row.avg_latency}</td>
                        </tr>
                      ))}
                    </tbody>
                  </table>
                </div>
              </div>

              <form
                onSubmit={addBlock}
                className="grid gap-4 rounded-2xl border border-[var(--line)] bg-[var(--bg-elevated)] p-4 md:grid-cols-3"
              >
                <div className="field">
                  <label htmlFor="block-ip">Block IP</label>
                  <input
                    id="block-ip"
                    value={blockIp}
                    onChange={(e) => setBlockIp(e.target.value)}
                    placeholder="e.g. 203.0.113.10"
                    required
                  />
                </div>
                <div className="field md:col-span-2">
                  <label htmlFor="block-reason">Reason</label>
                  <input
                    id="block-reason"
                    value={blockReason}
                    onChange={(e) => setBlockReason(e.target.value)}
                    placeholder="Abuse / scanner / flood"
                  />
                </div>
                <div className="flex flex-wrap items-end gap-2 md:col-span-3">
                  <button type="submit" className="btn btn-primary !py-2 !px-4 !text-sm">
                    Add to blocklist
                  </button>
                  {blockMsg ? (
                    <p className="text-sm text-[var(--muted)]">{blockMsg}</p>
                  ) : null}
                </div>
              </form>

              <div className="overflow-x-auto rounded-2xl border border-[var(--line)]">
                <table className="admin-table w-full min-w-[640px] text-left text-sm">
                  <thead>
                    <tr>
                      <th>IP</th>
                      <th>Reason</th>
                      <th>Source</th>
                      <th>Created</th>
                      <th />
                    </tr>
                  </thead>
                  <tbody>
                    {!network.blocklist.length ? (
                      <tr>
                        <td colSpan={5} className="!text-center text-[var(--muted)]">
                          Blocklist empty.
                        </td>
                      </tr>
                    ) : null}
                    {network.blocklist.map((row) => (
                      <tr key={row.id}>
                        <td className="font-medium">{row.client_ip}</td>
                        <td>{row.reason}</td>
                        <td>{row.source}</td>
                        <td>{formatDateTime(row.created_at)}</td>
                        <td>
                          <button
                            type="button"
                            className="btn btn-ghost !py-1 !px-3 !text-xs"
                            onClick={() => removeBlock(row.id)}
                          >
                            Unblock
                          </button>
                        </td>
                      </tr>
                    ))}
                  </tbody>
                </table>
              </div>
            </>
          ) : null}
        </section>
      ) : null}

      {tab === "infra" ? (
        <section className="mt-6 space-y-6">
          <p className="text-sm text-[var(--muted)]">
            Process memory, host load, MySQL ping. SNMP targets are a Phase F
            placeholder.
          </p>
          {sectionLoading && !infra ? (
            <p className="text-[var(--muted)]">Loading…</p>
          ) : null}
          {infra ? (
            <>
              <div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-4">
                {[
                  {
                    label: "Process uptime",
                    value: formatUptime(infra.process.uptime_seconds),
                  },
                  {
                    label: "Heap used",
                    value: formatBytes(infra.process.memory.heap_used),
                  },
                  {
                    label: "RSS",
                    value: formatBytes(infra.process.memory.rss),
                  },
                  {
                    label: "MySQL ping",
                    value: infra.mysql.ok
                      ? `${infra.mysql.latency_ms} ms`
                      : "DOWN",
                  },
                ].map((card) => (
                  <div
                    key={card.label}
                    className="rounded-2xl border border-[var(--line)] bg-[var(--bg-elevated)] px-5 py-4"
                  >
                    <p className="text-xs font-semibold uppercase tracking-[0.12em] text-[var(--muted)]">
                      {card.label}
                    </p>
                    <p className="font-display mt-2 text-2xl font-semibold">
                      {card.value}
                    </p>
                  </div>
                ))}
              </div>

              <div className="grid gap-4 lg:grid-cols-2">
                <div className="rounded-2xl border border-[var(--line)] bg-[var(--bg-elevated)] p-5 text-sm">
                  <h2 className="font-display text-xl font-semibold">Host</h2>
                  <dl className="mt-4 space-y-2 text-[var(--muted)]">
                    <div className="flex justify-between gap-4">
                      <dt>Hostname</dt>
                      <dd className="text-[var(--ink)]">{infra.host.hostname}</dd>
                    </div>
                    <div className="flex justify-between gap-4">
                      <dt>Platform</dt>
                      <dd className="text-[var(--ink)]">
                        {infra.host.platform} · {infra.host.cpus} CPUs
                      </dd>
                    </div>
                    <div className="flex justify-between gap-4">
                      <dt>Host uptime</dt>
                      <dd className="text-[var(--ink)]">
                        {formatUptime(infra.host.uptime_seconds)}
                      </dd>
                    </div>
                    <div className="flex justify-between gap-4">
                      <dt>Load avg</dt>
                      <dd className="text-[var(--ink)]">
                        {infra.host.loadavg?.length
                          ? infra.host.loadavg.map((n) => n.toFixed(2)).join(" / ")
                          : "n/a"}
                      </dd>
                    </div>
                    <div className="flex justify-between gap-4">
                      <dt>Memory free / total</dt>
                      <dd className="text-[var(--ink)]">
                        {formatBytes(infra.host.freemem)} /{" "}
                        {formatBytes(infra.host.totalmem)}
                      </dd>
                    </div>
                    <div className="flex justify-between gap-4">
                      <dt>Node</dt>
                      <dd className="text-[var(--ink)]">
                        {infra.process.node_version}
                      </dd>
                    </div>
                  </dl>
                </div>
                <div className="rounded-2xl border border-[var(--line)] bg-[var(--bg-elevated)] p-5 text-sm">
                  <h2 className="font-display text-xl font-semibold">
                    Disk & SNMP
                  </h2>
                  <p className="mt-4 text-[var(--muted)]">
                    {infra.disk.note || "Disk metrics unavailable."}
                  </p>
                  {infra.disk.freemem_bytes != null ? (
                    <p className="mt-2 text-[var(--ink)]">
                      Host freemem proxy:{" "}
                      {formatBytes(infra.disk.freemem_bytes)} /{" "}
                      {formatBytes(infra.disk.totalmem_bytes || 0)}
                    </p>
                  ) : null}
                  <p className="mt-6 text-[var(--muted)]">
                    SNMP targets:{" "}
                    {Array.isArray(infra.snmp) && infra.snmp.length
                      ? `${infra.snmp.length} configured`
                      : "none (placeholder [])"}
                  </p>
                  {!infra.mysql.ok && infra.mysql.error ? (
                    <p className="alert-error mt-4">{infra.mysql.error}</p>
                  ) : null}
                </div>
              </div>
            </>
          ) : null}
        </section>
      ) : null}
    </div>
  );
}
