import { useState, useMemo } from "react";
import { useNavigate } from "react-router-dom";
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
import {
  Loader2,
  AlertCircle,
  ArrowUp,
  ArrowDown,
  Minus,
  GitCompareArrows,
  Camera,
  Plus,
  TrendingUp,
  TrendingDown,
} from "lucide-react";
import {
  listSnapshots,
  compareSnapshots,
  createSnapshot,
  type SnapshotSummary,
  type SnapshotComparison,
} from "../api/snapshots";

type Tab = "improved" | "worsened" | "unchanged";

const statusColors: Record<string, string> = {
  validated: "text-green-400",
  partial: "text-yellow-400",
  not_covered: "text-red-400",
  in_progress: "text-blue-400",
  not_evaluated: "text-gray-500",
};

const statusDots: Record<string, string> = {
  validated: "bg-green-400",
  partial: "bg-yellow-400",
  not_covered: "bg-red-400",
  in_progress: "bg-blue-400",
  not_evaluated: "bg-gray-500",
};

function StatusBadge({ status }: { status: string }) {
  return (
    <span className="inline-flex items-center gap-1.5 text-xs">
      <span className={`h-2 w-2 rounded-full ${statusDots[status] || statusDots.not_evaluated}`} />
      <span className={statusColors[status] || statusColors.not_evaluated}>
        {status.replace(/_/g, " ")}
      </span>
    </span>
  );
}

function DeltaArrow({ delta }: { delta: number }) {
  if (delta > 0) return <ArrowUp className="h-3.5 w-3.5 text-green-400" />;
  if (delta < 0) return <ArrowDown className="h-3.5 w-3.5 text-red-400" />;
  return <Minus className="h-3.5 w-3.5 text-gray-500" />;
}

function MetricCard({
  label,
  valueA,
  valueB,
  suffix,
}: {
  label: string;
  valueA: number;
  valueB: number;
  suffix?: string;
}) {
  const delta = valueB - valueA;
  const deltaColor =
    delta > 0 ? "text-green-400" : delta < 0 ? "text-red-400" : "text-gray-500";

  return (
    <div className="flex flex-col gap-1">
      <span className="text-xs text-gray-500">{label}</span>
      <div className="flex items-baseline gap-2">
        <span className="text-lg font-bold text-white">
          {valueB}
          {suffix}
        </span>
        {delta !== 0 && (
          <span className={`flex items-center gap-0.5 text-xs font-medium ${deltaColor}`}>
            <DeltaArrow delta={delta} />
            {delta > 0 ? "+" : ""}
            {delta}
          </span>
        )}
      </div>
    </div>
  );
}

