"use client";

import { useAuth } from "@/components/AuthProvider";
import { c2api } from "@/lib/c2api";
import { useEffect, useState, useRef, useCallback } from "react";
import { useRouter } from "next/navigation";
import type { UserRecord, AuditEntry, UserRole } from "@/lib/types";

// ---------------------------------------------------------------------------
// Shared primitives
// ---------------------------------------------------------------------------

interface FeatureFlags {
  stt_enabled: boolean;
  correlation_enabled: boolean;
  summaries_enabled: boolean;
  vocabulary_learning_enabled: boolean;
}

const FLAG_META: { key: keyof FeatureFlags; label: string; description: string }[] = [
  {
    key: "stt_enabled",
    label: "Speech-to-Text (Whisper)",
    description: "Transcribe call audio via OpenAI Whisper. When off, calls are recorded and stored but no transcript is generated.",
  },
  {
    key: "correlation_enabled",
    label: "Incident Correlation",
    description: "Run scene extraction and incident correlation on each call. When off, calls are logged but not linked to incidents.",
  },
  {
    key: "summaries_enabled",
    label: "Incident Summaries",
    description: "Generate AI summaries for active incidents on each summarizer pass. Auto-resolve sweep is also paused when off.",
  },
  {
    key: "vocabulary_learning_enabled",
    label: "Vocabulary Learning",
    description: "Run the background vocabulary induction loop that proposes new STT terms from recent transcripts.",
  },
];

function Toggle({
  enabled,
  onChange,
  disabled,
}: {
  enabled: boolean;
  onChange: (val: boolean) => void;
  disabled: boolean;
}) {
  return (
    <button
      onClick={() => onChange(!enabled)}
      disabled={disabled}
      className={`relative inline-flex h-6 w-11 items-center rounded-full transition-colors focus:outline-none disabled:opacity-50 ${
        enabled ? "bg-indigo-600" : "bg-gray-700"
      }`}
    >
      <span
        className={`inline-block h-4 w-4 rounded-full bg-white shadow transition-transform ${
          enabled ? "translate-x-6" : "translate-x-1"
        }`}
      />
    </button>
  );
}

function fmtDate(iso: string | null | undefined) {
  if (!iso) return "—";
  return new Date(iso).toLocaleDateString("en-US", { month: "short", day: "numeric", year: "numeric" });
}

function fmtDatetime(iso: string | null | undefined) {
  if (!iso) return "—";
  return new Date(iso).toLocaleString("en-US", {
    month: "short", day: "numeric", year: "numeric",
    hour: "numeric", minute: "2-digit",
  });
}

const ROLE_COLORS: Record<UserRole, string> = {
  admin:    "bg-indigo-900 text-indigo-300",
  operator: "bg-green-900 text-green-300",
  viewer:   "bg-gray-800 text-gray-400",
};

function RoleBadge({ role }: { role: UserRole }) {
  const labels: Record<UserRole, string> = { admin: "Admin", operator: "Operator", viewer: "Viewer" };
  return (
    <span className={`text-xs font-mono px-2 py-0.5 rounded-full ${ROLE_COLORS[role]}`}>
      {labels[role]}
    </span>
  );
}

// ---------------------------------------------------------------------------
// AI Features tab
// ---------------------------------------------------------------------------

function FeaturesTab() {
  const [flags, setFlags] = useState<FeatureFlags | null>(null);
  const [loading, setLoading] = useState(true);
  const [saving, setSaving] = useState<string | null>(null);
  const [error, setError] = useState<string | null>(null);

  useEffect(() => {
    c2api.getFeatureFlags()
      .then((f) => setFlags(f as unknown as FeatureFlags))
      .catch((e) => setError(String(e)))
      .finally(() => setLoading(false));
  }, []);

  async function handleToggle(key: keyof FeatureFlags, value: boolean) {
    if (!flags) return;
    setSaving(key);
    setError(null);
    try {
      const updated = await c2api.setFeatureFlags({ [key]: value });
      setFlags(updated as unknown as FeatureFlags);
    } catch (e) {
      setError(String(e));
    } finally {
      setSaving(null);
    }
  }

  return (
    <section className="space-y-3">
      {error && (
        <div className="bg-red-950 border border-red-800 rounded-lg p-3">
          <p className="text-red-400 text-sm font-mono">{error}</p>
        </div>
      )}
      {loading ? (
        <p className="text-gray-500 text-sm font-mono">Loading…</p>
      ) : (
        <div className="bg-gray-900 border border-gray-800 rounded-xl divide-y divide-gray-800">
          {FLAG_META.map(({ key, label, description }) => (
            <div key={key} className="flex items-center justify-between gap-4 px-5 py-4">
              <div className="min-w-0">
                <p className="text-white text-sm font-semibold">{label}</p>
                <p className="text-gray-500 text-xs mt-0.5 leading-snug">{description}</p>
              </div>
              <Toggle
                enabled={flags?.[key] ?? true}
                onChange={(val) => handleToggle(key, val)}
                disabled={saving === key}
              />
            </div>
          ))}
        </div>
      )}
    </section>
  );
}

