import { useState, useMemo } from "react";
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
import { useNavigate } from "react-router-dom";
import {
  Loader2,
  AlertCircle,
  ClipboardCheck,
  CheckCircle,
  ExternalLink,
  RefreshCw,
  ChevronDown,
  ChevronUp,
  Rss,
  BookOpen,
  X,
  Globe,
} from "lucide-react";
import { getTechniques, markTechniqueReviewed } from "../api/techniques";
import { listIntelItems, type IntelItem } from "../api/intel";
import { createTemplate } from "../api/test-templates";
import type { TechniqueSummary } from "../api/techniques";
import { useAuth } from "../context/AuthContext";

/* ── helpers ─────────────────────────────────────────────────────── */

const STATUS_COLORS: Record<string, string> = {
  validated:     "bg-green-500/10 text-green-400 border-green-500/20",
  partial:       "bg-yellow-500/10 text-yellow-400 border-yellow-500/20",
  in_progress:   "bg-blue-500/10 text-blue-400 border-blue-500/20",
  not_covered:   "bg-red-500/10 text-red-400 border-red-500/20",
  not_evaluated: "bg-gray-500/10 text-gray-400 border-gray-600/20",
};

const STATUS_LABELS: Record<string, string> = {
  validated:     "Validated",
  partial:       "Partial",
  in_progress:   "In Progress",
  not_covered:   "Not Covered",
  not_evaluated: "Not Evaluated",
};

function formatDate(dateStr: string | null | undefined) {
  if (!dateStr) return "—";
  const utc = dateStr.endsWith("Z") || dateStr.includes("+") ? dateStr : dateStr + "Z";
  return new Date(utc).toLocaleDateString("es-ES", {
    year: "numeric", month: "short", day: "numeric",
  });
}

/* ── Create-template-from-intel modal ─────────────────────────────── */

