"use client";

import { useState, useEffect, useCallback } from "react";
import {
  ShieldCheck,
  ShieldX,
  ShieldAlert,
  Play,
  RefreshCw,
  CheckCircle,
  XCircle,
  ChevronDown,
  ChevronRight,
  Database,
  Clock,
} from "lucide-react";

interface VerificationCheckItem {
  name: string;
  passed: boolean;
  detail: string;
}

interface VerificationResult {
  id: string;
  backupId: string;
  destinationId: string;
  timestamp: string;
  passed: boolean;
  score: number;
  checks: VerificationCheckItem[];
  error: string | null;
  extractedFileCount: number;
  dbFiles: string[];
}

const CHECK_LABELS: Record<string, string> = {
  archive_download: "Archive Download",
  archive_size: "Archive Size",
  archive_extract: "Extraction",
  file_count: "File Count",
  sqlite_integrity: "SQLite Integrity",
  critical_files: "Critical Files",
  chain_integrity: "Chain Integrity",
};

function formatDate(iso: string): string {
  return new Date(iso).toLocaleString();
}

function formatAge(iso: string): string {
  const ageMs = Date.now() - new Date(iso).getTime();
  const hours = Math.floor(ageMs / 3600000);
  const minutes = Math.floor((ageMs % 3600000) / 60000);
  if (hours >= 24) return `${Math.floor(hours / 24)}d ago`;
  if (hours > 0) return `${hours}h ${minutes}m ago`;
  return `${minutes}m ago`;
}

function ScoreBadge({ score, passed }: { score: number; passed: boolean }) {
  const color = passed
    ? "bg-emerald-100 text-emerald-800 dark:bg-emerald-900/30 dark:text-emerald-400"
    : score >= 50
    ? "bg-amber-100 text-amber-800 dark:bg-amber-900/30 dark:text-amber-400"
    : "bg-red-100 text-red-800 dark:bg-red-900/30 dark:text-red-400";
  return (
    <span className={`inline-flex items-center rounded-full px-2 py-0.5 text-xs font-semibold ${color}`}>
      {score}%
    </span>
  );
}

function CheckRow({ check }: { check: VerificationCheckItem }) {
  const [open, setOpen] = useState(false);
  const label = CHECK_LABELS[check.name] ?? check.name;
  return (
    <div className="border-b border-zinc-100 last:border-0 dark:border-zinc-800">
      <button
        onClick={() => setOpen(!open)}
        className="flex w-full items-center gap-2 px-3 py-2 text-left text-sm hover:bg-zinc-50 dark:hover:bg-zinc-800/50"
      >
        {check.passed ? (
          <CheckCircle size={14} className="shrink-0 text-emerald-500" />
        ) : (
          <XCircle size={14} className="shrink-0 text-red-500" />
        )}
        <span className="flex-1 font-medium text-zinc-700 dark:text-zinc-300">{label}</span>
        {open ? (
          <ChevronDown size={12} className="text-zinc-400" />
        ) : (
          <ChevronRight size={12} className="text-zinc-400" />
        )}
      </button>
      {open && (
        <div className="px-8 pb-2 text-xs text-zinc-500 dark:text-zinc-400">
          {check.detail}
        </div>
      )}
    </div>
  );
}

