import { useState } from "react";
import { useQuery } from "@tanstack/react-query";
import MarkdownText from "../MarkdownText";
import {
  Shield,
  ShieldCheck,
  FileText,
  Clock,
  Upload,
  Loader2,
  CheckCircle,
  XCircle,
  AlertTriangle,
  Trash2,
  ExternalLink,
} from "lucide-react";
import type {
  Test,
  TestResult,
  ContainmentResult,
  AttackSuccessResult,
  TeamSide,
  Evidence,
  TestTimelineEntry,
  User,
  DefensiveTechnique,
} from "../../types/models";
import { RED_EDITABLE_STATES, BLUE_EDITABLE_STATES } from "../../types/models";
import { getDefensesForTechnique } from "../../api/d3fend";
import DetectionRuleChecklist from "./DetectionRuleChecklist";
import EvidenceUpload from "../EvidenceUpload";
import EvidenceList from "../EvidenceList";

// ── Tab definitions ────────────────────────────────────────────────

type TabKey = "red" | "blue" | "summary" | "timeline";

const TABS: { key: TabKey; label: string; icon: React.ReactNode }[] = [
  { key: "red", label: "Red Team", icon: <Shield className="h-4 w-4" /> },
  { key: "blue", label: "Blue Team", icon: <ShieldCheck className="h-4 w-4" /> },
  { key: "summary", label: "Summary", icon: <FileText className="h-4 w-4" /> },
  { key: "timeline", label: "Timeline", icon: <Clock className="h-4 w-4" /> },
];

const TAB_COLORS: Record<TabKey, string> = {
  red: "border-orange-500 text-orange-400",
  blue: "border-indigo-500 text-indigo-400",
  summary: "border-cyan-500 text-cyan-400",
  timeline: "border-gray-500 text-gray-400",
};

// ── Detection result options ───────────────────────────────────────

const DETECTION_RESULTS: { value: TestResult; label: string; color: string }[] = [
  { value: "detected", label: "Detected", color: "border-green-500 bg-green-500/10 text-green-400" },
  { value: "not_detected", label: "Not Detected", color: "border-red-500 bg-red-500/10 text-red-400" },
  {
    value: "partially_detected",
    label: "Partially Detected",
    color: "border-yellow-500 bg-yellow-500/10 text-yellow-400",
  },
];

// ── Containment result options ─────────────────────────────────────
// Order matches Detection's full/none/partial pattern for consistency.

const CONTAINMENT_RESULTS: { value: ContainmentResult; label: string; color: string }[] = [
  { value: "contained", label: "Contained", color: "border-green-500 bg-green-500/10 text-green-400" },
  { value: "not_contained", label: "Not Contained", color: "border-red-500 bg-red-500/10 text-red-400" },
  {
    value: "partially_contained",
    label: "Partially Contained",
    color: "border-yellow-500 bg-yellow-500/10 text-yellow-400",
  },
];

// ── Attack success options ──────────────────────────────────────────
// Order matches Detection's full/none/partial pattern for consistency.

const ATTACK_SUCCESS_RESULTS: { value: AttackSuccessResult; label: string; color: string }[] = [
  { value: "successful", label: "Yes", color: "border-green-500 bg-green-500/10 text-green-400" },
  { value: "not_successful", label: "No", color: "border-red-500 bg-red-500/10 text-red-400" },
  {
    value: "partially_successful",
    label: "Partial",
    color: "border-yellow-500 bg-yellow-500/10 text-yellow-400",
  },
];

// ── Props ──────────────────────────────────────────────────────────

interface TeamTabsProps {
  test: Test;
  user: User | null;
  timeline: TestTimelineEntry[];
  isTimelineLoading: boolean;

  // Red Team field handlers
  onRedFieldChange: (field: string, value: string | boolean) => void;
  redDraft: {
    procedure_text: string;
    tool_used: string;
    attack_success: AttackSuccessResult | "";
    red_summary: string;
    execution_start_time: string;
    execution_end_time: string;
  };

  // Blue Team field handlers
  onBlueFieldChange: (field: string, value: string) => void;
  blueDraft: {
    detection_result: TestResult | "";
    containment_result: ContainmentResult | "";
    detection_time: string;
    containment_time: string;
    blue_summary: string;
  };