function IntelTemplateModal({
  intel,
  techniqueMitreId,
  techniqueName,
  onClose,
  onSaved,
}: {
  intel: IntelItem;
  techniqueMitreId: string;
  techniqueName: string;
  onClose: () => void;
  onSaved: () => void;
}) {
  const [name, setName] = useState(intel.title ?? `Test for ${techniqueMitreId}`);
  const [description, setDescription] = useState(
    intel.title ? `Based on: ${intel.title}` : ""
  );
  const [platform, setPlatform] = useState("");
  const [attackProcedure, setAttackProcedure] = useState("");
  const [expectedDetection, setExpectedDetection] = useState("");
  const [severity, setSeverity] = useState("medium");

  const saveMutation = useMutation({
    mutationFn: () =>
      createTemplate({
        mitre_technique_id: techniqueMitreId,
        name: name.trim(),
        description: description.trim() || undefined,
        platform: platform.trim() || undefined,
        attack_procedure: attackProcedure.trim() || undefined,
        expected_detection: expectedDetection.trim() || undefined,
        source_url: intel.url,
        severity,
        source: "custom",
      }),
    onSuccess: () => onSaved(),
  });

  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/60 backdrop-blur-sm">
      <div className="max-h-[92vh] w-full max-w-2xl overflow-y-auto rounded-xl border border-gray-700 bg-gray-900 shadow-2xl">
        {/* Header */}
        <div className="sticky top-0 z-10 flex items-center justify-between border-b border-gray-800 bg-gray-900 px-6 py-4">
          <div className="flex items-center gap-2">
            <BookOpen className="h-5 w-5 text-cyan-400" />
            <h3 className="text-lg font-semibold text-white">Create Template from Intel</h3>
          </div>
          <button onClick={onClose} className="rounded p-1 text-gray-400 hover:bg-gray-800 hover:text-white">
            <X className="h-5 w-5" />
          </button>
        </div>

        <div className="space-y-4 px-6 py-5">
          {/* Source article banner */}
          <div className="flex items-start gap-3 rounded-lg border border-indigo-500/20 bg-indigo-900/10 px-4 py-3">
            <Rss className="mt-0.5 h-4 w-4 shrink-0 text-indigo-400" />
            <div className="flex-1 min-w-0">
              <p className="text-xs font-medium text-indigo-300">
                Source: {intel.source ?? "Unknown"} · {formatDate(intel.detected_at)}
              </p>
              <p className="mt-0.5 text-sm text-gray-300 line-clamp-2">{intel.title}</p>
            </div>
            <a
              href={intel.url}
              target="_blank"
              rel="noopener noreferrer"
              className="shrink-0 flex items-center gap-1 rounded border border-indigo-500/30 px-2 py-1 text-[10px] text-indigo-400 hover:bg-indigo-900/30 transition-colors"
            >
              <Globe className="h-3 w-3" />
              Open article
            </a>
          </div>

          {/* Technique banner */}
          <div className="rounded-lg border border-cyan-500/20 bg-cyan-900/10 px-4 py-2.5 text-xs text-cyan-400">
            Technique: <span className="font-mono font-semibold">{techniqueMitreId}</span>
            <span className="ml-2 text-gray-400">{techniqueName}</span>
          </div>

          {/* Name */}
          <div>
            <label className="mb-1.5 block text-sm font-medium text-gray-300">
              Template Name <span className="text-red-400">*</span>
            </label>
            <input
              value={name}
              onChange={(e) => setName(e.target.value)}
              className="w-full 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"
            />
          </div>

          {/* Platform + Severity */}
          <div className="grid gap-4 sm:grid-cols-2">
            <div>
              <label className="mb-1.5 block text-sm font-medium text-gray-300">Platform</label>
              <input
                value={platform}
                onChange={(e) => setPlatform(e.target.value)}
                placeholder="windows, linux, macos…"
                className="w-full 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"
              />
            </div>
            <div>
              <label className="mb-1.5 block text-sm font-medium text-gray-300">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"
              >
                <option value="low">Low</option>
                <option value="medium">Medium</option>
                <option value="high">High</option>
                <option value="critical">Critical</option>
              </select>
            </div>
          </div>

          {/* Description */}
          <div>
            <label className="mb-1.5 block text-sm font-medium text-gray-300">Description</label>
            <textarea
              value={description}
              onChange={(e) => setDescription(e.target.value)}
              rows={2}
              className="w-full 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"
              placeholder="Describe what this template tests…"
            />
          </div>

          {/* Attack Procedure */}
          <div>
            <label className="mb-1.5 block text-sm font-medium text-gray-300">
              Attack Procedure
              <span className="ml-2 text-xs text-gray-500">(read the article and fill this in)</span>
            </label>
            <textarea
              value={attackProcedure}
              onChange={(e) => setAttackProcedure(e.target.value)}
              rows={5}
              className="w-full rounded-lg border border-gray-700 bg-gray-800 px-3 py-2 font-mono text-sm text-gray-200 placeholder-gray-500 focus:border-cyan-500 focus:outline-none"
              placeholder="Steps to reproduce the attack described in the article…"
            />
          </div>

          {/* Expected Detection */}
          <div>
            <label className="mb-1.5 block text-sm font-medium text-gray-300">
              Expected Detection
              <span className="ml-2 text-xs text-gray-500">(Blue Team reference)</span>
            </label>
            <textarea
              value={expectedDetection}
              onChange={(e) => setExpectedDetection(e.target.value)}
              rows={3}
              className="w-full 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"
              placeholder="What alerts / logs should Blue Team look for?"
            />
          </div>

          {saveMutation.isError && (
            <div className="rounded-lg border border-red-500/30 bg-red-900/20 p-3 text-sm text-red-400">
              {(saveMutation.error as Error)?.message || "Failed to create template"}
            </div>
          )}
        </div>

        {/* Footer */}
        <div className="sticky bottom-0 flex justify-end gap-3 border-t border-gray-800 bg-gray-900 px-6 py-4">
          <button onClick={onClose} className="rounded-lg border border-gray-700 px-4 py-2 text-sm text-gray-400 hover:bg-gray-800">
            Cancel
          </button>
          <button
            onClick={() => saveMutation.mutate()}
            disabled={!name.trim() || saveMutation.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 disabled:opacity-50 transition-colors"
          >
            {saveMutation.isPending ? <Loader2 className="h-4 w-4 animate-spin" /> : <BookOpen className="h-4 w-4" />}
            Save Template
          </button>
        </div>
      </div>
    </div>
  );
}

/* ── Intel items panel (expanded row) ────────────────────────────── */