// ---------------------------------------------------------------------------
// Correlation Debug tab
// ---------------------------------------------------------------------------

function CorrelationDebugTab() {
  const [limit, setLimit] = useState(20);
  const [orphanHours, setOrphanHours] = useState(48);
  const [data, setData] = useState<unknown>(null);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [copied, setCopied] = useState(false);
  const preRef = useRef<HTMLPreElement>(null);

  async function handleFetch() {
    setLoading(true);
    setError(null);
    setData(null);
    setCopied(false);
    try {
      const result = await c2api.getCorrelationDebug(limit, orphanHours);
      setData(result);
    } catch (e) {
      setError(String(e));
    } finally {
      setLoading(false);
    }
  }

  function handleCopy() {
    if (!data) return;
    const text = JSON.stringify(data, null, 2);
    if (navigator.clipboard) {
      navigator.clipboard.writeText(text).then(() => {
        setCopied(true);
        setTimeout(() => setCopied(false), 2000);
      }).catch(() => fallbackCopy(text));
    } else {
      fallbackCopy(text);
    }
  }

  function fallbackCopy(text: string) {
    const ta = document.createElement("textarea");
    ta.value = text;
    ta.style.position = "fixed";
    ta.style.opacity = "0";
    document.body.appendChild(ta);
    ta.focus();
    ta.select();
    document.execCommand("copy");
    document.body.removeChild(ta);
    setCopied(true);
    setTimeout(() => setCopied(false), 2000);
  }

  const json = data ? JSON.stringify(data, null, 2) : null;
  const meta = data as {
    incident_count?: number;
    orphaned_call_count?: number;
    generated_at?: string;
    incidents?: Array<{ calls_detail?: Array<{ corr_path?: string; corr_fit_signal?: string }> }>;
    orphans_by_talkgroup?: Array<{ talkgroup_id?: number; talkgroup_name?: string; count: number; no_type_count: number; sweep_exhausted_count: number }>;
  } | null;

  const pathCounts: Record<string, number> = {};
  const signalCounts: Record<string, number> = {};
  if (meta?.incidents) {
    for (const inc of meta.incidents) {
      for (const call of inc.calls_detail ?? []) {
        const p = call.corr_path ?? "unknown";
        pathCounts[p] = (pathCounts[p] ?? 0) + 1;
        if (call.corr_fit_signal) {
          signalCounts[call.corr_fit_signal] = (signalCounts[call.corr_fit_signal] ?? 0) + 1;
        }
      }
    }
  }

  return (
    <div className="space-y-4">
      <p className="text-xs text-gray-500 font-mono">
        Fetches recent incidents with per-call correlation debug fields, plus orphaned calls.
        Copy the JSON and paste it to Claude to diagnose correlation problems.
      </p>

      <div className="flex flex-wrap items-end gap-4">
        <div>
          <label className="text-xs text-gray-400 block mb-1">Incidents (limit)</label>
          <input
            type="number"
            min={1} max={100}
            value={limit}
            onChange={(e) => setLimit(Math.min(100, Math.max(1, Number(e.target.value))))}
            className="w-24 bg-gray-800 border border-gray-700 rounded-lg px-3 py-1.5 text-white text-sm font-mono focus:outline-none focus:border-indigo-500"
          />
        </div>
        <div>
          <label className="text-xs text-gray-400 block mb-1">Orphan scan window (hours)</label>
          <input
            type="number"
            min={1} max={168}
            value={orphanHours}
            onChange={(e) => setOrphanHours(Math.min(168, Math.max(1, Number(e.target.value))))}
            className="w-28 bg-gray-800 border border-gray-700 rounded-lg px-3 py-1.5 text-white text-sm font-mono focus:outline-none focus:border-indigo-500"
          />
        </div>
        <button
          onClick={handleFetch}
          disabled={loading}
          className="bg-indigo-600 hover:bg-indigo-500 disabled:opacity-50 text-white text-sm font-mono px-4 py-1.5 rounded-lg transition-colors"
        >
          {loading ? "Fetching…" : "Fetch"}
        </button>
      </div>

      {error && (
        <div className="bg-red-950 border border-red-800 rounded-lg p-3">
          <p className="text-red-400 text-sm font-mono">{error}</p>
        </div>
      )}

      {meta && (
        <div className="flex items-center justify-between">
          <p className="text-xs text-gray-500 font-mono">
            {meta.incident_count} incidents · {meta.orphaned_call_count} orphaned calls · {meta.generated_at}
          </p>
          <button
            onClick={handleCopy}
            className="text-xs font-mono px-3 py-1.5 rounded-lg border border-gray-700 bg-gray-900 text-gray-300 hover:text-white transition-colors"
          >
            {copied ? "Copied!" : "Copy JSON"}
          </button>
        </div>
      )}

      {meta && Object.keys(pathCounts).length > 0 && (
        <div className="grid grid-cols-2 gap-3">
          <div className="bg-gray-900 border border-gray-800 rounded-xl p-4 space-y-1">
            <p className="text-xs text-gray-400 font-mono font-semibold mb-2">corr_path distribution</p>
            {Object.entries(pathCounts).sort((a, b) => b[1] - a[1]).map(([path, n]) => (
              <div key={path} className="flex justify-between text-xs font-mono">
                <span className="text-gray-300">{path}</span>
                <span className="text-indigo-400">{n}</span>
              </div>
            ))}
          </div>
          <div className="bg-gray-900 border border-gray-800 rounded-xl p-4 space-y-1">
            <p className="text-xs text-gray-400 font-mono font-semibold mb-2">fit_signal distribution</p>
            {Object.keys(signalCounts).length === 0
              ? <p className="text-xs text-gray-600 font-mono">No signal data yet — deploy correlator update first</p>
              : Object.entries(signalCounts).sort((a, b) => b[1] - a[1]).map(([sig, n]) => (
                  <div key={sig} className="flex justify-between text-xs font-mono">
                    <span className={sig === "time_fallback" ? "text-yellow-400" : "text-gray-300"}>{sig}</span>
                    <span className="text-indigo-400">{n}</span>
                  </div>
                ))
            }
          </div>
        </div>
      )}

      {meta?.orphans_by_talkgroup && meta.orphans_by_talkgroup.length > 0 && (
        <div className="bg-gray-900 border border-gray-800 rounded-xl p-4 space-y-1">
          <p className="text-xs text-gray-400 font-mono font-semibold mb-2">orphans by talkgroup</p>
          {meta.orphans_by_talkgroup.map((tg) => (
            <div key={String(tg.talkgroup_id)} className="flex justify-between text-xs font-mono">
              <span className="text-gray-300">{tg.talkgroup_name} <span className="text-gray-600">({tg.talkgroup_id})</span></span>
              <span className="text-gray-400">
                {tg.count} total · <span className="text-gray-500">{tg.no_type_count} no-type</span> · <span className="text-red-400">{tg.sweep_exhausted_count} exhausted</span>
              </span>
            </div>
          ))}
        </div>
      )}

      {json && (
        <pre
          ref={preRef}
          className="bg-gray-950 border border-gray-800 rounded-xl p-4 text-xs text-gray-300 font-mono overflow-auto max-h-[60vh] whitespace-pre"
        >
          {json}
        </pre>
      )}
    </div>
  );
}