export default function ComparisonPage() {
  const navigate = useNavigate();
  const queryClient = useQueryClient();
  const [snapA, setSnapA] = useState<string>("");
  const [snapB, setSnapB] = useState<string>("");
  const [activeTab, setActiveTab] = useState<Tab>("improved");
  const [showNameInput, setShowNameInput] = useState(false);
  const [snapshotName, setSnapshotName] = useState("");

  // Fetch all snapshots for the dropdowns
  const { data: snapshotsData, isLoading: isLoadingSnapshots } = useQuery({
    queryKey: ["snapshots", "all"],
    queryFn: () => listSnapshots({ limit: 200 }),
  });

  // Create snapshot mutation
  const createSnapshotMutation = useMutation({
    mutationFn: (name?: string) => createSnapshot(name),
    onSuccess: (newSnapshot) => {
      queryClient.invalidateQueries({ queryKey: ["snapshots"] });
      setShowNameInput(false);
      setSnapshotName("");
      // Auto-select the new snapshot as Snapshot B
      setSnapB(newSnapshot.id);
    },
  });

  const snapshots = snapshotsData?.items || [];

  // Comparison query
  const {
    data: comparison,
    isLoading: isComparing,
    error: compareError,
  } = useQuery({
    queryKey: ["snapshot-compare", snapA, snapB],
    queryFn: () => compareSnapshots(snapA, snapB),
    enabled: !!snapA && !!snapB && snapA !== snapB,
  });

  const formatDate = (dateStr: string | null) => {
    if (!dateStr) return "—";
    return new Date(dateStr).toLocaleDateString("en-US", {
      year: "numeric",
      month: "short",
      day: "numeric",
      hour: "2-digit",
      minute: "2-digit",
    });
  };

  // For the "unchanged" tab, we don't get individual rows from the API,
  // just a count, so we show the count.
  const tabData = useMemo(() => {
    if (!comparison) return { improved: [], worsened: [], unchanged_count: 0 };
    return {
      improved: comparison.improved,
      worsened: comparison.worsened,
      unchanged_count: comparison.unchanged_count,
    };
  }, [comparison]);

  return (
    <div className="space-y-6">
      {/* Header */}
      <div className="flex items-center justify-between">
        <div className="flex items-center gap-3">
          <div className="rounded-lg bg-cyan-500/10 p-2.5">
            <GitCompareArrows className="h-6 w-6 text-cyan-400" />
          </div>
          <div>
            <h1 className="text-2xl font-bold text-white">Temporal Comparison</h1>
            <p className="text-sm text-gray-400">Compare coverage snapshots over time</p>
          </div>
        </div>

        {/* Create Snapshot */}
        <div className="flex items-center gap-2">
          {showNameInput ? (
            <>
              <input
                value={snapshotName}
                onChange={(e) => setSnapshotName(e.target.value)}
                onKeyDown={(e) => {
                  if (e.key === "Enter") createSnapshotMutation.mutate(snapshotName || undefined);
                  if (e.key === "Escape") { setShowNameInput(false); setSnapshotName(""); }
                }}
                placeholder="Snapshot name (optional)"
                autoFocus
                className="rounded-lg border border-gray-700 bg-gray-800 px-3 py-2 text-sm text-gray-200 placeholder-gray-500 focus:border-cyan-500 focus:outline-none w-56"
              />
              <button
                onClick={() => createSnapshotMutation.mutate(snapshotName || undefined)}
                disabled={createSnapshotMutation.isPending}
                className="flex items-center gap-1.5 rounded-lg bg-cyan-600 px-4 py-2 text-sm font-medium text-white hover:bg-cyan-500 transition-colors disabled:opacity-50"
              >
                {createSnapshotMutation.isPending ? (
                  <Loader2 className="h-4 w-4 animate-spin" />
                ) : (
                  <Camera className="h-4 w-4" />
                )}
                Save
              </button>
              <button
                onClick={() => { setShowNameInput(false); setSnapshotName(""); }}
                className="rounded-lg border border-gray-700 px-3 py-2 text-sm text-gray-400 hover:bg-gray-800 transition-colors"
              >
                Cancel
              </button>
            </>
          ) : (
            <button
              onClick={() => setShowNameInput(true)}
              className="flex items-center gap-1.5 rounded-lg bg-cyan-600 px-4 py-2 text-sm font-medium text-white hover:bg-cyan-500 transition-colors"
            >
              <Plus className="h-4 w-4" />
              Create Snapshot
            </button>
          )}
        </div>
      </div>

      {/* Snapshot selectors */}
      <div className="rounded-xl border border-gray-800 bg-gray-900 p-6">
        <div className="grid grid-cols-1 gap-6 md:grid-cols-2">
          {/* Snapshot A */}
          <div>
            <label className="mb-2 block text-sm font-medium text-gray-400">
              Snapshot A (Baseline)
            </label>
            <select
              value={snapA}
              onChange={(e) => setSnapA(e.target.value)}
              className="w-full rounded-lg border border-gray-700 bg-gray-800 px-4 py-2.5 text-sm text-white focus:border-cyan-500 focus:outline-none focus:ring-1 focus:ring-cyan-500"
            >
              <option value="">Select snapshot...</option>
              {snapshots.map((s) => (
                <option key={s.id} value={s.id}>
                  {s.name || `Snapshot ${formatDate(s.created_at)}`} — Score:{" "}
                  {s.organization_score}
                </option>
              ))}
            </select>
          </div>

          {/* Snapshot B */}
          <div>
            <label className="mb-2 block text-sm font-medium text-gray-400">
              Snapshot B (Current)
            </label>
            <select
              value={snapB}
              onChange={(e) => setSnapB(e.target.value)}
              className="w-full rounded-lg border border-gray-700 bg-gray-800 px-4 py-2.5 text-sm text-white focus:border-cyan-500 focus:outline-none focus:ring-1 focus:ring-cyan-500"
            >
              <option value="">Select snapshot...</option>
              {snapshots.map((s) => (
                <option key={s.id} value={s.id}>
                  {s.name || `Snapshot ${formatDate(s.created_at)}`} — Score:{" "}
                  {s.organization_score}
                </option>
              ))}
            </select>
          </div>
        </div>

        {isLoadingSnapshots && (
          <div className="mt-4 flex items-center gap-2 text-sm text-gray-400">
            <Loader2 className="h-4 w-4 animate-spin" />
            Loading snapshots...
          </div>
        )}
      </div>

      {/* Loading / Error */}
      {isComparing && (
        <div className="flex h-40 items-center justify-center">
          <Loader2 className="h-8 w-8 animate-spin text-cyan-400" />
        </div>
      )}
      {compareError && (
        <div className="flex items-center gap-2 rounded-lg border border-red-500/30 bg-red-900/30 px-4 py-3 text-sm text-red-400">
          <AlertCircle className="h-4 w-4" />
          Failed to compare snapshots
        </div>
      )}

      {/* Comparison results */}
      {comparison && (
        <>
          {/* Side-by-side score cards */}
          <div className="grid grid-cols-1 gap-4 md:grid-cols-2">
            {/* Snapshot A card */}
            <div className="rounded-xl border border-gray-800 bg-gray-900 p-6">
              <div className="mb-4 flex items-center gap-2">
                <Camera className="h-4 w-4 text-gray-500" />
                <span className="text-sm font-medium text-gray-400">
                  {comparison.snapshot_a.name || "Snapshot A"}
                </span>
                <span className="ml-auto text-xs text-gray-600">
                  {formatDate(comparison.snapshot_a.created_at)}
                </span>
              </div>
              <div className="text-3xl font-bold text-white">
                {comparison.snapshot_a.organization_score}
              </div>
              <div className="mt-3 grid grid-cols-2 gap-3">
                <MetricCard
                  label="Validated"
                  valueA={comparison.snapshot_a.validated_count}
                  valueB={comparison.snapshot_a.validated_count}
                />
                <MetricCard
                  label="Partial"
                  valueA={comparison.snapshot_a.partial_count}
                  valueB={comparison.snapshot_a.partial_count}
                />
                <MetricCard
                  label="Not Covered"
                  valueA={comparison.snapshot_a.not_covered_count}
                  valueB={comparison.snapshot_a.not_covered_count}
                />
                <MetricCard
                  label="In Progress"
                  valueA={comparison.snapshot_a.in_progress_count}
                  valueB={comparison.snapshot_a.in_progress_count}
                />
              </div>
            </div>

            {/* Snapshot B card */}
            <div className="rounded-xl border border-gray-800 bg-gray-900 p-6">
              <div className="mb-4 flex items-center gap-2">
                <Camera className="h-4 w-4 text-gray-500" />
                <span className="text-sm font-medium text-gray-400">
                  {comparison.snapshot_b.name || "Snapshot B"}
                </span>
                <span className="ml-auto text-xs text-gray-600">
                  {formatDate(comparison.snapshot_b.created_at)}
                </span>
              </div>
              <div className="flex items-baseline gap-3">
                <span className="text-3xl font-bold text-white">
                  {comparison.snapshot_b.organization_score}
                </span>
                {comparison.score_delta !== 0 && (
                  <span
                    className={`flex items-center gap-1 text-sm font-semibold ${
                      comparison.score_delta > 0 ? "text-green-400" : "text-red-400"
                    }`}
                  >
                    {comparison.score_delta > 0 ? (
                      <TrendingUp className="h-4 w-4" />
                    ) : (
                      <TrendingDown className="h-4 w-4" />
                    )}
                    {comparison.score_delta > 0 ? "+" : ""}
                    {comparison.score_delta}
                  </span>
                )}
              </div>
              <div className="mt-3 grid grid-cols-2 gap-3">
                <MetricCard
                  label="Validated"
                  valueA={comparison.snapshot_a.validated_count}
                  valueB={comparison.snapshot_b.validated_count}
                />
                <MetricCard
                  label="Partial"
                  valueA={comparison.snapshot_a.partial_count}
                  valueB={comparison.snapshot_b.partial_count}
                />
                <MetricCard
                  label="Not Covered"
                  valueA={comparison.snapshot_a.not_covered_count}
                  valueB={comparison.snapshot_b.not_covered_count}
                />
                <MetricCard
                  label="In Progress"
                  valueA={comparison.snapshot_a.in_progress_count}
                  valueB={comparison.snapshot_b.in_progress_count}
                />
              </div>
            </div>
          </div>

          {/* Tabs */}
          <div className="rounded-xl border border-gray-800 bg-gray-900">
            <div className="flex border-b border-gray-800">
              <button
                onClick={() => setActiveTab("improved")}
                className={`flex items-center gap-2 px-6 py-3 text-sm font-medium transition-colors ${
                  activeTab === "improved"
                    ? "border-b-2 border-green-400 text-green-400"
                    : "text-gray-400 hover:text-white"
                }`}
              >
                <ArrowUp className="h-4 w-4" />
                Improved ({comparison.summary.improved_count})
              </button>
              <button
                onClick={() => setActiveTab("worsened")}
                className={`flex items-center gap-2 px-6 py-3 text-sm font-medium transition-colors ${
                  activeTab === "worsened"
                    ? "border-b-2 border-red-400 text-red-400"
                    : "text-gray-400 hover:text-white"
                }`}
              >
                <ArrowDown className="h-4 w-4" />
                Worsened ({comparison.summary.worsened_count})
              </button>
              <button
                onClick={() => setActiveTab("unchanged")}
                className={`flex items-center gap-2 px-6 py-3 text-sm font-medium transition-colors ${
                  activeTab === "unchanged"
                    ? "border-b-2 border-gray-400 text-gray-400"
                    : "text-gray-500 hover:text-white"
                }`}
              >
                <Minus className="h-4 w-4" />
                Unchanged ({comparison.unchanged_count})
              </button>
            </div>

            <div className="p-6">
              {activeTab === "unchanged" ? (
                <div className="flex flex-col items-center justify-center py-8 text-gray-400">
                  <Minus className="mb-2 h-8 w-8 text-gray-600" />
                  <p className="text-lg font-medium">
                    {comparison.unchanged_count} techniques unchanged
                  </p>
                  <p className="mt-1 text-sm text-gray-500">
                    These techniques had the same status and score in both snapshots.
                  </p>
                </div>
              ) : (
                <>
                  {(activeTab === "improved"
                    ? tabData.improved
                    : tabData.worsened
                  ).length === 0 ? (
                    <div className="flex flex-col items-center justify-center py-8 text-gray-400">
                      <p className="text-sm">No techniques {activeTab} between snapshots.</p>
                    </div>
                  ) : (
                    <div className="overflow-x-auto">
                      <table className="w-full text-left text-sm">
                        <thead>
                          <tr className="border-b border-gray-800">
                            <th className="pb-3 pr-4 font-medium text-gray-400">MITRE ID</th>
                            <th className="pb-3 px-4 font-medium text-gray-400">Before</th>
                            <th className="pb-3 px-4 font-medium text-gray-400">After</th>
                            <th className="pb-3 px-4 font-medium text-gray-400">Score Before</th>
                            <th className="pb-3 px-4 font-medium text-gray-400">Score After</th>
                            <th className="pb-3 pl-4 font-medium text-gray-400">Delta</th>
                          </tr>
                        </thead>
                        <tbody>
                          {(activeTab === "improved"
                            ? tabData.improved
                            : tabData.worsened
                          ).map((item) => (
                            <tr
                              key={item.mitre_id}
                              className="border-b border-gray-800/50 hover:bg-gray-800/30 transition-colors cursor-pointer"
                              onClick={() =>
                                navigate(`/techniques/${item.mitre_id}`)
                              }
                            >
                              <td className="py-3 pr-4">
                                <span className="font-mono text-xs text-cyan-400">
                                  {item.mitre_id}
                                </span>
                              </td>
                              <td className="py-3 px-4">
                                <StatusBadge status={item.old_status} />
                              </td>
                              <td className="py-3 px-4">
                                <StatusBadge status={item.new_status} />
                              </td>
                              <td className="py-3 px-4">
                                <span className="text-xs text-gray-400">{item.old_score}</span>
                              </td>
                              <td className="py-3 px-4">
                                <span className="text-xs text-white">{item.new_score}</span>
                              </td>
                              <td className="py-3 pl-4">
                                <span
                                  className={`flex items-center gap-1 text-xs font-medium ${
                                    item.new_score > item.old_score
                                      ? "text-green-400"
                                      : item.new_score < item.old_score
                                        ? "text-red-400"
                                        : "text-gray-500"
                                  }`}
                                >
                                  <DeltaArrow delta={item.new_score - item.old_score} />
                                  {item.new_score > item.old_score ? "+" : ""}
                                  {Math.round((item.new_score - item.old_score) * 10) / 10}
                                </span>
                              </td>
                            </tr>
                          ))}
                        </tbody>
                      </table>
                    </div>
                  )}
                </>
              )}
            </div>
          </div>
        </>
      )}

      {/* No selection prompt */}
      {!comparison && !isComparing && !compareError && (
        <div className="flex flex-col items-center justify-center py-16 text-gray-400">
          <GitCompareArrows className="mb-3 h-12 w-12 text-gray-600" />
          <p className="text-lg font-medium">Select two snapshots to compare</p>
          <p className="mt-1 text-sm text-gray-500">
            Choose a baseline and current snapshot from the dropdowns above.
          </p>
        </div>
      )}
    </div>
  );
}
