import { useState } from "react";
import { useQuery } from "@tanstack/react-query";
import { useNavigate, useSearchParams, useParams } from "react-router-dom";
import {
  Loader2,
  Search,
  BookOpen,
  Filter,
  ChevronLeft,
  ChevronRight,
  FlaskConical,
  X,
} from "lucide-react";
import { getTemplates } from "../api/test-templates";
import TestFromTemplateForm from "../components/TestFromTemplateForm";
import type { TestTemplateSummary } from "../types/models";
import { useAuth } from "../context/AuthContext";

// ── Constants ──────────────────────────────────────────────────────

const PAGE_SIZE = 12;

const SOURCE_OPTIONS = [
  { value: "", label: "All Sources" },
  { value: "atomic_red_team", label: "Atomic Red Team" },
  { value: "caldera", label: "MITRE CALDERA" },
  { value: "lolbas", label: "LOLBAS (Windows)" },
  { value: "gtfobins", label: "GTFOBins (Linux)" },
  { value: "custom", label: "Custom" },
];

const SEVERITY_OPTIONS = [
  { value: "", label: "All Severities" },
  { value: "low", label: "Low" },
  { value: "medium", label: "Medium" },
  { value: "high", label: "High" },
  { value: "critical", label: "Critical" },
];

const PLATFORM_OPTIONS = [
  { value: "", label: "All Platforms" },
  { value: "windows", label: "Windows" },
  { value: "linux", label: "Linux" },
  { value: "macos", label: "macOS" },
  { value: "azure-ad", label: "Azure AD" },
  { value: "office-365", label: "Office 365" },
  { value: "containers", label: "Containers" },
];

const SOURCE_BADGE: Record<string, string> = {
  atomic_red_team: "bg-red-900/50 text-red-400 border-red-500/30",
  caldera: "bg-purple-900/50 text-purple-400 border-purple-500/30",
  lolbas: "bg-amber-900/50 text-amber-400 border-amber-500/30",
  gtfobins: "bg-green-900/50 text-green-400 border-green-500/30",
  custom: "bg-cyan-900/50 text-cyan-400 border-cyan-500/30",
};

const SOURCE_LABEL: Record<string, string> = {
  atomic_red_team: "Atomic",
  caldera: "CALDERA",
  lolbas: "LOLBAS",
  gtfobins: "GTFOBins",
  custom: "Custom",
};

const SEVERITY_BADGE: Record<string, string> = {
  low: "bg-blue-900/50 text-blue-400 border-blue-500/30",
  medium: "bg-yellow-900/50 text-yellow-400 border-yellow-500/30",
  high: "bg-orange-900/50 text-orange-400 border-orange-500/30",
  critical: "bg-red-900/50 text-red-400 border-red-500/30",
};

// ── Component ──────────────────────────────────────────────────────