// ---------------------------------------------------------------------------
// User detail panel
// ---------------------------------------------------------------------------

function UserDetailPanel({
  user,
  onClose,
  onUpdated,
  currentUid,
}: {
  user: UserRecord;
  onClose: () => void;
  onUpdated: (u: UserRecord) => void;
  currentUid: string;
}) {
  const [detail, setDetail] = useState<UserRecord>(user);
  const [editRole, setEditRole] = useState<UserRole>(user.role);
  const [editNodes, setEditNodes] = useState<string>(user.owned_node_ids.join(", "));
  const [editName, setEditName] = useState<string>(user.display_name ?? "");
  const [saving, setSaving] = useState(false);
  const [toggling, setToggling] = useState(false);
  const [deleting, setDeleting] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [showSessions, setShowSessions] = useState(false);

  // Fetch full detail (sessions) lazily
  useEffect(() => {
    c2api.getUser(user.uid)
      .then((d) => setDetail(d))
      .catch(() => {});
  }, [user.uid]);

  async function handleSave() {
    setSaving(true);
    setError(null);
    const nodes = editRole === "operator"
      ? editNodes.split(",").map((s) => s.trim()).filter(Boolean)
      : [];
    try {
      const updated = await c2api.updateUser(user.uid, {
        role: editRole,
        owned_node_ids: nodes,
        display_name: editName || undefined,
      });
      onUpdated(updated);
      setDetail((d) => ({ ...d, ...updated }));
    } catch (e) {
      setError(e instanceof Error ? e.message : String(e));
    } finally {
      setSaving(false);
    }
  }

  async function handleToggleDisabled() {
    setToggling(true);
    setError(null);
    try {
      if (detail.disabled) {
        await c2api.enableUser(user.uid);
      } else {
        await c2api.disableUser(user.uid);
      }
      const next = { ...detail, disabled: !detail.disabled };
      setDetail(next);
      onUpdated(next);
    } catch (e) {
      setError(e instanceof Error ? e.message : String(e));
    } finally {
      setToggling(false);
    }
  }

  async function handleDelete() {
    if (!confirm(`Permanently delete ${detail.email}? This cannot be undone.`)) return;
    setDeleting(true);
    setError(null);
    try {
      await c2api.deleteUser(user.uid);
      onUpdated({ ...detail, uid: "__deleted__" });
      onClose();
    } catch (e) {
      setError(e instanceof Error ? e.message : String(e));
    } finally {
      setDeleting(false);
    }
  }

  const isSelf = user.uid === currentUid;

  return (
    <div className="bg-gray-900 border border-gray-700 rounded-xl p-5 space-y-5 font-mono">
      <div className="flex items-start justify-between">
        <div>
          <p className="text-white font-semibold">{detail.email}</p>
          <p className="text-xs text-gray-500 mt-0.5">{detail.uid}</p>
        </div>
        <button onClick={onClose} className="text-gray-600 hover:text-gray-300 transition-colors text-xl leading-none">×</button>
      </div>

      {error && (
        <div className="bg-red-950 border border-red-800 rounded-lg p-3">
          <p className="text-red-400 text-xs">{error}</p>
        </div>
      )}

      <div className="space-y-3">
        <div>
          <label className="text-xs text-gray-400 block mb-1">Display Name</label>
          <input
            value={editName}
            onChange={(e) => setEditName(e.target.value)}
            className="w-full bg-gray-800 border border-gray-700 rounded-lg px-3 py-1.5 text-white text-sm focus:outline-none focus:border-indigo-500"
            placeholder="Full name"
          />
        </div>

        <div>
          <label className="text-xs text-gray-400 block mb-1">Role</label>
          <select
            value={editRole}
            onChange={(e) => setEditRole(e.target.value as UserRole)}
            className="w-full bg-gray-800 border border-gray-700 rounded-lg px-3 py-1.5 text-white text-sm focus:outline-none focus:border-indigo-500"
          >
            <option value="admin">Admin — full access</option>
            <option value="operator">Operator — owns nodes</option>
            <option value="viewer">Viewer — read-only</option>
          </select>
        </div>

        {editRole === "operator" && (
          <div>
            <label className="text-xs text-gray-400 block mb-1">
              Owned Node IDs <span className="text-gray-600">(comma-separated, required)</span>
            </label>
            <input
              value={editNodes}
              onChange={(e) => setEditNodes(e.target.value)}
              className="w-full bg-gray-800 border border-gray-700 rounded-lg px-3 py-1.5 text-white text-sm font-mono focus:outline-none focus:border-indigo-500"
              placeholder="node-abc123, node-def456"
            />
          </div>
        )}

        <button
          onClick={handleSave}
          disabled={saving}
          className="bg-indigo-600 hover:bg-indigo-500 disabled:opacity-50 text-white text-sm px-4 py-1.5 rounded-lg transition-colors"
        >
          {saving ? "Saving…" : "Save changes"}
        </button>
      </div>

      <div className="border-t border-gray-800 pt-4 space-y-2 text-xs">
        <div className="flex justify-between">
          <span className="text-gray-500">Status</span>
          <span className={detail.disabled ? "text-red-400" : "text-green-400"}>
            {detail.disabled ? "Disabled" : "Active"}
          </span>
        </div>
        <div className="flex justify-between">
          <span className="text-gray-500">Discord</span>
          <span className="text-gray-300">
            {detail.discord_linked
              ? `@${detail.discord_username ?? detail.discord_user_id}`
              : "Not linked"}
          </span>
        </div>
        <div className="flex justify-between">
          <span className="text-gray-500">Created</span>
          <span className="text-gray-300">{fmtDate(detail.creation_time)}</span>
        </div>
        <div className="flex justify-between">
          <span className="text-gray-500">Last sign-in</span>
          <span className="text-gray-300">{fmtDate(detail.last_sign_in)}</span>
        </div>
      </div>

      {(detail.sessions?.length ?? 0) > 0 && (
        <div className="border-t border-gray-800 pt-4">
          <button
            onClick={() => setShowSessions((v) => !v)}
            className="text-xs text-gray-500 hover:text-gray-300 transition-colors flex items-center gap-1"
          >
            <span>{showSessions ? "▲" : "▼"}</span>
            <span>Login history ({detail.sessions?.length} recent)</span>
          </button>
          {showSessions && (
            <div className="mt-3 space-y-1.5 max-h-48 overflow-y-auto">
              {detail.sessions?.map((s) => (
                <div key={s.session_id} className="text-xs text-gray-400 flex justify-between gap-4">
                  <span>{fmtDatetime(s.timestamp)}</span>
                  <span className="text-gray-600 truncate">{s.ip ?? "—"}</span>
                </div>
              ))}
            </div>
          )}
        </div>
      )}

      <div className="border-t border-gray-800 pt-4 flex gap-4 flex-wrap">
        {!isSelf ? (
          <>
            <button
              onClick={handleToggleDisabled}
              disabled={toggling}
              className="text-xs text-yellow-500 hover:text-yellow-400 disabled:opacity-50 transition-colors"
            >
              {toggling ? "…" : detail.disabled ? "Enable account" : "Disable account"}
            </button>
            <button
              onClick={handleDelete}
              disabled={deleting}
              className="text-xs text-red-500 hover:text-red-400 disabled:opacity-50 transition-colors"
            >
              {deleting ? "Deleting…" : "Delete user"}
            </button>
          </>
        ) : (
          <p className="text-xs text-gray-600">Cannot disable or delete your own account.</p>
        )}
      </div>
    </div>
  );
}

