import { useState } from "react";
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
import { Loader2, AlertCircle, Download, FileText, Plus, ExternalLink, BookOpen, AlertTriangle, FlaskConical } from "lucide-react";
import {
  getComplianceFrameworks,
  getFrameworkStatus,
  downloadComplianceCSV,
  importNistMappings,
  importCisMappings,
  importDoraMappings,
  importIso27001Mappings,
  importIso42001Mappings,
  type ComplianceFrameworkSummary,
} from "../api/compliance";
import { useAuth } from "../context/AuthContext";
import ComplianceGauge from "../components/compliance/ComplianceGauge";
import ControlsTable from "../components/compliance/ControlsTable";

export default function CompliancePage() {
  const [selectedFrameworkId, setSelectedFrameworkId] = useState<string | null>(null);
  const queryClient = useQueryClient();
  const { user } = useAuth();
  const isAdmin = user?.role === "admin";

  // Fetch available frameworks
  const {
    data: frameworks,
    isLoading: loadingFrameworks,
  } = useQuery({
    queryKey: ["compliance-frameworks"],
    queryFn: getComplianceFrameworks,
  });

  // Auto-select first framework
  const activeFrameworkId = selectedFrameworkId || frameworks?.[0]?.id || null;

  // Fetch framework status
  const {
    data: frameworkStatus,
    isLoading: loadingStatus,
  } = useQuery({
    queryKey: ["compliance-status", activeFrameworkId],
    queryFn: () => getFrameworkStatus(activeFrameworkId!),
    enabled: !!activeFrameworkId,
  });

  const isLoading = loadingFrameworks || loadingStatus;
  const summary = frameworkStatus?.summary;
  const controls = frameworkStatus?.controls || [];
  const activeFramework = frameworks?.find((f) => f.id === activeFrameworkId) ?? null;

  // Mapping confidence notices for frameworks that lack an official CTID ATT&CK mapping
  type ConfidenceLevel = "community" | "experimental";
  const MAPPING_NOTICES: Record<string, { level: ConfidenceLevel; source: string; notice: string }> = {
    "DORA": {
      level: "community",
      source: "ENISA guidance + TIBER-EU threat-led testing framework",
      notice:
        "No official MITRE CTID ATT&CK mapping exists for DORA (EU 2022/2554). " +
        "The technique mappings in Aegis are based on ENISA ICT risk management guidelines and the TIBER-EU " +
        "threat-led penetration testing framework — both authoritative sources for this regulation. " +
        "They reflect regulatory intent and established industry practice, but have not been " +
        "formally certified. We recommend reviewing coverage with a compliance specialist " +
        "before submitting to supervisory authorities (EBA / ESMA / EIOPA / ECB).",
    },
    "ISO/IEC 27001:2022": {
      level: "community",
      source: "ISO/IEC 27002:2022 + industry consensus",
      notice:
        "No official MITRE CTID ATT&CK mapping exists for ISO/IEC 27001:2022. " +
        "ISO charges for its published standards, which prevents the open-source community from " +
        "producing a formally certified mapping. The technique mappings in Aegis are based on " +
        "ISO/IEC 27002:2022 implementation guidance (the companion standard) and widely adopted " +
        "industry practice from the security community. They are directionally correct and " +
        "representative, but should be validated against your organisation's specific control " +
        "implementation before use in a formal ISO 27001 audit or certification exercise.",
    },
    "ISO/IEC 42001:2023": {
      level: "experimental",
      source: "Interpretation — MITRE ATT&CK Enterprise v14 has no AI-specific techniques",
      notice:
        "ISO/IEC 42001 was published in December 2023. MITRE ATT&CK Enterprise v14 does not yet " +
        "include adversarial techniques specifically targeting AI systems (model poisoning, " +
        "adversarial examples, training data exfiltration, etc.). " +
        "The mappings in Aegis cover threats to the IT INFRASTRUCTURE that supports AI systems — " +
        "data pipelines, model-serving APIs, ML framework supply chains, and cloud AI services — " +
        "using the closest available ATT&CK techniques. " +
        "This is a best-effort directional mapping intended to identify where Red Team coverage " +
        "of AI infrastructure is lacking. It should NOT be treated as a formal ISO 42001 " +
        "compliance assessment until MITRE publishes dedicated AI attack techniques.",
    },
  };

  const handleExportCSV = async () => {
    if (activeFrameworkId) {
      await downloadComplianceCSV(activeFrameworkId);
    }
  };

  const handleExportJSON = async () => {
    if (!frameworkStatus) return;
    const json = JSON.stringify(frameworkStatus, null, 2);
    const blob = new Blob([json], { type: "application/json" });
    const url = URL.createObjectURL(blob);
    const safeName = frameworkStatus.framework.name
      .replace(/[^a-zA-Z0-9\s_-]/g, "")
      .replace(/\s+/g, "_")
      .substring(0, 64);
    const a = document.createElement("a");
    a.href = url;
    a.download = `compliance_${safeName}.json`;
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
    URL.revokeObjectURL(url);
  };

  const importNist = useMutation({
    mutationFn: importNistMappings,
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ["compliance-frameworks"] });
      queryClient.invalidateQueries({ queryKey: ["compliance-status"] });
    },
  });

  const importCis = useMutation({
    mutationFn: importCisMappings,
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ["compliance-frameworks"] });
      queryClient.invalidateQueries({ queryKey: ["compliance-status"] });
    },
  });

  const importDora = useMutation({
    mutationFn: importDoraMappings,
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ["compliance-frameworks"] });
      queryClient.invalidateQueries({ queryKey: ["compliance-status"] });
    },
  });

  const importIso27001 = useMutation({
    mutationFn: importIso27001Mappings,
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ["compliance-frameworks"] });
      queryClient.invalidateQueries({ queryKey: ["compliance-status"] });
    },
  });

  const importIso42001 = useMutation({
    mutationFn: importIso42001Mappings,
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ["compliance-frameworks"] });
      queryClient.invalidateQueries({ queryKey: ["compliance-status"] });
    },
  });

  const isImporting =
    importNist.isPending ||
    importCis.isPending ||
    importDora.isPending ||
    importIso27001.isPending ||
    importIso42001.isPending;

  if (isLoading && !frameworkStatus) {
    return (
      <div className="flex h-64 items-center justify-center">
        <Loader2 className="h-8 w-8 animate-spin text-cyan-400" />
      </div>
    );
  }

  return (
    <div className="space-y-6">
      {/* Header */}
      <div className="flex items-center justify-between">
        <div>
          <h1 className="text-2xl font-bold text-white">Compliance</h1>
          <p className="mt-1 text-sm text-gray-400">
            Map ATT&CK coverage to compliance framework controls
          </p>
        </div>

        <div className="flex items-center gap-2">
          {/* Framework selector */}
          <select
            value={activeFrameworkId || ""}
            onChange={(e) => setSelectedFrameworkId(e.target.value)}
            className="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"
          >
            {(frameworks || []).map((fw) => (
              <option key={fw.id} value={fw.id}>
                {fw.name}
              </option>
            ))}
          </select>

          {/* Export buttons */}
          <button
            onClick={handleExportCSV}
            className="flex items-center gap-1.5 rounded-lg border border-gray-700 bg-gray-800 px-3 py-2 text-xs font-medium text-gray-300 hover:border-cyan-500/50 hover:text-white"
          >
            <Download className="h-3.5 w-3.5" />
            Export CSV
          </button>
          <button
            onClick={handleExportJSON}
            className="flex items-center gap-1.5 rounded-lg border border-gray-700 bg-gray-800 px-3 py-2 text-xs font-medium text-gray-300 hover:border-cyan-500/50 hover:text-white"
          >
            <FileText className="h-3.5 w-3.5" />
            Export JSON
          </button>
        </div>
      </div>

      {/* Framework info banner */}
      {activeFramework?.description && (
        <div className="flex items-start gap-3 rounded-xl border border-gray-700/60 bg-gray-900/60 px-5 py-4">
          <BookOpen className="mt-0.5 h-4 w-4 shrink-0 text-cyan-400" />
          <div className="flex-1 min-w-0">
            <div className="flex flex-wrap items-center gap-2 mb-1">
              <span className="text-sm font-semibold text-white">{activeFramework.name}</span>
              {activeFramework.version && (
                <span className="rounded-full border border-gray-700 bg-gray-800 px-2 py-0.5 text-[10px] text-gray-400">
                  v{activeFramework.version}
                </span>
              )}
              {activeFramework.url && (
                <a
                  href={activeFramework.url}
                  target="_blank"
                  rel="noopener noreferrer"
                  className="flex items-center gap-1 text-[10px] text-cyan-400 hover:text-cyan-300 transition-colors"
                  onClick={(e) => e.stopPropagation()}
                >
                  <ExternalLink className="h-3 w-3" />
                  Official standard
                </a>
              )}
            </div>
            <p className="text-xs leading-relaxed text-gray-400">{activeFramework.description}</p>
          </div>
        </div>
      )}

      {/* Mapping confidence notice — shown for frameworks without official CTID mapping */}
      {activeFramework && MAPPING_NOTICES[activeFramework.name] && (() => {
        const notice = MAPPING_NOTICES[activeFramework.name];
        const isExperimental = notice.level === "experimental";
        return (
          <div className={`rounded-xl border px-5 py-4 ${
            isExperimental
              ? "border-orange-500/30 bg-orange-500/5"
              : "border-amber-500/25 bg-amber-500/5"
          }`}>
            <div className="flex items-start gap-3">
              {isExperimental
                ? <FlaskConical className="mt-0.5 h-4 w-4 shrink-0 text-orange-400" />
                : <AlertTriangle className="mt-0.5 h-4 w-4 shrink-0 text-amber-400" />
              }
              <div className="flex-1 min-w-0">
                <div className="flex flex-wrap items-center gap-2 mb-2">
                  <span className={`text-xs font-semibold ${isExperimental ? "text-orange-300" : "text-amber-300"}`}>
                    {isExperimental ? "Experimental mapping — use with caution" : "Community-based mapping — not officially certified"}
                  </span>
                  <span className={`rounded-full border px-2 py-0.5 text-[10px] font-medium ${
                    isExperimental
                      ? "border-orange-500/30 bg-orange-500/10 text-orange-400"
                      : "border-amber-500/25 bg-amber-500/10 text-amber-400"
                  }`}>
                    {isExperimental ? "Experimental" : "Community"}
                  </span>
                </div>
                <p className={`text-xs leading-relaxed mb-2 ${isExperimental ? "text-orange-200/80" : "text-amber-200/70"}`}>
                  {notice.notice}
                </p>
                <p className={`text-[10px] ${isExperimental ? "text-orange-400/60" : "text-amber-400/50"}`}>
                  <span className="font-semibold">Mapping source:</span> {notice.source}
                </p>
              </div>
            </div>
          </div>
        );
      })()}

      {/* Summary cards */}
      {summary && (
        <div className="grid grid-cols-2 gap-4 lg:grid-cols-5">
          {/* Gauge */}
          <div className="rounded-xl border border-gray-800 bg-gray-900 p-4 flex flex-col items-center justify-center">
            <ComplianceGauge percentage={summary.compliance_percentage} size="md" />
            <p className="mt-2 text-xs text-gray-500">Overall Compliance</p>
          </div>

          {/* Covered */}
          <div className="rounded-xl border border-gray-800 bg-gray-900 p-4">
            <p className="text-xs text-gray-500 uppercase tracking-wider">Covered</p>
            <p className="mt-2 text-3xl font-bold text-green-400">{summary.covered}</p>
            <div className="mt-2 h-1.5 w-full rounded-full bg-gray-800">
              <div
                className="h-full rounded-full bg-green-500"
                style={{ width: `${summary.total_controls > 0 ? (summary.covered / summary.total_controls) * 100 : 0}%` }}
              />
            </div>
          </div>

          {/* Partial */}
          <div className="rounded-xl border border-gray-800 bg-gray-900 p-4">
            <p className="text-xs text-gray-500 uppercase tracking-wider">Partial</p>
            <p className="mt-2 text-3xl font-bold text-yellow-400">
              {summary.partially_covered}
            </p>
            <div className="mt-2 h-1.5 w-full rounded-full bg-gray-800">
              <div
                className="h-full rounded-full bg-yellow-500"
                style={{ width: `${summary.total_controls > 0 ? (summary.partially_covered / summary.total_controls) * 100 : 0}%` }}
              />
            </div>
          </div>

          {/* Not Covered */}
          <div className="rounded-xl border border-gray-800 bg-gray-900 p-4">
            <p className="text-xs text-gray-500 uppercase tracking-wider">Not Covered</p>
            <p className="mt-2 text-3xl font-bold text-red-400">{summary.not_covered}</p>
            <div className="mt-2 h-1.5 w-full rounded-full bg-gray-800">
              <div
                className="h-full rounded-full bg-red-500"
                style={{ width: `${summary.total_controls > 0 ? (summary.not_covered / summary.total_controls) * 100 : 0}%` }}
              />
            </div>
          </div>

          {/* Not Evaluated */}
          <div className="rounded-xl border border-gray-800 bg-gray-900 p-4">
            <p className="text-xs text-gray-500 uppercase tracking-wider">Not Evaluated</p>
            <p className="mt-2 text-3xl font-bold text-gray-400">{summary.not_evaluated}</p>
            <div className="mt-2 h-1.5 w-full rounded-full bg-gray-800">
              <div
                className="h-full rounded-full bg-gray-500"
                style={{ width: `${summary.total_controls > 0 ? (summary.not_evaluated / summary.total_controls) * 100 : 0}%` }}
              />
            </div>
          </div>
        </div>
      )}

      {/* Import buttons for admin */}
      {isAdmin && (
        <div className="flex flex-wrap items-center gap-2">
          <span className="text-xs text-gray-500">Import frameworks:</span>
          <button
            onClick={() => importNist.mutate()}
            disabled={isImporting}
            className="flex items-center gap-1.5 rounded-lg border border-gray-700 bg-gray-800 px-3 py-1.5 text-xs font-medium text-gray-300 hover:border-cyan-500/50 hover:text-white transition-colors disabled:opacity-50"
          >
            {importNist.isPending ? <Loader2 className="h-3 w-3 animate-spin" /> : <Plus className="h-3 w-3" />}
            NIST 800-53
          </button>
          <button
            onClick={() => importCis.mutate()}
            disabled={isImporting}
            className="flex items-center gap-1.5 rounded-lg border border-gray-700 bg-gray-800 px-3 py-1.5 text-xs font-medium text-gray-300 hover:border-cyan-500/50 hover:text-white transition-colors disabled:opacity-50"
          >
            {importCis.isPending ? <Loader2 className="h-3 w-3 animate-spin" /> : <Plus className="h-3 w-3" />}
            CIS Controls v8
          </button>
          <button
            onClick={() => importDora.mutate()}
            disabled={isImporting}
            className="flex items-center gap-1.5 rounded-lg border border-gray-700 bg-gray-800 px-3 py-1.5 text-xs font-medium text-gray-300 hover:border-cyan-500/50 hover:text-white transition-colors disabled:opacity-50"
          >
            {importDora.isPending ? <Loader2 className="h-3 w-3 animate-spin" /> : <Plus className="h-3 w-3" />}
            DORA
          </button>
          <button
            onClick={() => importIso27001.mutate()}
            disabled={isImporting}
            className="flex items-center gap-1.5 rounded-lg border border-gray-700 bg-gray-800 px-3 py-1.5 text-xs font-medium text-gray-300 hover:border-cyan-500/50 hover:text-white transition-colors disabled:opacity-50"
          >
            {importIso27001.isPending ? <Loader2 className="h-3 w-3 animate-spin" /> : <Plus className="h-3 w-3" />}
            ISO 27001:2022
          </button>
          <button
            onClick={() => importIso42001.mutate()}
            disabled={isImporting}
            className="flex items-center gap-1.5 rounded-lg border border-gray-700 bg-gray-800 px-3 py-1.5 text-xs font-medium text-gray-300 hover:border-cyan-500/50 hover:text-white transition-colors disabled:opacity-50"
          >
            {importIso42001.isPending ? <Loader2 className="h-3 w-3 animate-spin" /> : <Plus className="h-3 w-3" />}
            ISO 42001:2023
          </button>
          {(importNist.isSuccess || importCis.isSuccess || importDora.isSuccess ||
            importIso27001.isSuccess || importIso42001.isSuccess) && (
            <span className="text-xs text-green-400">Import complete</span>
          )}
          {(importNist.isError || importCis.isError || importDora.isError ||
            importIso27001.isError || importIso42001.isError) && (
            <span className="text-xs text-red-400">Import failed</span>
          )}
        </div>
      )}

      {/* Controls table */}
      {controls.length > 0 ? (
        <ControlsTable controls={controls} />
      ) : (
        !isLoading && (
          <div className="rounded-xl border border-gray-800 bg-gray-900 p-8 text-center">
            <AlertCircle className="mx-auto h-10 w-10 text-gray-600" />
            <p className="mt-3 text-gray-400">
              No compliance data available. Use the import buttons above to load a compliance framework.
            </p>
          </div>
        )
      )}
    </div>
  );
}