function VerificationCard({ result, isLatest }: { result: VerificationResult; isLatest: boolean }) {
  const [expanded, setExpanded] = useState(isLatest && !result.passed);

  return (
    <div
      className={`rounded-lg border ${
        result.passed
          ? "border-emerald-200 dark:border-emerald-800/50"
          : "border-red-200 dark:border-red-800/50"
      } overflow-hidden bg-white dark:bg-zinc-900`}
    >
      <button
        onClick={() => setExpanded(!expanded)}
        className="flex w-full items-center gap-3 p-4 text-left hover:bg-zinc-50 dark:hover:bg-zinc-800/30"
      >
        {result.passed ? (
          <ShieldCheck size={20} className="shrink-0 text-emerald-500" />
        ) : (
          <ShieldX size={20} className="shrink-0 text-red-500" />
        )}

        <div className="min-w-0 flex-1">
          <div className="flex items-center gap-2 flex-wrap">
            <span className="text-sm font-semibold text-zinc-800 dark:text-zinc-200">
              {result.passed ? "Passed" : "Failed"}
            </span>
            <ScoreBadge score={result.score} passed={result.passed} />
            {isLatest && (
              <span className="rounded-full bg-zinc-100 px-2 py-0.5 text-xs text-zinc-500 dark:bg-zinc-800 dark:text-zinc-400">
                Latest
              </span>
            )}
          </div>
          <div className="mt-0.5 flex items-center gap-3 text-xs text-zinc-500 dark:text-zinc-400">
            <span>{formatDate(result.timestamp)}</span>
            <span>·</span>
            <span>{formatAge(result.timestamp)}</span>
            {result.extractedFileCount > 0 && (
              <>
                <span>·</span>
                <span>{result.extractedFileCount} files</span>
              </>
            )}
            {result.dbFiles.length > 0 && (
              <>
                <span>·</span>
                <Database size={10} className="inline" />
                <span>{result.dbFiles.length} db</span>
              </>
            )}
          </div>
          <div className="mt-0.5 font-mono text-xs text-zinc-400 dark:text-zinc-500">
            backup: {result.backupId.slice(0, 8)}…
          </div>
        </div>

        <div className="shrink-0">
          {expanded ? (
            <ChevronDown size={16} className="text-zinc-400" />
          ) : (
            <ChevronRight size={16} className="text-zinc-400" />
          )}
        </div>
      </button>

      {expanded && (
        <div className="border-t border-zinc-100 dark:border-zinc-800">
          {result.error && (
            <div className="px-4 py-2 text-xs text-red-600 dark:text-red-400 bg-red-50 dark:bg-red-900/10">
              Error: {result.error}
            </div>
          )}
          <div className="divide-y divide-zinc-100 dark:divide-zinc-800">
            {result.checks.map((check) => (
              <CheckRow key={check.name} check={check} />
            ))}
          </div>
          {result.dbFiles.length > 0 && (
            <div className="border-t border-zinc-100 dark:border-zinc-800 px-4 py-2">
              <div className="text-xs font-medium text-zinc-500 dark:text-zinc-400 mb-1">SQLite files checked</div>
              {result.dbFiles.map((f) => (
                <div key={f} className="font-mono text-xs text-zinc-400 dark:text-zinc-500">{f}</div>
              ))}
            </div>
          )}
        </div>
      )}
    </div>
  );
}