// ---------------------------------------------------------------------------
// Create User modal
// ---------------------------------------------------------------------------

function CreateUserModal({
  onClose,
  onCreated,
}: {
  onClose: () => void;
  onCreated: (u: UserRecord) => void;
}) {
  const [email, setEmail] = useState("");
  const [displayName, setDisplayName] = useState("");
  const [role, setRole] = useState<UserRole>("viewer");
  const [nodeIds, setNodeIds] = useState("");
  const [saving, setSaving] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [inviteLink, setInviteLink] = useState<string | null>(null);
  const [copied, setCopied] = useState(false);

  async function handleSubmit(e: React.FormEvent) {
    e.preventDefault();
    setSaving(true);
    setError(null);
    const owned_node_ids = role === "operator"
      ? nodeIds.split(",").map((s) => s.trim()).filter(Boolean)
      : [];
    try {
      const created = await c2api.createUser({
        email,
        role,
        display_name: displayName || undefined,
        owned_node_ids,
      });
      onCreated(created);
      if (created.invite_link) {
        setInviteLink(created.invite_link);
      } else {
        onClose();
      }
    } catch (e) {
      setError(e instanceof Error ? e.message : String(e));
    } finally {
      setSaving(false);
    }
  }

  function copyLink() {
    if (!inviteLink) return;
    navigator.clipboard?.writeText(inviteLink).then(() => {
      setCopied(true);
      setTimeout(() => setCopied(false), 2000);
    });
  }

  if (inviteLink) {
    return (
      <div className="fixed inset-0 z-50 bg-black/70 flex items-center justify-center p-4">
        <div className="bg-gray-900 border border-gray-700 rounded-xl w-full max-w-md p-6 space-y-4 font-mono">
          <h2 className="text-white font-semibold">User Created</h2>
          <p className="text-xs text-gray-400">
            Share this one-time invite link with the new user so they can set their password.
            It expires after use.
          </p>
          <div className="bg-gray-800 border border-gray-700 rounded-lg p-3">
            <p className="text-xs text-indigo-300 break-all">{inviteLink}</p>
          </div>
          <div className="flex gap-3">
            <button
              onClick={copyLink}
              className="flex-1 bg-gray-800 hover:bg-gray-700 text-gray-300 rounded-lg py-2 text-sm transition-colors"
            >
              {copied ? "Copied!" : "Copy link"}
            </button>
            <button
              onClick={onClose}
              className="flex-1 bg-indigo-600 hover:bg-indigo-500 text-white rounded-lg py-2 text-sm transition-colors"
            >
              Done
            </button>
          </div>
        </div>
      </div>
    );
  }

  return (
    <div className="fixed inset-0 z-50 bg-black/70 flex items-center justify-center p-4">
      <div className="bg-gray-900 border border-gray-700 rounded-xl w-full max-w-md p-6 font-mono">
        <h2 className="text-white font-semibold mb-4">Create User</h2>
        <form onSubmit={handleSubmit} className="space-y-4">
          <div>
            <label className="text-xs text-gray-400 block mb-1">Email</label>
            <input
              type="email"
              value={email}
              onChange={(e) => setEmail(e.target.value)}
              required
              className="w-full bg-gray-800 border border-gray-700 rounded-lg px-3 py-2 text-white text-sm focus:outline-none focus:border-indigo-500"
              placeholder="user@example.com"
            />
          </div>
          <div>
            <label className="text-xs text-gray-400 block mb-1">
              Display Name <span className="text-gray-600">(optional)</span>
            </label>
            <input
              value={displayName}
              onChange={(e) => setDisplayName(e.target.value)}
              className="w-full bg-gray-800 border border-gray-700 rounded-lg px-3 py-2 text-white text-sm focus:outline-none focus:border-indigo-500"
              placeholder="Jane Smith"
            />
          </div>
          <div>
            <label className="text-xs text-gray-400 block mb-1">Role</label>
            <select
              value={role}
              onChange={(e) => setRole(e.target.value as UserRole)}
              className="w-full bg-gray-800 border border-gray-700 rounded-lg px-3 py-2 text-white text-sm focus:outline-none focus:border-indigo-500"
            >
              <option value="admin">Admin — full access</option>
              <option value="operator">Operator — owns nodes</option>
              <option value="viewer">Viewer — read-only</option>
            </select>
          </div>
          {role === "operator" && (
            <div>
              <label className="text-xs text-gray-400 block mb-1">
                Owned Node IDs <span className="text-gray-600">(comma-separated, required)</span>
              </label>
              <input
                value={nodeIds}
                onChange={(e) => setNodeIds(e.target.value)}
                required
                className="w-full bg-gray-800 border border-gray-700 rounded-lg px-3 py-2 text-white text-sm font-mono focus:outline-none focus:border-indigo-500"
                placeholder="node-abc123, node-def456"
              />
            </div>
          )}
          {error && <p className="text-red-400 text-xs">{error}</p>}
          <div className="flex gap-3 pt-1">
            <button
              type="submit"
              disabled={saving}
              className="flex-1 bg-indigo-600 hover:bg-indigo-500 disabled:opacity-50 text-white rounded-lg py-2 text-sm font-semibold transition-colors"
            >
              {saving ? "Creating…" : "Create user"}
            </button>
            <button
              type="button"
              onClick={onClose}
              className="flex-1 bg-gray-800 hover:bg-gray-700 text-gray-300 rounded-lg py-2 text-sm transition-colors"
            >
              Cancel
            </button>
          </div>
        </form>
      </div>
    </div>
  );
}