function IntelPanel({
  tech,
  canReview,
}: {
  tech: TechniqueSummary;
  canReview: boolean;
}) {
  const [createFromIntel, setCreateFromIntel] = useState<IntelItem | null>(null);
  const queryClient = useQueryClient();

  const { data: items = [], isLoading } = useQuery({
    queryKey: ["intel-items", tech.id],
    queryFn: () => listIntelItems(tech.id),
    staleTime: 60_000,
  });

  const handleTemplateSaved = () => {
    setCreateFromIntel(null);
    queryClient.invalidateQueries({ queryKey: ["intel-items", tech.id] });
  };

  if (isLoading) {
    return (
      <div className="flex items-center gap-2 px-5 py-3 text-xs text-gray-500">
        <Loader2 className="h-3.5 w-3.5 animate-spin" />
        Loading intel items…
      </div>
    );
  }

  if (items.length === 0) {
    return (
      <div className="px-5 py-3 text-xs text-gray-500">
        No intel items found for this technique.
      </div>
    );
  }

  return (
    <>
      <div className="divide-y divide-gray-800/50 border-t border-gray-800">
        {items.map((item) => (
          <div key={item.id} className="flex items-start gap-3 px-5 py-3 bg-gray-950/30 hover:bg-gray-800/20 transition-colors">
            <Rss className="mt-0.5 h-3.5 w-3.5 shrink-0 text-indigo-400" />
            <div className="flex-1 min-w-0">
              <p className="text-sm font-medium text-gray-200 line-clamp-1">
                {item.title ?? item.url}
              </p>
              <p className="mt-0.5 text-xs text-gray-500">
                {item.source && <span className="text-indigo-400/70">{item.source} · </span>}
                {formatDate(item.detected_at)}
              </p>
            </div>
            <div className="flex shrink-0 items-center gap-1.5">
              <a
                href={item.url}
                target="_blank"
                rel="noopener noreferrer"
                className="flex items-center gap-1 rounded border border-gray-700 px-2 py-1 text-[10px] text-gray-400 hover:border-gray-600 hover:text-white transition-colors"
              >
                <Globe className="h-3 w-3" />
                Article
              </a>
              {canReview && (
                <button
                  onClick={() => setCreateFromIntel(item)}
                  className="flex items-center gap-1 rounded border border-cyan-500/30 bg-cyan-500/10 px-2 py-1 text-[10px] text-cyan-400 hover:bg-cyan-500/20 transition-colors"
                >
                  <BookOpen className="h-3 w-3" />
                  Create Template
                </button>
              )}
            </div>
          </div>
        ))}
      </div>

      {createFromIntel && (
        <IntelTemplateModal
          intel={createFromIntel}
          techniqueMitreId={tech.mitre_id}
          techniqueName={tech.name}
          onClose={() => setCreateFromIntel(null)}
          onSaved={handleTemplateSaved}
        />
      )}
    </>
  );
}

/* ── Main page ────────────────────────────────────────────────────── */