export function VerificationView() {
  const [history, setHistory] = useState<VerificationResult[]>([]);
  const [loading, setLoading] = useState(true);
  const [running, setRunning] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [runMessage, setRunMessage] = useState<string | null>(null);

  const fetchHistory = useCallback(async () => {
    try {
      const res = await fetch("/api/admin/backup/verify/history");
      if (res.ok) {
        const data = await res.json();
        setHistory(data);
      }
    } catch {
      setError("Backup service unavailable");
    } finally {
      setLoading(false);
    }
  }, []);

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

  const runNow = useCallback(async () => {
    setRunning(true);
    setRunMessage(null);
    try {
      const res = await fetch("/api/admin/backup/verify", { method: "POST" });
      const data = await res.json();
      if (res.ok) {
        setRunMessage(
          `Verification started for backup ${data.backupId?.slice(0, 8)}…. Results will appear in ~1-2 minutes.`
        );
        // Poll for new result after a delay
        setTimeout(() => fetchHistory(), 15000);
        setTimeout(() => fetchHistory(), 60000);
        setTimeout(() => fetchHistory(), 120000);
      } else {
        setRunMessage(`Error: ${data.error || "Unknown error"}`);
      }
    } catch {
      setRunMessage("Failed to reach backup service");
    } finally {
      setRunning(false);
    }
  }, [fetchHistory]);

  const lastSuccess = history.find((r) => r.passed);
  const lastFailure = history.find((r) => !r.passed);
  const ageHours = lastSuccess
    ? (Date.now() - new Date(lastSuccess.timestamp).getTime()) / 3600000
    : null;
  const isStale = ageHours === null || ageHours > 48;

  return (
    <div className="flex h-full flex-col overflow-hidden">
      {/* Header */}
      <div className="flex items-center justify-between border-b border-zinc-200 px-6 py-4 dark:border-zinc-800">
        <div className="flex items-center gap-3">
          <ShieldCheck size={20} className="text-zinc-600 dark:text-zinc-400" />
          <h1 className="text-lg font-semibold text-zinc-900 dark:text-zinc-100">
            Backup Verification
          </h1>
        </div>
        <div className="flex items-center gap-2">
          <button
            onClick={fetchHistory}
            className="flex items-center gap-1.5 rounded-md px-3 py-1.5 text-sm text-zinc-600 hover:bg-zinc-100 dark:text-zinc-400 dark:hover:bg-zinc-800"
          >
            <RefreshCw size={14} />
            Refresh
          </button>
          <button
            onClick={runNow}
            disabled={running}
            className="flex items-center gap-1.5 rounded-md bg-zinc-900 px-3 py-1.5 text-sm text-white hover:bg-zinc-700 disabled:opacity-50 dark:bg-zinc-100 dark:text-zinc-900 dark:hover:bg-zinc-200"
          >
            <Play size={14} />
            {running ? "Starting…" : "Run Now"}
          </button>
        </div>
      </div>

      <div className="flex-1 overflow-y-auto p-6 space-y-6">
        {/* Status banner */}
        {runMessage && (
          <div className="rounded-lg bg-blue-50 px-4 py-3 text-sm text-blue-700 dark:bg-blue-900/20 dark:text-blue-300">
            {runMessage}
          </div>
        )}

        {isStale && !loading && (
          <div className="flex items-center gap-3 rounded-lg border border-amber-200 bg-amber-50 px-4 py-3 dark:border-amber-800/50 dark:bg-amber-900/10">
            <ShieldAlert size={18} className="shrink-0 text-amber-600 dark:text-amber-400" />
            <div className="text-sm">
              <p className="font-medium text-amber-800 dark:text-amber-300">
                {lastSuccess
                  ? `Last successful verification was ${formatAge(lastSuccess.timestamp)}`
                  : "No successful verification on record"}
              </p>
              <p className="text-amber-700 dark:text-amber-400">
                Run a verification now to confirm your backups are restorable.
              </p>
            </div>
          </div>
        )}

        {/* Summary stats */}
        {history.length > 0 && (
          <div className="grid grid-cols-3 gap-4">
            <div className="rounded-lg border border-zinc-200 bg-white p-4 dark:border-zinc-800 dark:bg-zinc-900">
              <div className="text-2xl font-bold text-zinc-900 dark:text-zinc-100">
                {history.filter((r) => r.passed).length}
              </div>
              <div className="text-xs text-zinc-500 dark:text-zinc-400 mt-0.5">Passed</div>
            </div>
            <div className="rounded-lg border border-zinc-200 bg-white p-4 dark:border-zinc-800 dark:bg-zinc-900">
              <div className="text-2xl font-bold text-zinc-900 dark:text-zinc-100">
                {history.filter((r) => !r.passed).length}
              </div>
              <div className="text-xs text-zinc-500 dark:text-zinc-400 mt-0.5">Failed</div>
            </div>
            <div className="rounded-lg border border-zinc-200 bg-white p-4 dark:border-zinc-800 dark:bg-zinc-900">
              <div className="flex items-center gap-1.5">
                <Clock size={14} className="text-zinc-400" />
                <div className="text-sm font-semibold text-zinc-900 dark:text-zinc-100">
                  {lastSuccess ? formatAge(lastSuccess.timestamp) : "Never"}
                </div>
              </div>
              <div className="text-xs text-zinc-500 dark:text-zinc-400 mt-0.5">Last success</div>
            </div>
          </div>
        )}

        {/* Verification history list */}
        {loading ? (
          <div className="text-center text-sm text-zinc-400 py-12">Loading…</div>
        ) : error ? (
          <div className="text-center text-sm text-red-500 py-12">{error}</div>
        ) : history.length === 0 ? (
          <div className="flex flex-col items-center justify-center py-16 text-center">
            <ShieldAlert size={40} className="text-zinc-300 dark:text-zinc-700 mb-4" />
            <p className="text-sm font-medium text-zinc-600 dark:text-zinc-400">
              No verifications yet
            </p>
            <p className="text-xs text-zinc-400 dark:text-zinc-500 mt-1">
              Click "Run Now" to verify your latest backup, or wait for the scheduled run after each backup.
            </p>
          </div>
        ) : (
          <div className="space-y-3">
            <h2 className="text-sm font-semibold text-zinc-500 dark:text-zinc-400 uppercase tracking-wide">
              Verification History
            </h2>
            {history.map((result, idx) => (
              <VerificationCard key={result.id} result={result} isLatest={idx === 0} />
            ))}
          </div>
        )}

        {/* Restore CLI info */}
        <div className="rounded-lg border border-zinc-200 bg-zinc-50 p-4 dark:border-zinc-800 dark:bg-zinc-900/50">
          <h2 className="text-sm font-semibold text-zinc-700 dark:text-zinc-300 mb-2">
            Restore CLI
          </h2>
          <p className="text-xs text-zinc-500 dark:text-zinc-400 mb-3">
            To rehearse a restore or recover from backup, use the restore CLI tool:
          </p>
          <code className="block rounded bg-zinc-900 px-3 py-2 text-xs text-zinc-300 dark:bg-zinc-800">
            node services/backup/dist/restore-cli.js &lt;backup-id&gt; &lt;target-dir&gt;
          </code>
          <p className="text-xs text-zinc-400 dark:text-zinc-500 mt-2">
            The CLI resolves the full incremental chain and applies archives in dependency order.
          </p>
        </div>
      </div>
    </div>
  );
}