// ---------------------------------------------------------------------------
// Users tab
// ---------------------------------------------------------------------------

function UsersTab({ currentUid }: { currentUid: string }) {
  const [users, setUsers] = useState<UserRecord[]>([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [selectedUid, setSelectedUid] = useState<string | null>(null);
  const [showCreate, setShowCreate] = useState(false);

  const loadUsers = useCallback(async () => {
    try {
      const data = await c2api.listUsers();
      setUsers(data);
    } catch (e) {
      setError(String(e));
    } finally {
      setLoading(false);
    }
  }, []);

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

  function handleUpdated(updated: UserRecord) {
    if (updated.uid === "__deleted__") {
      setUsers((prev) => prev.filter((u) => u.uid !== selectedUid));
      setSelectedUid(null);
    } else {
      setUsers((prev) => prev.map((u) => u.uid === updated.uid ? { ...u, ...updated } : u));
    }
  }

  function handleCreated(created: UserRecord) {
    setUsers((prev) => [...prev, created]);
  }

  const selectedUser = users.find((u) => u.uid === selectedUid);

  return (
    <div className="space-y-4">
      {showCreate && (
        <CreateUserModal
          onClose={() => setShowCreate(false)}
          onCreated={(u) => { handleCreated(u); setShowCreate(false); }}
        />
      )}

      <div className="flex items-center justify-between">
        <p className="text-xs text-gray-500 font-mono">{users.length} user{users.length !== 1 ? "s" : ""}</p>
        <button
          onClick={() => setShowCreate(true)}
          className="bg-indigo-600 hover:bg-indigo-500 text-white text-sm font-mono px-4 py-1.5 rounded-lg transition-colors"
        >
          + Create user
        </button>
      </div>

      {error && (
        <div className="bg-red-950 border border-red-800 rounded-lg p-3">
          <p className="text-red-400 text-sm font-mono">{error}</p>
        </div>
      )}

      {loading ? (
        <p className="text-gray-500 text-sm font-mono">Loading…</p>
      ) : users.length === 0 ? (
        <p className="text-gray-600 text-sm font-mono">No users found.</p>
      ) : (
        <div className="border border-gray-800 rounded-xl overflow-hidden">
          <table className="w-full text-xs font-mono">
            <thead>
              <tr className="bg-gray-900 text-gray-500 uppercase tracking-wider">
                <th className="px-4 py-2.5 text-left">Email</th>
                <th className="px-4 py-2.5 text-left hidden lg:table-cell">Name</th>
                <th className="px-4 py-2.5 text-left">Role</th>
                <th className="px-4 py-2.5 text-left hidden sm:table-cell">Discord</th>
                <th className="px-4 py-2.5 text-left hidden md:table-cell">Last sign-in</th>
                <th className="px-4 py-2.5 text-left">Status</th>
                <th className="px-4 py-2.5 w-16"></th>
              </tr>
            </thead>
            <tbody>
              {users.map((u) => (
                <tr
                  key={u.uid}
                  className={`border-t border-gray-800 transition-colors ${
                    selectedUid === u.uid ? "bg-gray-800/60" : "hover:bg-gray-900/60"
                  }`}
                >
                  <td className="px-4 py-2.5 text-gray-200">{u.email ?? "—"}</td>
                  <td className="px-4 py-2.5 text-gray-400 hidden lg:table-cell">{u.display_name ?? "—"}</td>
                  <td className="px-4 py-2.5"><RoleBadge role={u.role} /></td>
                  <td className="px-4 py-2.5 text-gray-500 hidden sm:table-cell">
                    {u.discord_linked ? `@${u.discord_username ?? "linked"}` : "—"}
                  </td>
                  <td className="px-4 py-2.5 text-gray-500 hidden md:table-cell">{fmtDate(u.last_sign_in)}</td>
                  <td className="px-4 py-2.5">
                    {u.disabled
                      ? <span className="text-red-500">Disabled</span>
                      : <span className="text-green-500">Active</span>
                    }
                  </td>
                  <td className="px-4 py-2.5 text-right">
                    <button
                      onClick={() => setSelectedUid(selectedUid === u.uid ? null : u.uid)}
                      className="text-indigo-400 hover:text-indigo-300 transition-colors"
                    >
                      {selectedUid === u.uid ? "Close" : "Edit"}
                    </button>
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      )}

      {selectedUser && (
        <UserDetailPanel
          user={selectedUser}
          onClose={() => setSelectedUid(null)}
          onUpdated={handleUpdated}
          currentUid={currentUid}
        />
      )}
    </div>
  );
}

// ---------------------------------------------------------------------------
// Audit Log tab
// ---------------------------------------------------------------------------

function AuditLogTab() {
  const [entries, setEntries] = useState<AuditEntry[]>([]);
  const [loading, setLoading] = useState(true);
  const [loadingMore, setLoadingMore] = useState(false);
  const [hasMore, setHasMore] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const PAGE = 50;

  useEffect(() => {
    c2api.getAuditLog(PAGE, 0)
      .then((data) => {
        setEntries(data);
        setHasMore(data.length === PAGE);
      })
      .catch((e) => setError(String(e)))
      .finally(() => setLoading(false));
  }, []);

  async function loadMore() {
    setLoadingMore(true);
    try {
      const more = await c2api.getAuditLog(PAGE, entries.length);
      setEntries((prev) => [...prev, ...more]);
      setHasMore(more.length === PAGE);
    } catch (e) {
      setError(String(e));
    } finally {
      setLoadingMore(false);
    }
  }

  function actionColor(action: string) {
    if (action.includes("delete")) return "text-red-400";
    if (action.includes("disable")) return "text-yellow-400";
    if (action.includes("create")) return "text-green-400";
    return "text-indigo-400";
  }

  return (
    <div className="space-y-4">
      {error && (
        <div className="bg-red-950 border border-red-800 rounded-lg p-3">
          <p className="text-red-400 text-sm font-mono">{error}</p>
        </div>
      )}

      {loading ? (
        <p className="text-gray-500 text-sm font-mono">Loading…</p>
      ) : entries.length === 0 ? (
        <p className="text-gray-600 text-sm font-mono">No audit entries yet.</p>
      ) : (
        <>
          <div className="border border-gray-800 rounded-xl overflow-hidden">
            <table className="w-full text-xs font-mono">
              <thead>
                <tr className="bg-gray-900 text-gray-500 uppercase tracking-wider">
                  <th className="px-4 py-2.5 text-left">Time</th>
                  <th className="px-4 py-2.5 text-left">Action</th>
                  <th className="px-4 py-2.5 text-left hidden sm:table-cell">Actor</th>
                  <th className="px-4 py-2.5 text-left hidden md:table-cell">Target</th>
                  <th className="px-4 py-2.5 text-left">Details</th>
                </tr>
              </thead>
              <tbody>
                {entries.map((e) => (
                  <tr key={e.log_id} className="border-t border-gray-800 hover:bg-gray-900/40">
                    <td className="px-4 py-2.5 text-gray-500 whitespace-nowrap">{fmtDatetime(e.timestamp)}</td>
                    <td className={`px-4 py-2.5 whitespace-nowrap ${actionColor(e.action)}`}>{e.action}</td>
                    <td className="px-4 py-2.5 text-gray-400 hidden sm:table-cell">{e.actor_email}</td>
                    <td className="px-4 py-2.5 text-gray-400 hidden md:table-cell">{e.target_email ?? "—"}</td>
                    <td className="px-4 py-2.5 text-gray-600 max-w-xs truncate">
                      {Object.keys(e.details).length > 0
                        ? Object.entries(e.details)
                            .map(([k, v]) => `${k}: ${JSON.stringify(v)}`)
                            .join(" · ")
                        : "—"}
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>

          {hasMore && (
            <button
              onClick={loadMore}
              disabled={loadingMore}
              className="text-sm font-mono text-indigo-400 hover:text-indigo-300 disabled:opacity-50 transition-colors"
            >
              {loadingMore ? "Loading…" : "Load more"}
            </button>
          )}
        </>
      )}
    </div>
  );
}

// ---------------------------------------------------------------------------
// Stale Calls tab
// ---------------------------------------------------------------------------

function StaleCallsTab() {
  const [minutes, setMinutes]   = useState(30);
  const [result, setResult]     = useState<{ dry_run: boolean; count: number; call_ids: string[] } | null>(null);
  const [loading, setLoading]   = useState(false);
  const [error, setError]       = useState<string | null>(null);

  async function run(dryRun: boolean) {
    setLoading(true);
    setError(null);
    setResult(null);
    try {
      const res = await c2api.closeStallCalls(minutes, dryRun);
      setResult(res);
    } catch (e) {
      setError(String(e));
    } finally {
      setLoading(false);
    }
  }

  return (
    <div className="space-y-5">
      <p className="text-xs text-gray-500 font-mono">
        Finds calls stuck in <span className="text-gray-300">active</span> status because a node rebooted before sending an end-call event.
        Preview first, then close.
      </p>

      <div className="flex flex-wrap items-end gap-4">
        <div>
          <label className="text-xs text-gray-400 block mb-1">Older than (minutes)</label>
          <input
            type="number"
            min={1} max={1440}
            value={minutes}
            onChange={(e) => setMinutes(Math.min(1440, Math.max(1, Number(e.target.value))))}
            className="w-28 bg-gray-800 border border-gray-700 rounded-lg px-3 py-1.5 text-white text-sm font-mono focus:outline-none focus:border-indigo-500"
          />
        </div>
        <button
          onClick={() => run(true)}
          disabled={loading}
          className="bg-gray-800 hover:bg-gray-700 disabled:opacity-50 border border-gray-700 text-white text-sm font-mono px-4 py-1.5 rounded-lg transition-colors"
        >
          {loading ? "Working…" : "Preview"}
        </button>
        <button
          onClick={() => run(false)}
          disabled={loading || result === null || result.count === 0}
          className="bg-red-700 hover:bg-red-600 disabled:opacity-50 text-white text-sm font-mono px-4 py-1.5 rounded-lg transition-colors"
        >
          {result && !result.dry_run ? "Closed" : result?.count ? `Close ${result.count} calls` : "Close calls"}
        </button>
      </div>

      {error && (
        <div className="bg-red-950 border border-red-800 rounded-lg p-3">
          <p className="text-red-400 text-sm font-mono">{error}</p>
        </div>
      )}

      {result && (
        <div className="bg-gray-900 border border-gray-800 rounded-xl p-4 space-y-2">
          <p className="text-sm font-mono text-white">
            {result.dry_run ? "Preview: " : "Closed: "}
            <span className={result.count > 0 ? "text-amber-400" : "text-green-400"}>
              {result.count} stale call{result.count !== 1 ? "s" : ""}
            </span>
            {result.count === 0 && <span className="text-gray-500"> — nothing to clear</span>}
          </p>
          {result.call_ids.length > 0 && (
            <div className="max-h-40 overflow-y-auto space-y-0.5">
              {result.call_ids.map((id) => (
                <p key={id} className="text-xs font-mono text-gray-400">{id}</p>
              ))}
            </div>
          )}
        </div>
      )}
    </div>
  );
}

// ---------------------------------------------------------------------------
// Main admin page
// ---------------------------------------------------------------------------

type AdminTab = "features" | "correlation" | "users" | "audit" | "calls";

const TAB_LABELS: { key: AdminTab; label: string }[] = [
  { key: "features",    label: "AI Features" },
  { key: "correlation", label: "Correlation Debug" },
  { key: "calls",       label: "Calls" },
  { key: "users",       label: "Users" },
  { key: "audit",       label: "Audit Log" },
];

export default function AdminPage() {
  const { user, isAdmin } = useAuth();
  const router = useRouter();
  const [tab, setTab] = useState<AdminTab>("features");

  useEffect(() => {
    if (!isAdmin) router.replace("/dashboard");
  }, [isAdmin, router]);

  if (!isAdmin) return null;

  // Users/Audit tabs benefit from full width; everything else is narrow
  const wide = tab === "users" || tab === "audit";

  return (
    <div className={`space-y-6 ${wide ? "" : "max-w-2xl"}`}>
      <h1 className="text-white text-xl font-bold font-mono">Admin</h1>

      <div className="flex flex-wrap gap-1 bg-gray-900 border border-gray-800 rounded-lg p-1 w-fit">
        {TAB_LABELS.map(({ key, label }) => (
          <button
            key={key}
            onClick={() => setTab(key)}
            className={`text-sm font-mono px-4 py-1.5 rounded-md transition-colors ${
              tab === key ? "bg-gray-800 text-white" : "text-gray-500 hover:text-gray-300"
            }`}
          >
            {label}
          </button>
        ))}
      </div>

      {tab === "features"    && <FeaturesTab />}
      {tab === "correlation" && <CorrelationDebugTab />}
      {tab === "calls"       && <StaleCallsTab />}
      {tab === "users"       && <UsersTab currentUid={user?.uid ?? ""} />}
      {tab === "audit"       && <AuditLogTab />}
    </div>
  );
}