  // Evidence
  onUploadEvidence: (file: File, team: TeamSide) => Promise<void>;
  isUploading: boolean;
  onDownloadEvidence: (evidenceId: string) => void;
  onDeleteEvidence?: (evidenceId: string) => void;
  isDeletingEvidence?: boolean;
}

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

export default function TeamTabs({
  test,
  user,
  timeline,
  isTimelineLoading,
  onRedFieldChange,
  redDraft,
  onBlueFieldChange,
  blueDraft,
  onUploadEvidence,
  isUploading,
  onDownloadEvidence,
  onDeleteEvidence,
  isDeletingEvidence,
}: TeamTabsProps) {
  const [activeTab, setActiveTab] = useState<TabKey>("red");
  const role = user?.role ?? "";

  // Fetch D3FEND defenses for the test's technique
  const { data: d3fendData } = useQuery({
    queryKey: ["d3fend-defenses", test.technique_mitre_id],
    queryFn: () => getDefensesForTechnique(test.technique_mitre_id!),
    enabled: !!test.technique_mitre_id,
  });

  // Leads and admins can edit during both draft and executing phases.
  // Operators (red_tech) may only edit once execution has started —
  // the timer must be running before they can document the attack.
  const canEditRed =
    (test.state === "red_executing" &&
      (role === "red_tech" || role === "red_lead" || role === "admin")) ||
    (test.state === "draft" && (role === "red_lead" || role === "admin"));

  // Blue operators may only edit after they explicitly pick up the test
  // (Start Evaluation pressed → blue_work_started_at is set).
  // Blue leads and admins can edit at any point during blue_evaluating.
  const canEditBlue =
    BLUE_EDITABLE_STATES.includes(test.state) &&
    ((role === "blue_lead" || role === "admin") ||
      (role === "blue_tech" && !!test.blue_work_started_at));

  // Blind visibility: neither side sees the other's data until both reviews
  // pass (matches the backend's field-masking on GET /tests/{id}).
  const BLIND_STATES = ["draft", "red_executing", "red_review", "blue_evaluating", "blue_review"];
  const isBlind = BLIND_STATES.includes(test.state) && role !== "admin" && role !== "viewer";
  const hideBlueFromMe = isBlind && (role === "red_tech" || role === "red_lead");
  const hideRedFromMe = isBlind && (role === "blue_tech" || role === "blue_lead");

  // Containment fields only visible when attack was detected (draft or saved value)
  const isDetected = canEditBlue
    ? blueDraft.detection_result === "detected" || blueDraft.detection_result === "partially_detected"
    : test.detection_result === "detected" || test.detection_result === "partially_detected";

  // Hint messages shown to operators when editing is locked
  const redLockedHint =
    test.state === "draft" && role === "red_tech"
      ? "Press Start Execution to begin editing — the timer must be running first."
      : null;

  const blueLockedHint =
    BLUE_EDITABLE_STATES.includes(test.state) &&
    role === "blue_tech" &&
    !test.blue_work_started_at
      ? "Press Start Evaluation to begin editing — pick up the test first."
      : null;

  // ── Red Team Tab ─────────────────────────────────────────────────

  const renderRedTab = () => {
    if (hideRedFromMe) {
      return (
        <div className="py-12 text-center">
          <Shield className="mx-auto h-10 w-10 text-gray-600" />
          <p className="mt-2 text-sm text-gray-400">
            Red Team work is hidden until both teams' reviews are complete — this keeps
            detection testing blind.
          </p>
        </div>
      );
    }
    return (
    <div className="space-y-6">
      {/* Locked hint for red_tech in draft state */}
      {redLockedHint && (
        <div className="flex items-center gap-2 rounded-lg border border-orange-500/30 bg-orange-500/5 px-4 py-3 text-sm text-orange-400">
          <span className="text-base">⏱</span>
          {redLockedHint}
        </div>
      )}
      {/* Procedure */}
      <div>
        <label className="mb-1.5 block text-sm font-medium text-gray-300">
          Attack Procedure
        </label>
        {canEditRed ? (
          <textarea
            value={redDraft.procedure_text}
            onChange={(e) => onRedFieldChange("procedure_text", e.target.value)}
            rows={6}
            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 focus:ring-1 focus:ring-cyan-500 font-mono"
            placeholder="Describe the attack procedure..."
          />
        ) : (
          <pre className="whitespace-pre-wrap rounded-lg bg-gray-800 p-4 font-mono text-sm text-gray-300">
            {test.procedure_text || "No procedure documented."}
          </pre>
        )}
      </div>

      {/* Tool Used */}
      <div>
        <label className="mb-1.5 block text-sm font-medium text-gray-300">
          Tool Used
        </label>
        {canEditRed ? (
          <input
            value={redDraft.tool_used}
            onChange={(e) => onRedFieldChange("tool_used", 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 focus:ring-1 focus:ring-cyan-500"
            placeholder="e.g. Atomic Red Team, Cobalt Strike, ..."
          />
        ) : (
          <p className="text-sm text-gray-400">{test.tool_used || "Not specified"}</p>
        )}
      </div>

      {/* Attack Success */}
      <div>
        <label className="mb-2 block text-sm font-medium text-gray-300">
          Attack Successful?
        </label>
        {canEditRed ? (
          <div className="flex flex-wrap gap-2">
            {ATTACK_SUCCESS_RESULTS.map((opt) => (
              <button
                key={opt.value}
                onClick={() => onRedFieldChange("attack_success", opt.value)}
                className={`rounded-lg border px-3 py-2 text-sm font-medium transition-colors ${
                  redDraft.attack_success === opt.value
                    ? opt.color
                    : "border-gray-700 bg-gray-800 text-gray-400 hover:border-gray-600"
                }`}
              >
                {opt.label}
              </button>
            ))}
          </div>
        ) : (
          <p className="text-sm">
            {test.attack_success ? (
              <span
                className={`inline-flex rounded-full border px-2.5 py-0.5 text-xs font-medium ${
                  test.attack_success === "successful"
                    ? "border-green-500/30 bg-green-900/50 text-green-400"
                    : test.attack_success === "not_successful"
                      ? "border-red-500/30 bg-red-900/50 text-red-400"
                      : "border-yellow-500/30 bg-yellow-900/50 text-yellow-400"
                }`}
              >
                {ATTACK_SUCCESS_RESULTS.find((o) => o.value === test.attack_success)?.label}
              </span>
            ) : (
              <span className="text-gray-500">Not set</span>
            )}
          </p>
        )}
      </div>

      {/* Execution times */}
      <div className="grid grid-cols-2 gap-4">
        <div>
          <label className="mb-1.5 block text-sm font-medium text-gray-300">
            Execution Start (UTC) <span className="text-red-400">*</span>
          </label>
          {canEditRed ? (
            <input
              type="datetime-local"
              required
              value={redDraft.execution_start_time}
              onChange={(e) => onRedFieldChange("execution_start_time", 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 focus:ring-1 focus:ring-cyan-500"
            />
          ) : (
            <p className="text-sm text-gray-400">
              {test.execution_start_time ? new Date(test.execution_start_time + "Z").toUTCString().replace(" GMT", " UTC") : "—"}
            </p>
          )}
        </div>
        <div>
          <label className="mb-1.5 block text-sm font-medium text-gray-300">
            Execution End (UTC) <span className="text-red-400">*</span>
          </label>
          {canEditRed ? (
            <input
              type="datetime-local"
              required
              value={redDraft.execution_end_time}
              onChange={(e) => onRedFieldChange("execution_end_time", 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 focus:ring-1 focus:ring-cyan-500"
            />
          ) : (
            <p className="text-sm text-gray-400">
              {test.execution_end_time ? new Date(test.execution_end_time + "Z").toUTCString().replace(" GMT", " UTC") : "—"}
            </p>
          )}
        </div>
      </div>

      {/* Red Summary */}
      <div>
        <label className="mb-1.5 block text-sm font-medium text-gray-300">
          Red Team Summary
        </label>
        {canEditRed ? (
          <textarea
            value={redDraft.red_summary}
            onChange={(e) => onRedFieldChange("red_summary", e.target.value)}
            rows={4}
            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 focus:ring-1 focus:ring-cyan-500"
            placeholder="Summarize the Red Team findings..."
          />
        ) : (
          <MarkdownText content={test.red_summary || "No summary yet."} className="text-sm text-gray-400" />
        )}
      </div>

      {/* Red Evidences */}
      <div>
        <h3 className="mb-3 text-sm font-medium text-gray-300">Red Team Evidence</h3>
        {canEditRed && (
          <div className="mb-4">
            <EvidenceUpload
              onUpload={async (file) => await onUploadEvidence(file, "red")}
              isUploading={isUploading}
            />
          </div>
        )}
        <EvidenceList
          evidences={test.red_evidences || []}
          onDownload={onDownloadEvidence}
        />
      </div>

      {/* Red validation status if applicable */}
      {test.red_validation_status && (
        <div
          className={`rounded-lg border p-3 ${
            test.red_validation_status === "approved"
              ? "border-green-500/30 bg-green-900/20"
              : "border-red-500/30 bg-red-900/20"
          }`}
        >
          <div className="flex items-center gap-2">
            {test.red_validation_status === "approved" ? (
              <CheckCircle className="h-4 w-4 text-green-400" />
            ) : (
              <XCircle className="h-4 w-4 text-red-400" />
            )}
            <span
              className={`text-sm font-medium ${
                test.red_validation_status === "approved" ? "text-green-400" : "text-red-400"
              }`}
            >
              Red Lead: {test.red_validation_status === "approved" ? "Approved" : "Rejected"}
            </span>
          </div>
          {test.red_validation_notes && (
            <MarkdownText content={test.red_validation_notes} className="mt-2 text-sm text-gray-400" />
          )}
        </div>
      )}
    </div>
    );
  };

  // ── Blue Team Tab ────────────────────────────────────────────────

  const renderBlueTab = () => {
    if (hideBlueFromMe) {
      return (
        <div className="py-12 text-center">
          <ShieldCheck className="mx-auto h-10 w-10 text-gray-600" />
          <p className="mt-2 text-sm text-gray-400">
            Blue Team work is hidden until both teams' reviews are complete — this keeps
            detection testing blind.
          </p>
        </div>
      );
    }
    return (
    <div className="space-y-6">
      {/* Locked hint for blue_tech before Start Evaluation */}
      {blueLockedHint && (
        <div className="flex items-center gap-2 rounded-lg border border-indigo-500/30 bg-indigo-500/5 px-4 py-3 text-sm text-indigo-400">
          <span className="text-base">⏱</span>
          {blueLockedHint}
        </div>
      )}
      {/* Detection Result */}
      <div>
        <label className="mb-2 block text-sm font-medium text-gray-300">
          Detection Result
        </label>
        {canEditBlue ? (
          <div className="flex flex-wrap gap-2">
            {DETECTION_RESULTS.map((opt) => (
              <button
                key={opt.value}
                onClick={() => onBlueFieldChange("detection_result", opt.value)}
                className={`rounded-lg border px-3 py-2 text-sm font-medium transition-colors ${
                  blueDraft.detection_result === opt.value
                    ? opt.color
                    : "border-gray-700 bg-gray-800 text-gray-400 hover:border-gray-600"
                }`}
              >
                {opt.label}
              </button>
            ))}
          </div>
        ) : (
          <p className="text-sm">
            {test.detection_result ? (
              <span
                className={`inline-flex rounded-full border px-2.5 py-0.5 text-xs font-medium ${
                  test.detection_result === "detected"
                    ? "border-green-500/30 bg-green-900/50 text-green-400"
                    : test.detection_result === "not_detected"
                      ? "border-red-500/30 bg-red-900/50 text-red-400"
                      : "border-yellow-500/30 bg-yellow-900/50 text-yellow-400"
                }`}
              >
                {test.detection_result.replace(/_/g, " ")}
              </span>
            ) : (
              <span className="text-gray-500">Not evaluated yet</span>
            )}
          </p>
        )}
      </div>

      {/* Containment Result — only when detected/partially_detected */}
      {isDetected && (
        <div>
          <label className="mb-2 block text-sm font-medium text-gray-300">
            Containment Result
          </label>
          {canEditBlue ? (
            <div className="flex flex-wrap gap-2">
              {CONTAINMENT_RESULTS.map((opt) => (
                <button
                  key={opt.value}
                  onClick={() => onBlueFieldChange("containment_result", opt.value)}
                  className={`rounded-lg border px-3 py-2 text-sm font-medium transition-colors ${
                    blueDraft.containment_result === opt.value
                      ? opt.color
                      : "border-gray-700 bg-gray-800 text-gray-400 hover:border-gray-600"
                  }`}
                >
                  {opt.label}
                </button>
              ))}
            </div>
          ) : (
            <p className="text-sm">
              {test.containment_result ? (
                <span
                  className={`inline-flex rounded-full border px-2.5 py-0.5 text-xs font-medium ${
                    test.containment_result === "contained"
                      ? "border-green-500/30 bg-green-900/50 text-green-400"
                      : test.containment_result === "not_contained"
                        ? "border-red-500/30 bg-red-900/50 text-red-400"
                        : "border-yellow-500/30 bg-yellow-900/50 text-yellow-400"
                  }`}
                >
                  {test.containment_result.replace(/_/g, " ")}
                </span>
              ) : (
                <span className="text-gray-500">Not evaluated yet</span>
              )}
            </p>
          )}
        </div>
      )}

      {/* Detection & Containment times — only when detected/partially_detected */}
      {isDetected && (
        <div className="grid grid-cols-2 gap-4">
          <div>
            <label className="mb-1.5 block text-sm font-medium text-gray-300">
              Detection Time (UTC) <span className="text-red-400">*</span>
            </label>
            {canEditBlue ? (
              <input
                type="datetime-local"
                required
                value={blueDraft.detection_time}
                onChange={(e) => onBlueFieldChange("detection_time", 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-indigo-500 focus:outline-none focus:ring-1 focus:ring-indigo-500"
              />
            ) : (
              <p className="text-sm text-gray-400">
                {test.detection_time ? new Date(test.detection_time + "Z").toUTCString().replace(" GMT", " UTC") : "—"}
              </p>
            )}
          </div>
          <div>
            <label className="mb-1.5 block text-sm font-medium text-gray-300">
              Containment Time (UTC) <span className="text-red-400">*</span>
            </label>
            {canEditBlue ? (
              <input
                type="datetime-local"
                required
                value={blueDraft.containment_time}
                onChange={(e) => onBlueFieldChange("containment_time", 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-indigo-500 focus:outline-none focus:ring-1 focus:ring-indigo-500"
              />
            ) : (
              <p className="text-sm text-gray-400">
                {test.containment_time ? new Date(test.containment_time + "Z").toUTCString().replace(" GMT", " UTC") : "—"}
              </p>
            )}
          </div>
        </div>
      )}

      {/* Blue Summary */}
      <div>
        <label className="mb-1.5 block text-sm font-medium text-gray-300">
          Blue Team Summary
        </label>
        {canEditBlue ? (
          <textarea
            value={blueDraft.blue_summary}
            onChange={(e) => onBlueFieldChange("blue_summary", e.target.value)}
            rows={4}
            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-indigo-500 focus:outline-none focus:ring-1 focus:ring-indigo-500"
            placeholder="Summarize the Blue Team analysis..."
          />
        ) : (
          <MarkdownText content={test.blue_summary || "No summary yet."} className="text-sm text-gray-400" />
        )}
      </div>

      {/* Blue Evidences */}
      <div>
        <h3 className="mb-3 text-sm font-medium text-gray-300">Blue Team Evidence</h3>
        {canEditBlue && (
          <div className="mb-4">
            <EvidenceUpload
              onUpload={async (file) => await onUploadEvidence(file, "blue")}
              isUploading={isUploading}
            />
          </div>
        )}
        <EvidenceList
          evidences={test.blue_evidences || []}
          onDownload={onDownloadEvidence}
        />
      </div>

      {/* Detection Rule Checklist */}
      <div>
        <h3 className="mb-3 flex items-center gap-2 text-sm font-medium text-gray-300">
          <ShieldCheck className="h-4 w-4 text-indigo-400" />
          Detection Rule Evaluation
        </h3>
        <DetectionRuleChecklist
          testId={test.id}
          user={user}
          canEdit={canEditBlue}
        />
      </div>

      {/* Recommended Detection Approaches (D3FEND) */}
      {d3fendData && d3fendData.defenses.length > 0 && (
        <div className="rounded-lg border border-emerald-500/20 bg-emerald-900/10 p-4">
          <h3 className="mb-3 flex items-center gap-2 text-sm font-semibold text-emerald-400">
            <Shield className="h-4 w-4" />
            Recommended Detection Approaches
            <span className="ml-auto rounded-full bg-emerald-900/50 border border-emerald-500/30 px-2 py-0.5 text-[10px] font-medium text-emerald-400">
              {d3fendData.defenses.length} countermeasure{d3fendData.defenses.length !== 1 ? "s" : ""}
            </span>
          </h3>
          <div className="space-y-2 max-h-64 overflow-y-auto pr-1">
            {d3fendData.defenses.map((def) => (
              <div
                key={def.id}
                className="flex items-start justify-between rounded-lg border border-gray-700 bg-gray-800/50 p-3"
              >
                <div className="min-w-0 flex-1">
                  <div className="flex items-center gap-2">
                    <span className="shrink-0 rounded bg-emerald-900/50 border border-emerald-500/30 px-1.5 py-0.5 font-mono text-[10px] text-emerald-400">
                      {def.d3fend_id}
                    </span>
                    <span className="text-sm font-medium text-gray-200">{def.name}</span>
                    {def.tactic && (
                      <span className="shrink-0 rounded-full bg-gray-800 border border-gray-700 px-1.5 py-0.5 text-[10px] text-gray-400">
                        {def.tactic}
                      </span>
                    )}
                  </div>
                  {def.description && (
                    <p className="mt-1 text-xs text-gray-400 line-clamp-2">{def.description}</p>
                  )}
                </div>
                {def.d3fend_url && (
                  <a
                    href={def.d3fend_url}
                    target="_blank"
                    rel="noopener noreferrer"
                    className="ml-2 shrink-0 text-gray-500 hover:text-cyan-400"
                    title="View in D3FEND"
                  >
                    <ExternalLink className="h-3.5 w-3.5" />
                  </a>
                )}
              </div>
            ))}
          </div>
        </div>
      )}

      {/* Blue validation status if applicable */}
      {test.blue_validation_status && (
        <div
          className={`rounded-lg border p-3 ${
            test.blue_validation_status === "approved"
              ? "border-green-500/30 bg-green-900/20"
              : "border-red-500/30 bg-red-900/20"
          }`}
        >
          <div className="flex items-center gap-2">
            {test.blue_validation_status === "approved" ? (
              <CheckCircle className="h-4 w-4 text-green-400" />
            ) : (
              <XCircle className="h-4 w-4 text-red-400" />
            )}
            <span
              className={`text-sm font-medium ${
                test.blue_validation_status === "approved" ? "text-green-400" : "text-red-400"
              }`}
            >
              Blue Lead: {test.blue_validation_status === "approved" ? "Approved" : "Rejected"}
            </span>
          </div>
          {test.blue_validation_notes && (
            <MarkdownText content={test.blue_validation_notes} className="mt-2 text-sm text-gray-400" />
          )}
        </div>
      )}
    </div>
    );
  };

  // ── Summary Tab ──────────────────────────────────────────────────

  const renderSummaryTab = () => (
    <div className="space-y-6">
      {/* Side-by-side comparison */}
      <div className="grid gap-6 md:grid-cols-2">
        {/* Red Side */}
        <div className="rounded-lg border border-orange-500/20 bg-orange-900/10 p-4">
          <h3 className="mb-3 flex items-center gap-2 text-sm font-semibold text-orange-400">
            <Shield className="h-4 w-4" /> Red Team (Attack)
          </h3>
          <dl className="space-y-3">
            <div>
              <dt className="text-xs font-medium uppercase text-gray-500">Attack Success</dt>
              <dd className="mt-0.5 text-sm">
                {test.attack_success ? (
                  <span
                    className={
                      test.attack_success === "successful"
                        ? "text-green-400"
                        : test.attack_success === "not_successful"
                          ? "text-red-400"
                          : "text-yellow-400"
                    }
                  >
                    {ATTACK_SUCCESS_RESULTS.find((o) => o.value === test.attack_success)?.label}
                  </span>
                ) : (
                  <span className="text-gray-500">Not set</span>
                )}
              </dd>
            </div>
            <div>
              <dt className="text-xs font-medium uppercase text-gray-500">Tool Used</dt>
              <dd className="mt-0.5 text-sm text-gray-300">{test.tool_used || "N/A"}</dd>
            </div>
            <div>
              <dt className="text-xs font-medium uppercase text-gray-500">Summary</dt>
              <dd className="mt-0.5"><MarkdownText content={test.red_summary || "N/A"} className="text-sm text-gray-300" /></dd>
            </div>
            <div>
              <dt className="text-xs font-medium uppercase text-gray-500">Evidence Files</dt>
              <dd className="mt-0.5 text-sm text-gray-400">
                {(test.red_evidences || []).length} file(s)
              </dd>
            </div>
            {test.red_validation_status && (
              <div>
                <dt className="text-xs font-medium uppercase text-gray-500">Red Lead Validation</dt>
                <dd className="mt-0.5 flex items-center gap-1 text-sm">
                  {test.red_validation_status === "approved" ? (
                    <><CheckCircle className="h-3.5 w-3.5 text-green-400" /><span className="text-green-400">Approved</span></>
                  ) : (
                    <><XCircle className="h-3.5 w-3.5 text-red-400" /><span className="text-red-400">Rejected</span></>
                  )}
                </dd>
              </div>
            )}
          </dl>
        </div>

        {/* Blue Side */}
        <div className="rounded-lg border border-indigo-500/20 bg-indigo-900/10 p-4">
          <h3 className="mb-3 flex items-center gap-2 text-sm font-semibold text-indigo-400">
            <ShieldCheck className="h-4 w-4" /> Blue Team (Detection)
          </h3>
          <dl className="space-y-3">
            <div>
              <dt className="text-xs font-medium uppercase text-gray-500">Detection Result</dt>
              <dd className="mt-0.5 text-sm">
                {test.detection_result ? (
                  <span
                    className={`inline-flex rounded-full border px-2 py-0.5 text-xs font-medium ${
                      test.detection_result === "detected"
                        ? "border-green-500/30 bg-green-900/50 text-green-400"
                        : test.detection_result === "not_detected"
                          ? "border-red-500/30 bg-red-900/50 text-red-400"
                          : "border-yellow-500/30 bg-yellow-900/50 text-yellow-400"
                    }`}
                  >
                    {test.detection_result.replace(/_/g, " ")}
                  </span>
                ) : (
                  <span className="text-gray-500">Not evaluated</span>
                )}
              </dd>
            </div>
            <div>
              <dt className="text-xs font-medium uppercase text-gray-500">Summary</dt>
              <dd className="mt-0.5"><MarkdownText content={test.blue_summary || "N/A"} className="text-sm text-gray-300" /></dd>
            </div>
            <div>
              <dt className="text-xs font-medium uppercase text-gray-500">Evidence Files</dt>
              <dd className="mt-0.5 text-sm text-gray-400">
                {(test.blue_evidences || []).length} file(s)
              </dd>
            </div>
            {test.blue_validation_status && (
              <div>
                <dt className="text-xs font-medium uppercase text-gray-500">Blue Lead Validation</dt>
                <dd className="mt-0.5 flex items-center gap-1 text-sm">
                  {test.blue_validation_status === "approved" ? (
                    <><CheckCircle className="h-3.5 w-3.5 text-green-400" /><span className="text-green-400">Approved</span></>
                  ) : (
                    <><XCircle className="h-3.5 w-3.5 text-red-400" /><span className="text-red-400">Rejected</span></>
                  )}
                </dd>
              </div>
            )}
            {test.system_gaps && (
              <div>
                <dt className="text-xs font-medium uppercase text-gray-500">System Gaps Flagged</dt>
                <dd className="mt-0.5 text-sm text-purple-300">{test.system_gaps}</dd>
              </div>
            )}
          </dl>
        </div>
      </div>

      {/* Final Result */}
      <div className="rounded-lg border border-gray-700 bg-gray-800/50 p-4">
        <h3 className="mb-2 text-sm font-semibold text-gray-300">Final Result</h3>
        <div className="flex items-center gap-4">
          <div className="flex items-center gap-2">
            <span className="text-xs text-gray-500">State:</span>
            <span className="text-sm font-medium capitalize text-gray-200">
              {test.state.replace(/_/g, " ")}
            </span>
          </div>
          {test.detection_result && (
            <div className="flex items-center gap-2">
              <span className="text-xs text-gray-500">Detection:</span>
              <span className="text-sm font-medium capitalize text-gray-200">
                {test.detection_result.replace(/_/g, " ")}
              </span>
            </div>
          )}
        </div>
      </div>
    </div>
  );

  // ── Timeline Tab ─────────────────────────────────────────────────

  const renderTimelineTab = () => {
    if (isTimelineLoading) {
      return (
        <div className="flex items-center justify-center py-12">
          <Loader2 className="h-6 w-6 animate-spin text-gray-500" />
        </div>
      );
    }

    if (!timeline || timeline.length === 0) {
      return (
        <div className="py-12 text-center">
          <Clock className="mx-auto h-10 w-10 text-gray-600" />
          <p className="mt-2 text-sm text-gray-400">No timeline events yet</p>
        </div>
      );
    }

    const formatDate = (d: string) =>
      new Date(d).toLocaleString("en-US", {
        month: "short",
        day: "numeric",
        hour: "2-digit",
        minute: "2-digit",
        second: "2-digit",
      });

    return (
      <div className="relative space-y-0">
        {/* Timeline vertical line */}
        <div className="absolute left-4 top-2 bottom-2 w-px bg-gray-700" />

        {timeline.map((entry, idx) => (
          <div key={entry.id || idx} className="relative flex gap-4 py-3">
            {/* Dot */}
            <div className="z-10 flex h-8 w-8 shrink-0 items-center justify-center rounded-full border border-gray-700 bg-gray-800">
              <Clock className="h-3.5 w-3.5 text-gray-400" />
            </div>
            {/* Content */}
            <div className="flex-1 pt-0.5">
              <p className="text-sm font-medium text-gray-200">{entry.action}</p>
              <p className="text-xs text-gray-500">
                {formatDate(entry.timestamp)}
                {entry.user_id && ` - User: ${entry.user_id}`}
              </p>
              {entry.details && Object.keys(entry.details).length > 0 && (
                <pre className="mt-1 max-h-24 overflow-auto rounded bg-gray-800 p-2 font-mono text-xs text-gray-400">
                  {JSON.stringify(entry.details, null, 2)}
                </pre>
              )}
            </div>
          </div>
        ))}
      </div>
    );
  };

  // ── Tab content router ───────────────────────────────────────────

  const TAB_CONTENT: Record<TabKey, () => React.ReactNode> = {
    red: renderRedTab,
    blue: renderBlueTab,
    summary: renderSummaryTab,
    timeline: renderTimelineTab,
  };

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

  return (
    <div className="rounded-xl border border-gray-800 bg-gray-900">
      {/* Tab bar */}
      <div className="flex border-b border-gray-800">
        {TABS.map((tab) => (
          <button
            key={tab.key}
            onClick={() => setActiveTab(tab.key)}
            className={`flex items-center gap-2 border-b-2 px-5 py-3 text-sm font-medium transition-colors ${
              activeTab === tab.key
                ? TAB_COLORS[tab.key]
                : "border-transparent text-gray-500 hover:text-gray-300"
            }`}
          >
            {tab.icon}
            {tab.label}
          </button>
        ))}
      </div>

      {/* Tab content */}
      <div className="p-6">{TAB_CONTENT[activeTab]()}</div>
    </div>
  );
}