export default function TestCatalogPage() {
  const navigate = useNavigate();
  const { templateId } = useParams<{ templateId: string }>();
  const [searchParams, setSearchParams] = useSearchParams();
  const { user } = useAuth();

  // Only leads and admins can create tests from templates
  const canUseTemplate =
    user?.role === "admin" ||
    user?.role === "red_lead" ||
    user?.role === "blue_lead";

  const [search, setSearch] = useState(searchParams.get("search") || "");
  const [source, setSource] = useState(searchParams.get("source") || "");
  const [platform, setPlatform] = useState(searchParams.get("platform") || "");
  const [severity, setSeverity] = useState(searchParams.get("severity") || "");
  const [page, setPage] = useState(0);

  // Build filters
  const filters = {
    search: search || undefined,
    source: source || undefined,
    platform: platform || undefined,
    severity: severity || undefined,
    offset: page * PAGE_SIZE,
    limit: PAGE_SIZE,
  };

  const { data: templates = [], isLoading } = useQuery({
    queryKey: ["test-templates", filters],
    queryFn: () => getTemplates(filters),
  });

  // ── Filter handlers ──────────────────────────────────────────────

  const applyFilters = () => {
    setPage(0);
    const params = new URLSearchParams();
    if (search) params.set("search", search);
    if (source) params.set("source", source);
    if (platform) params.set("platform", platform);
    if (severity) params.set("severity", severity);
    setSearchParams(params);
  };

  const clearFilters = () => {
    setSearch("");
    setSource("");
    setPlatform("");
    setSeverity("");
    setPage(0);
    setSearchParams({});
  };

  const hasActiveFilters = search || source || platform || severity;

  // ── Render ───────────────────────────────────────────────────────

  return (
    <div className="space-y-6">
      {/* Page header */}
      <div>
        <h1 className="text-2xl font-bold text-white">Test Catalog</h1>
        <p className="mt-1 text-sm text-gray-400">
          Browse available test templates. Use a template to quickly create a security test.
        </p>
      </div>

      {/* Filters bar */}
      <div className="rounded-xl border border-gray-800 bg-gray-900 p-4">
        <div className="flex flex-wrap items-end gap-3">
          {/* Search */}
          <div className="flex-1 min-w-[200px]">
            <label className="mb-1 block text-xs font-medium text-gray-500">Search</label>
            <div className="relative">
              <Search className="absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-gray-500" />
              <input
                value={search}
                onChange={(e) => setSearch(e.target.value)}
                onKeyDown={(e) => e.key === "Enter" && applyFilters()}
                placeholder="Search templates..."
                className="w-full rounded-lg border border-gray-700 bg-gray-800 py-2 pl-9 pr-3 text-sm text-gray-200 placeholder-gray-500 focus:border-cyan-500 focus:outline-none focus:ring-1 focus:ring-cyan-500"
              />
            </div>
          </div>

          {/* Source */}
          <div className="min-w-[150px]">
            <label className="mb-1 block text-xs font-medium text-gray-500">Source</label>
            <select
              value={source}
              onChange={(e) => { setSource(e.target.value); }}
              className="w-full rounded-lg border border-gray-700 bg-gray-800 px-3 py-2 text-sm text-gray-200 focus:border-cyan-500 focus:outline-none"
            >
              {SOURCE_OPTIONS.map((o) => (
                <option key={o.value} value={o.value}>{o.label}</option>
              ))}
            </select>
          </div>

          {/* Platform */}
          <div className="min-w-[150px]">
            <label className="mb-1 block text-xs font-medium text-gray-500">Platform</label>
            <select
              value={platform}
              onChange={(e) => { setPlatform(e.target.value); }}
              className="w-full rounded-lg border border-gray-700 bg-gray-800 px-3 py-2 text-sm text-gray-200 focus:border-cyan-500 focus:outline-none"
            >
              {PLATFORM_OPTIONS.map((o) => (
                <option key={o.value} value={o.value}>{o.label}</option>
              ))}
            </select>
          </div>

          {/* Severity */}
          <div className="min-w-[140px]">
            <label className="mb-1 block text-xs font-medium text-gray-500">Severity</label>
            <select
              value={severity}
              onChange={(e) => { setSeverity(e.target.value); }}
              className="w-full rounded-lg border border-gray-700 bg-gray-800 px-3 py-2 text-sm text-gray-200 focus:border-cyan-500 focus:outline-none"
            >
              {SEVERITY_OPTIONS.map((o) => (
                <option key={o.value} value={o.value}>{o.label}</option>
              ))}
            </select>
          </div>

          {/* Buttons */}
          <button
            onClick={applyFilters}
            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"
          >
            <Filter className="h-4 w-4" />
            Apply
          </button>

          {hasActiveFilters && (
            <button
              onClick={clearFilters}
              className="flex items-center gap-1.5 rounded-lg border border-gray-700 px-3 py-2 text-sm text-gray-400 hover:bg-gray-800 transition-colors"
            >
              <X className="h-4 w-4" />
              Clear
            </button>
          )}
        </div>
      </div>

      {/* Results */}
      {isLoading ? (
        <div className="flex h-48 items-center justify-center">
          <Loader2 className="h-8 w-8 animate-spin text-cyan-400" />
        </div>
      ) : templates.length === 0 ? (
        <div className="flex flex-col items-center justify-center rounded-xl border border-gray-800 bg-gray-900 py-16">
          <BookOpen className="h-12 w-12 text-gray-600" />
          <p className="mt-3 text-gray-400">No templates found</p>
          <p className="mt-1 text-sm text-gray-500">
            {hasActiveFilters
              ? "Try adjusting your filters or search term."
              : "Import Atomic Red Team tests from the System page to populate the catalog."}
          </p>
        </div>
      ) : (
        <>
          {/* Template Grid */}
          <div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-3">
            {templates.map((tpl) => (
              <TemplateCard
                key={tpl.id}
                template={tpl}
                canUse={canUseTemplate}
                onUse={() => navigate(`/test-catalog/${tpl.id}/use`)}
              />
            ))}
          </div>

          {/* Pagination */}
          <div className="flex items-center justify-between">
            <p className="text-sm text-gray-500">
              Showing {page * PAGE_SIZE + 1}
              {" - "}
              {page * PAGE_SIZE + templates.length}
            </p>
            <div className="flex items-center gap-2">
              <button
                onClick={() => setPage((p) => Math.max(0, p - 1))}
                disabled={page === 0}
                className="flex items-center gap-1 rounded-lg border border-gray-700 px-3 py-1.5 text-sm text-gray-400 hover:bg-gray-800 disabled:opacity-40 transition-colors"
              >
                <ChevronLeft className="h-4 w-4" />
                Prev
              </button>
              <span className="text-sm text-gray-400">Page {page + 1}</span>
              <button
                onClick={() => setPage((p) => p + 1)}
                disabled={templates.length < PAGE_SIZE}
                className="flex items-center gap-1 rounded-lg border border-gray-700 px-3 py-1.5 text-sm text-gray-400 hover:bg-gray-800 disabled:opacity-40 transition-colors"
              >
                Next
                <ChevronRight className="h-4 w-4" />
              </button>
            </div>
          </div>
        </>
      )}

      {/* Template instantiation modal */}
      {templateId && (
        <TestFromTemplateForm
          templateId={templateId}
          onClose={() => navigate("/test-catalog")}
        />
      )}
    </div>
  );
}