export default function ReviewQueuePage() {
  const navigate = useNavigate();
  const queryClient = useQueryClient();
  const { user } = useAuth();

  const canReview =
    user?.role === "admin" ||
    user?.role === "red_lead" ||
    user?.role === "blue_lead";

  const [expandedId, setExpandedId] = useState<string | null>(null);

  const { data: techniques, isLoading, error, refetch } = useQuery({
    queryKey: ["techniques", "review-queue"],
    queryFn: () => getTechniques({ review_required: true }),
  });

  const reviewMutation = useMutation({
    mutationFn: (mitreId: string) => markTechniqueReviewed(mitreId),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ["techniques", "review-queue"] });
      queryClient.invalidateQueries({ queryKey: ["techniques"] });
    },
  });

  const byTactic = useMemo(() => {
    if (!techniques) return [];
    const map = new Map<string, TechniqueSummary[]>();
    for (const t of techniques) {
      const tactic = t.tactic || "Unknown";
      if (!map.has(tactic)) map.set(tactic, []);
      map.get(tactic)!.push(t);
    }
    return Array.from(map.entries()).sort(([a], [b]) => a.localeCompare(b));
  }, [techniques]);

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

  if (error) {
    return (
      <div className="flex h-64 flex-col items-center justify-center gap-2">
        <AlertCircle className="h-10 w-10 text-red-400" />
        <p className="text-red-400">Failed to load review queue</p>
      </div>
    );
  }

  const total = techniques?.length ?? 0;

  return (
    <div className="space-y-6">
      {/* Header */}
      <div className="flex items-center justify-between">
        <div className="flex items-center gap-3">
          <ClipboardCheck className="h-7 w-7 text-amber-400" />
          <div>
            <h1 className="text-2xl font-bold text-white">Technique Review Queue</h1>
            <p className="mt-0.5 text-sm text-gray-400">
              Techniques flagged for review — click a row to see intel articles
            </p>
          </div>
        </div>
        <div className="flex items-center gap-3">
          {total > 0 && (
            <span className="rounded-full border border-amber-500/30 bg-amber-500/10 px-3 py-1 text-sm font-medium text-amber-400">
              {total} pending
            </span>
          )}
          <button
            onClick={() => refetch()}
            className="flex items-center gap-1.5 rounded-lg border border-gray-700 bg-gray-800 px-3 py-2 text-sm text-gray-400 hover:bg-gray-700 hover:text-white transition-colors"
          >
            <RefreshCw className="h-3.5 w-3.5" />
            Refresh
          </button>
        </div>
      </div>

      {/* Explanation */}
      {total > 0 && (
        <div className="rounded-xl border border-amber-500/20 bg-amber-500/5 p-4 space-y-2">
          <p className="text-sm text-amber-300">
            <span className="font-semibold">What does this mean?</span>{" "}
            Techniques appear here when:
          </p>
          <ul className="ml-4 list-disc space-y-1 text-xs text-amber-400/80">
            <li>The MITRE ATT&CK sync detected an update to the technique</li>
            <li>The Threat Intel Scan found a new article about this technique in a security feed</li>
            <li>A new detection rule or test template was added for this technique</li>
          </ul>
          <p className="text-xs text-amber-400/70">
            Expand a row to see the intel articles. If relevant, create a test template from the article.
            Once reviewed, click <span className="font-semibold">Mark Reviewed</span>.
          </p>
        </div>
      )}

      {/* Empty state */}
      {total === 0 && (
        <div className="rounded-xl border border-gray-800 bg-gray-900 p-16 text-center">
          <CheckCircle className="mx-auto mb-3 h-12 w-12 text-green-500/50" />
          <p className="text-lg font-medium text-white">All caught up!</p>
          <p className="mt-1 text-sm text-gray-500">
            No techniques are currently flagged for review.
          </p>
        </div>
      )}

      {/* Table grouped by tactic */}
      {byTactic.map(([tactic, items]) => (
        <div key={tactic} className="rounded-xl border border-gray-800 bg-gray-900">
          <div className="flex items-center justify-between border-b border-gray-800 px-5 py-3">
            <h2 className="text-sm font-semibold capitalize text-gray-300">{tactic}</h2>
            <span className="text-xs text-gray-500">{items.length}</span>
          </div>

          <div className="divide-y divide-gray-800/50">
            {items.map((tech) => {
              const isExpanded = expandedId === tech.mitre_id;
              return (
                <div key={tech.mitre_id}>
                  {/* Main row */}
                  <div
                    className="flex items-center gap-3 px-5 py-3 cursor-pointer hover:bg-gray-800/30 transition-colors"
                    onClick={() => setExpandedId(isExpanded ? null : tech.mitre_id)}
                  >
                    {/* Expand chevron */}
                    <span className="shrink-0 text-gray-600">
                      {isExpanded
                        ? <ChevronUp className="h-4 w-4" />
                        : <ChevronDown className="h-4 w-4" />
                      }
                    </span>

                    {/* MITRE ID */}
                    <span className="w-20 shrink-0 font-mono text-xs font-semibold text-cyan-400">
                      {tech.mitre_id}
                    </span>

                    {/* Name */}
                    <span className="flex-1 text-sm text-gray-200 line-clamp-1 min-w-0">
                      {tech.name}
                    </span>

                    {/* Coverage */}
                    <span
                      className={`shrink-0 inline-flex rounded-full border px-2 py-0.5 text-xs font-medium ${
                        STATUS_COLORS[tech.status_global] ?? STATUS_COLORS.not_evaluated
                      }`}
                    >
                      {STATUS_LABELS[tech.status_global] ?? tech.status_global}
                    </span>

                    {/* Actions — stop propagation so row click doesn't interfere */}
                    <div
                      className="flex shrink-0 items-center gap-1.5"
                      onClick={(e) => e.stopPropagation()}
                    >
                      <button
                        onClick={() => navigate(`/techniques/${tech.mitre_id}`)}
                        className="flex items-center gap-1 rounded-lg border border-gray-700 px-2.5 py-1.5 text-xs text-gray-400 hover:border-gray-600 hover:text-white transition-colors"
                        title="Open technique"
                      >
                        <ExternalLink className="h-3 w-3" />
                        View
                      </button>
                      {canReview && (
                        <button
                          onClick={() => reviewMutation.mutate(tech.mitre_id)}
                          disabled={reviewMutation.isPending && reviewMutation.variables === tech.mitre_id}
                          className="flex items-center gap-1 rounded-lg bg-amber-600 px-2.5 py-1.5 text-xs font-medium text-white hover:bg-amber-500 disabled:opacity-50 transition-colors"
                        >
                          {reviewMutation.isPending && reviewMutation.variables === tech.mitre_id ? (
                            <Loader2 className="h-3 w-3 animate-spin" />
                          ) : (
                            <CheckCircle className="h-3 w-3" />
                          )}
                          Mark Reviewed
                        </button>
                      )}
                    </div>
                  </div>

                  {/* Expanded intel panel */}
                  {isExpanded && (
                    <IntelPanel tech={tech} canReview={canReview} />
                  )}
                </div>
              );
            })}
          </div>
        </div>
      ))}
    </div>
  );
}