// ── Template Card ──────────────────────────────────────────────────

function TemplateCard({
  template,
  canUse,
  onUse,
}: {
  template: TestTemplateSummary;
  canUse: boolean;
  onUse: () => void;
}) {
  return (
    <div className="flex flex-col rounded-xl border border-gray-800 bg-gray-900 p-5 transition-colors hover:border-gray-700">
      {/* Header */}
      <div className="flex items-start justify-between gap-2">
        <div className="flex items-center gap-2">
          <FlaskConical className="h-5 w-5 shrink-0 text-cyan-400" />
          <h3 className="line-clamp-2 text-sm font-semibold text-white">
            {template.name}
          </h3>
        </div>
      </div>

      {/* Badges */}
      <div className="mt-3 flex flex-wrap gap-1.5">
        {/* Technique */}
        <span className="inline-flex rounded-full border border-gray-600/30 bg-gray-800/50 px-2 py-0.5 text-xs text-gray-400">
          {template.mitre_technique_id}
        </span>

        {/* Source */}
        <span
          className={`inline-flex rounded-full border px-2 py-0.5 text-xs font-medium ${
            SOURCE_BADGE[template.source] || "bg-gray-800/50 text-gray-400 border-gray-600/30"
          }`}
        >
          {SOURCE_LABEL[template.source] || template.source}
        </span>

        {/* Platform */}
        {template.platform && (
          <span className="inline-flex rounded-full border border-gray-600/30 bg-gray-800/50 px-2 py-0.5 text-xs capitalize text-gray-400">
            {template.platform}
          </span>
        )}

        {/* Severity */}
        {template.severity && (
          <span
            className={`inline-flex rounded-full border px-2 py-0.5 text-xs font-medium capitalize ${
              SEVERITY_BADGE[template.severity] || "bg-gray-800/50 text-gray-400 border-gray-600/30"
            }`}
          >
            {template.severity}
          </span>
        )}
      </div>

      {/* Spacer */}
      <div className="flex-1" />

      {/* Action — only visible to users who can create tests */}
      {canUse && (
        <button
          onClick={onUse}
          className="mt-4 flex w-full items-center justify-center gap-1.5 rounded-lg border border-cyan-500/30 bg-cyan-500/10 py-2 text-sm font-medium text-cyan-400 hover:bg-cyan-500/20 transition-colors"
        >
          <FlaskConical className="h-4 w-4" />
          Use Template
        </button>
      )}
    </div>
  );
}
