import { useState, useMemo } from "react";
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
import { useNavigate } from "react-router-dom";
import {
  Loader2,
  AlertCircle,
  Plus,
  Filter,
  ListChecks,
  Clock,
  CheckCircle,
  XCircle,
  Eye,
  Play,
  Shield,
  Search,
  ChevronUp,
  ChevronDown,
  ChevronsUpDown,
  Timer,
  AlertTriangle,
  Lightbulb,
} from "lucide-react";
import { getTests, type TestListFilters } from "../api/tests";
import {
  getProcedureSuggestions,
  approveProcedureSuggestion,
  rejectProcedureSuggestion,
} from "../api/procedure-suggestions";
import type { Test, TestState } from "../types/models";
import { useAuth } from "../context/AuthContext";

/* ── Badge colour map ──────────────────────────────────────────────── */

const testStateBadgeColors: Record<TestState, string> = {
  draft: "bg-gray-800/50 text-gray-400 border-gray-600/30",
  red_executing: "bg-orange-900/50 text-orange-400 border-orange-500/30",
  red_review: "bg-amber-900/50 text-amber-400 border-amber-500/30",
  blue_evaluating: "bg-indigo-900/50 text-indigo-400 border-indigo-500/30",
  blue_review: "bg-purple-900/50 text-purple-400 border-purple-500/30",
  in_review: "bg-blue-900/50 text-blue-400 border-blue-500/30",
  validated: "bg-green-900/50 text-green-400 border-green-500/30",
  rejected: "bg-red-900/50 text-red-400 border-red-500/30",
  disputed: "bg-amber-900/50 text-amber-400 border-amber-500/30",
};

const testStateLabels: Record<TestState, string> = {
  draft: "Draft",
  red_executing: "Red Executing",
  red_review: "Red Review",
  blue_evaluating: "Blue Evaluating",
  blue_review: "Blue Review",
  in_review: "In Review",
  validated: "Validated",
  rejected: "Rejected",
  disputed: "Disputed",
};

const ALL_STATES: TestState[] = [
  "draft",
  "red_executing",
  "red_review",
  "blue_evaluating",
  "blue_review",
  "in_review",
  "validated",
  "rejected",
  "disputed",
];

/* ── Helper: which team "owns" the current state ────────────────────── */

function currentTeamForState(state: TestState): string {
  switch (state) {
    case "draft":
    case "red_executing":
      return "Red Team";
    case "red_review":
      return "Red Lead";
    case "blue_evaluating":
      return "Blue Team";
    case "blue_review":
      return "Blue Lead";
    case "in_review":
      return "Managers";
    case "validated":
      return "-";
    case "rejected":
      return "Red Team";
    default:
      return "-";
  }
}

/* ── Helper: most recent activity timestamp on a test ──────────────── */
// updated_at column does not exist in the DB — derive from available fields
function lastActivityDate(t: Test): string | null {
  const candidates = [
    t.blue_validated_at,
    t.red_validated_at,
    (t as any).blue_work_started_at,
    (t as any).blue_started_at,
    (t as any).red_started_at,
    t.created_at,
  ].filter(Boolean) as string[];
  if (!candidates.length) return null;
  return candidates.reduce((latest, d) =>
    new Date(d) > new Date(latest) ? d : latest
  );
}

/* ── Helper: elapsed time since a date ─────────────────────────────── */

function formatElapsed(dateStr: string | null | undefined): string {
  if (!dateStr) return "—";
  const utc =
    dateStr.endsWith("Z") || dateStr.includes("+") ? dateStr : dateStr + "Z";
  const ms = Date.now() - new Date(utc).getTime();
  const minutes = Math.floor(ms / 60000);
  if (minutes < 1) return "<1m";
  if (minutes < 60) return `${minutes}m`;
  const hours = Math.floor(minutes / 60);
  if (hours < 24) return `${hours}h ${minutes % 60}m`;
  const days = Math.floor(hours / 24);
  return `${days}d ${hours % 24}h`;
}

/* ── Shared sort key type ────────────────────────────────────────────── */

type SortKey =
  | "name"
  | "technique"
  | "state"
  | "team"
  | "platform"
  | "created_at"
  | "updated_at"
  | "waiting_time";

/* ── Component ──────────────────────────────────────────────────────── */

const isTechRole = (role?: string) => role === "red_tech" || role === "blue_tech";

export default function TestsPage() {
  const navigate = useNavigate();
  const { user } = useAuth();

  // Only leads can create tests — admin administers the site, not test content.
  const canCreate = user?.role === "red_lead" || user?.role === "blue_lead";

  const techRole = isTechRole(user?.role);

  // ── Filter state ──────────────────────────────────────────────────
  const [stateFilter, setStateFilter] = useState<TestState | "">("");
  const [platformFilter, setPlatformFilter] = useState("");
  const [searchText, setSearchText] = useState("");
  const [showMyTasks, setShowMyTasks] = useState(false);
  const isReviewLead = user?.role === "red_lead" || user?.role === "blue_lead";
  const reviewQueueActive = isReviewLead && !showMyTasks;

  // ── Sort state ────────────────────────────────────────────────────
  const [sortKey, setSortKey] = useState<SortKey>("created_at");
  const [sortDir, setSortDir] = useState<"asc" | "desc">("desc");

  const handleSort = (key: SortKey) => {
    if (sortKey === key) {
      setSortDir((d) => (d === "asc" ? "desc" : "asc"));
    } else {
      setSortKey(key);
      setSortDir(key === "waiting_time" ? "asc" : "asc");
    }
  };

  // Build API filters
  const filters = useMemo<TestListFilters>(() => {
    const f: TestListFilters = { limit: 200 };

    if (showMyTasks && user) {
      switch (user.role) {
        case "red_tech":
          f.created_by = user.id;
          if (stateFilter) f.state = stateFilter as TestState;
          break;
        case "blue_tech":
          f.state = "blue_evaluating";
          break;
        case "red_lead":
          f.pending_validation_side = "red";
          break;
        case "blue_lead":
          f.pending_validation_side = "blue";
          break;
        default:
          if (stateFilter) f.state = stateFilter as TestState;
          break;
      }
    } else {
      if (stateFilter) f.state = stateFilter as TestState;
    }

    if (platformFilter) f.platform = platformFilter;
    return f;
  }, [stateFilter, platformFilter, showMyTasks, user]);

  const {
    data: allTests,
    isLoading,
    error,
  } = useQuery({
    queryKey: ["tests", filters],
    queryFn: () => getTests(filters),
  });

  // Client-side filtering
  const tests = useMemo(() => {
    if (!allTests) return [];
    let filtered = allTests;

    // Red tech "my tasks" — client-side filter for draft + red_executing
    if (showMyTasks && user?.role === "red_tech" && !stateFilter) {
      filtered = filtered.filter(
        (t) => t.state === "draft" || t.state === "red_executing"
      );
    }

    // Exclude validated from this table — they live in /tests/validated
    if (stateFilter !== "validated") {
      filtered = filtered.filter((t) => t.state !== "validated");
    }

    // Search text
    if (searchText.trim()) {
      const q = searchText.toLowerCase();
      filtered = filtered.filter(
        (t) =>
          t.name.toLowerCase().includes(q) ||
          (t.technique_mitre_id && t.technique_mitre_id.toLowerCase().includes(q)) ||
          (t.technique_name && t.technique_name.toLowerCase().includes(q))
      );
    }

    // Sort
    filtered = [...filtered].sort((a, b) => {
      let av = "";
      let bv = "";

      switch (sortKey) {
        case "name":
          av = a.name.toLowerCase();
          bv = b.name.toLowerCase();
          break;
        case "technique":
          av = (a.technique_mitre_id || "").toLowerCase();
          bv = (b.technique_mitre_id || "").toLowerCase();
          break;
        case "state":
          av = a.state;
          bv = b.state;
          break;
        case "team":
          av = currentTeamForState(a.state);
          bv = currentTeamForState(b.state);
          break;
        case "platform":
          av = (a.platform || "").toLowerCase();
          bv = (b.platform || "").toLowerCase();
          break;
        case "created_at":
          av = a.created_at || "";
          bv = b.created_at || "";
          break;
        case "updated_at":
          av = lastActivityDate(a) || "";
          bv = lastActivityDate(b) || "";
          break;
        case "waiting_time": {
          const aIsBlue = a.state === "blue_evaluating";
          const bIsBlue = b.state === "blue_evaluating";
          if (aIsBlue && bIsBlue) {
            // Older blue_started_at = waited longer = sort first in asc
            av = (a as any).blue_started_at || a.created_at || "";
            bv = (b as any).blue_started_at || b.created_at || "";
          } else {
            if (aIsBlue && !bIsBlue) return sortDir === "asc" ? -1 : 1;
            if (!aIsBlue && bIsBlue) return sortDir === "asc" ? 1 : -1;
            av = (a as any).blue_started_at || a.created_at || "";
            bv = (b as any).blue_started_at || b.created_at || "";
          }
          break;
        }
      }
      const cmp = av < bv ? -1 : av > bv ? 1 : 0;
      return sortDir === "asc" ? cmp : -cmp;
    });

    return filtered;
  }, [allTests, searchText, showMyTasks, user, stateFilter, sortKey, sortDir]);

  // ── State counters ────────────────────────────────────────────────
  const { data: allTestsUnfiltered } = useQuery({
    queryKey: ["tests", "unfiltered-counts"],
    queryFn: () => getTests({ limit: 200 }),
  });

  const globalCounts = useMemo(() => {
    const counts: Record<string, number> = {};
    for (const s of ALL_STATES) counts[s] = 0;
    if (allTestsUnfiltered) {
      for (const t of allTestsUnfiltered) {
        counts[t.state] = (counts[t.state] || 0) + 1;
      }
    }
    return counts;
  }, [allTestsUnfiltered]);

  const totalTests = allTestsUnfiltered?.length || 0;

  // ── Two-queue split for tech roles ────────────────────────────────
  const { availableTests, myAssignedTests } = useMemo(() => {
    if (!techRole || !user || !allTests) {
      return { availableTests: [] as typeof tests, myAssignedTests: [] as typeof tests };
    }

    let searchFiltered = allTests.filter((t) => t.state !== "validated");
    if (searchText.trim()) {
      const q = searchText.toLowerCase();
      searchFiltered = searchFiltered.filter(
        (t) =>
          t.name.toLowerCase().includes(q) ||
          (t.technique_mitre_id && t.technique_mitre_id.toLowerCase().includes(q)) ||
          (t.technique_name && t.technique_name.toLowerCase().includes(q))
      );
    }
    if (platformFilter) {
      searchFiltered = searchFiltered.filter((t) =>
        t.platform?.toLowerCase().includes(platformFilter.toLowerCase())
      );
    }

    if (user.role === "red_tech") {
      const available = searchFiltered.filter(
        (t) =>
          (t.state === "draft" || t.state === "red_executing") &&
          t.red_tech_assignee === null
      );
      const mine = searchFiltered.filter((t) => t.red_tech_assignee === user.id);
      return { availableTests: available, myAssignedTests: mine };
    }

    if (user.role === "blue_tech") {
      const available = searchFiltered.filter(
        (t) =>
          t.state === "blue_evaluating" &&
          t.blue_tech_assignee === null &&
          t.blue_work_started_at === null
      );
      const mine = searchFiltered.filter((t) => t.blue_tech_assignee === user.id);
      return { availableTests: available, myAssignedTests: mine };
    }

    return { availableTests: [] as typeof tests, myAssignedTests: [] as typeof tests };
  }, [techRole, user, allTests, searchText, platformFilter]);

  // ── Two-queue split for lead review gate (red_review / blue_review) ─
  // The auto load-balancer always assigns a reviewer immediately, so
  // "available" here means "assigned to another lead" — visible so a
  // lead can pick up a peer's review if they can't get to it.
  //
  // Also includes cross-validation (in_review) tests still awaiting this
  // lead's vote — previously only surfaced by toggling "My Tasks", which
  // meant a lead landing on this page by default never saw them here at
  // all despite this being "the review queue" as far as they're concerned.
  const { availableReviews, myAssignedReviews, pendingMyValidation } = useMemo(() => {
    if (!isReviewLead || !user || !allTests || showMyTasks) {
      return {
        availableReviews: [] as typeof tests,
        myAssignedReviews: [] as typeof tests,
        pendingMyValidation: [] as typeof tests,
      };
    }

    let searchFiltered = allTests;
    if (searchText.trim()) {
      const q = searchText.toLowerCase();
      searchFiltered = searchFiltered.filter(
        (t) =>
          t.name.toLowerCase().includes(q) ||
          (t.technique_mitre_id && t.technique_mitre_id.toLowerCase().includes(q)) ||
          (t.technique_name && t.technique_name.toLowerCase().includes(q))
      );
    }
    if (platformFilter) {
      searchFiltered = searchFiltered.filter((t) =>
        t.platform?.toLowerCase().includes(platformFilter.toLowerCase())
      );
    }

    const reviewState = user.role === "red_lead" ? "red_review" : "blue_review";
    const reviewerField = user.role === "red_lead" ? "red_reviewer_assignee" : "blue_reviewer_assignee";
    const inState = searchFiltered.filter((t) => t.state === reviewState);
    const available = inState.filter((t) => t[reviewerField] !== user.id);
    const mine = inState.filter((t) => t[reviewerField] === user.id);

    const validationField = user.role === "red_lead" ? "red_validation_status" : "blue_validation_status";
    const pendingValidation = searchFiltered.filter(
      (t) => t.state === "in_review" && !t[validationField]
    );

    return { availableReviews: available, myAssignedReviews: mine, pendingMyValidation: pendingValidation };
  }, [isReviewLead, user, allTests, searchText, platformFilter, showMyTasks]);

  // ── Disputed tests — always fetched independently of the my-tasks
  // toggle/state filter so this alert never silently disappears just
  // because the lead is looking at a different view. ──────────────────
  const { data: disputedTests = [] } = useQuery({
    queryKey: ["tests", "disputed-queue"],
    queryFn: () => getTests({ state: "disputed", limit: 200 }),
    enabled: isReviewLead,
  });

  // ── Formatting helpers ─────────────────────────────────────────────
  const 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",
    });
  };

  // ── My tasks label ────────────────────────────────────────────────
  const myTasksLabel = useMemo(() => {
    if (!user) return "My Tasks";
    switch (user.role) {
      case "red_tech":
        return "My Tests (Draft / Executing)";
      case "blue_tech":
        return "Pending Blue Evaluation";
      case "red_lead":
        return "Pending Red Validation";
      case "blue_lead":
        return "Pending Blue Validation";
      default:
        return "My Tasks";
    }
  }, [user]);

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

  if (isLoading) {
    return (
      <div className="flex h-64 items-center justify-center">
        <Loader2 className="h-8 w-8 animate-spin text-cyan-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 tests</p>
      </div>
    );
  }

  const mainTableColumns: { key: SortKey; label: string; cls: string }[] = [
    { key: "name", label: "Name", cls: "pr-4" },
    { key: "technique", label: "Technique", cls: "px-4" },
    { key: "state", label: "State", cls: "px-4" },
    { key: "team", label: "Current Team", cls: "px-4" },
    { key: "platform", label: "Platform", cls: "px-4" },
    { key: "waiting_time", label: "Waiting", cls: "px-4" },
    { key: "created_at", label: "Created", cls: "px-4" },
    { key: "updated_at", label: "Updated", cls: "px-4" },
  ];

  return (
    <div className="space-y-6">
      {/* Header */}
      <div className="flex items-center justify-between">
        <div>
          <h1 className="text-2xl font-bold text-white">Tests</h1>
          <p className="mt-1 text-sm text-gray-400">
            Security tests for technique validation — Red/Blue workflow
          </p>
        </div>
        {canCreate && (
          <button
            onClick={() => navigate("/tests/new")}
            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" />
            New Test
          </button>
        )}
      </div>

      {/* ── State Counter Cards ───────────────────────────────────────── */}
      <div className="grid gap-2 grid-cols-3 sm:grid-cols-5 lg:grid-cols-9">
        {ALL_STATES.map((state) => {
          const icons: Record<TestState, React.ReactNode> = {
            draft: <Clock className="h-4 w-4 text-gray-400" />,
            red_executing: <Play className="h-4 w-4 text-orange-400" />,
            red_review: <Shield className="h-4 w-4 text-amber-400" />,
            blue_evaluating: <Shield className="h-4 w-4 text-indigo-400" />,
            blue_review: <Shield className="h-4 w-4 text-purple-400" />,
            in_review: <Eye className="h-4 w-4 text-blue-400" />,
            validated: <CheckCircle className="h-4 w-4 text-green-400" />,
            rejected: <XCircle className="h-4 w-4 text-red-400" />,
            disputed: <AlertTriangle className="h-4 w-4 text-amber-400" />,
          };
          const colorMap: Record<TestState, string> = {
            draft: "text-gray-400",
            red_executing: "text-orange-400",
            red_review: "text-amber-400",
            blue_evaluating: "text-indigo-400",
            blue_review: "text-purple-400",
            in_review: "text-blue-400",
            validated: "text-green-400",
            rejected: "text-red-400",
            disputed: "text-amber-400",
          };
          return (
            <button
              key={state}
              onClick={() => {
                if (state === "validated") {
                  navigate("/tests/validated");
                  return;
                }
                setShowMyTasks(false);
                setStateFilter(stateFilter === state ? "" : state);
              }}
              className={`rounded-xl border p-2.5 text-left transition-colors ${
                stateFilter === state
                  ? "border-cyan-500/50 bg-cyan-500/10"
                  : "border-gray-800 bg-gray-900 hover:border-gray-700"
              }`}
            >
              <div className="flex items-center gap-1.5">
                {icons[state]}
                <span className="text-[11px] text-gray-400 truncate">
                  {testStateLabels[state]}
                </span>
              </div>
              <p className={`mt-1.5 text-lg font-bold ${colorMap[state]}`}>
                {globalCounts[state]}
              </p>
            </button>
          );
        })}
      </div>

      {/* ── Filters Bar ───────────────────────────────────────────────── */}
      <div className="rounded-xl border border-gray-800 bg-gray-900 p-4">
        <div className="flex flex-wrap items-center gap-3">
          {/* My tasks toggle — hidden for tech roles (two-queue view below);
              for leads this switches AWAY from the review two-queue view
              to the in_review dual-validation stage, a distinct responsibility. */}
          {user?.role !== "admin" && user?.role !== "viewer" && !techRole && (
            <button
              onClick={() => {
                setShowMyTasks(!showMyTasks);
                if (!showMyTasks) {
                  setStateFilter("");
                }
              }}
              className={`flex items-center gap-1.5 rounded-lg border px-3 py-2 text-sm font-medium transition-colors ${
                showMyTasks
                  ? "border-cyan-500/50 bg-cyan-500/20 text-cyan-400"
                  : "border-gray-700 bg-gray-800 text-gray-300 hover:border-gray-600"
              }`}
            >
              <ListChecks className="h-4 w-4" />
              {myTasksLabel}
            </button>
          )}

          {/* State filter */}
          <div className="flex items-center gap-1.5">
            <Filter className="h-4 w-4 text-gray-500" />
            <select
              value={stateFilter}
              onChange={(e) => {
                const val = e.target.value as TestState | "";
                if (val === "validated") {
                  navigate("/tests/validated");
                  return;
                }
                setStateFilter(val);
              }}
              className="rounded-lg border border-gray-700 bg-gray-800 px-3 py-2 text-sm text-gray-300 focus:border-cyan-500 focus:outline-none"
            >
              <option value="">All States</option>
              {ALL_STATES.filter((s) => s !== "validated").map((s) => (
                <option key={s} value={s}>
                  {testStateLabels[s]}
                </option>
              ))}
            </select>
          </div>

          {/* Platform filter */}
          <input
            type="text"
            value={platformFilter}
            onChange={(e) => setPlatformFilter(e.target.value)}
            placeholder="Platform..."
            className="rounded-lg border border-gray-700 bg-gray-800 px-3 py-2 text-sm text-gray-300 placeholder-gray-500 focus:border-cyan-500 focus:outline-none w-32"
          />

          {/* Search */}
          <div className="relative flex-1 min-w-[200px]">
            <Search className="absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-gray-500" />
            <input
              type="text"
              value={searchText}
              onChange={(e) => setSearchText(e.target.value)}
              placeholder="Search by name or technique..."
              className="w-full rounded-lg border border-gray-700 bg-gray-800 pl-9 pr-3 py-2 text-sm text-gray-300 placeholder-gray-500 focus:border-cyan-500 focus:outline-none"
            />
          </div>

          {/* Clear filters */}
          {(stateFilter || platformFilter || searchText || showMyTasks) && (
            <button
              onClick={() => {
                setStateFilter("");
                setPlatformFilter("");
                setSearchText("");
                setShowMyTasks(false);
              }}
              className="text-xs text-gray-400 hover:text-white transition-colors"
            >
              Clear all
            </button>
          )}
        </div>

        {/* Active filter summary */}
        {(stateFilter || showMyTasks) && (
          <div className="mt-3 flex items-center gap-2 text-xs text-gray-400">
            <span>Showing:</span>
            {showMyTasks && (
              <span className="rounded-full border border-cyan-500/30 bg-cyan-500/10 px-2 py-0.5 text-cyan-400">
                {myTasksLabel}
              </span>
            )}
            {stateFilter && (
              <span className="rounded-full border border-gray-600 bg-gray-800 px-2 py-0.5 text-gray-300">
                {testStateLabels[stateFilter as TestState]}
              </span>
            )}
            <span className="text-gray-500">
              ({tests.length} of {totalTests} tests)
            </span>
          </div>
        )}
      </div>

      {/* ── Disputed tests — most urgent, always on top when present ──── */}
      {isReviewLead && disputedTests.length > 0 && (
        <div className="rounded-xl border border-amber-500/40 bg-amber-500/5 p-6">
          <div className="mb-4 flex items-center justify-between">
            <div className="flex items-center gap-2">
              <AlertTriangle className="h-5 w-5 text-amber-400" />
              <h2 className="text-lg font-semibold text-amber-400">Disputed</h2>
              <span className="rounded-full border border-amber-500/30 bg-amber-500/10 px-2 py-0.5 text-xs font-medium text-amber-400">
                {disputedTests.length}
              </span>
            </div>
            <span className="text-xs text-amber-400/70">Leads disagree on the outcome — needs resolution</span>
          </div>
          <TestTable
            tests={disputedTests}
            columns={mainTableColumns}
            sortKey={sortKey}
            sortDir={sortDir}
            handleSort={handleSort}
            navigate={navigate}
            formatDate={formatDate}
            emptyMessage=""
          />
        </div>
      )}

      {/* ── Tests Table / Two-Queue View ─────────────────────────────── */}
      {techRole ? (
        /* Two-section queue for red_tech and blue_tech */
        <div className="space-y-6">
          {/* Available Tests */}
          <div className="rounded-xl border border-gray-800 bg-gray-900 p-6">
            <div className="mb-4 flex items-center justify-between">
              <div className="flex items-center gap-2">
                <h2 className="text-lg font-semibold text-white">Available Tests</h2>
                <span className="rounded-full border border-cyan-500/30 bg-cyan-500/10 px-2 py-0.5 text-xs font-medium text-cyan-400">
                  {availableTests.length}
                </span>
              </div>
              <span className="text-xs text-gray-500">Unassigned — pick one to claim it</span>
            </div>
            <TestTable tests={availableTests} columns={mainTableColumns} sortKey={sortKey} sortDir={sortDir} handleSort={handleSort} navigate={navigate} formatDate={formatDate} emptyMessage="No available tests right now." />
          </div>

          {/* My Assigned Tests */}
          <div className="rounded-xl border border-gray-800 bg-gray-900 p-6">
            <div className="mb-4 flex items-center justify-between">
              <div className="flex items-center gap-2">
                <h2 className="text-lg font-semibold text-white">My Assigned Tests</h2>
                <span className="rounded-full border border-orange-500/30 bg-orange-500/10 px-2 py-0.5 text-xs font-medium text-orange-400">
                  {myAssignedTests.length}
                </span>
              </div>
              <span className="text-xs text-gray-500">Tests assigned to you</span>
            </div>
            <TestTable tests={myAssignedTests} columns={mainTableColumns} sortKey={sortKey} sortDir={sortDir} handleSort={handleSort} navigate={navigate} formatDate={formatDate} emptyMessage="No tests currently assigned to you." />
          </div>
        </div>
      ) : reviewQueueActive ? (
        /* Two-section review queue for red_lead/blue_lead */
        <div className="space-y-6">
          {/* Available to Review */}
          <div className="rounded-xl border border-gray-800 bg-gray-900 p-6">
            <div className="mb-4 flex items-center justify-between">
              <div className="flex items-center gap-2">
                <h2 className="text-lg font-semibold text-white">Available to Review</h2>
                <span className="rounded-full border border-cyan-500/30 bg-cyan-500/10 px-2 py-0.5 text-xs font-medium text-cyan-400">
                  {availableReviews.length}
                </span>
              </div>
              <span className="text-xs text-gray-500">Assigned to other leads — pick one up if needed</span>
            </div>
            <TestTable tests={availableReviews} columns={mainTableColumns} sortKey={sortKey} sortDir={sortDir} handleSort={handleSort} navigate={navigate} formatDate={formatDate} emptyMessage="No other pending reviews right now." />
          </div>

          {/* My Assigned Reviews */}
          <div className="rounded-xl border border-gray-800 bg-gray-900 p-6">
            <div className="mb-4 flex items-center justify-between">
              <div className="flex items-center gap-2">
                <h2 className="text-lg font-semibold text-white">My Assigned Reviews</h2>
                <span className="rounded-full border border-orange-500/30 bg-orange-500/10 px-2 py-0.5 text-xs font-medium text-orange-400">
                  {myAssignedReviews.length}
                </span>
              </div>
              <span className="text-xs text-gray-500">Reviews assigned to you</span>
            </div>
            <TestTable tests={myAssignedReviews} columns={mainTableColumns} sortKey={sortKey} sortDir={sortDir} handleSort={handleSort} navigate={navigate} formatDate={formatDate} emptyMessage="No reviews currently assigned to you." />
          </div>

          {/* Awaiting My Validation — cross-validation stage (in_review),
              distinct from the red_review/blue_review gate above: both
              leads act independently here, so there's no "assigned to
              someone else" bucket, just "have I voted yet or not". */}
          <div className="rounded-xl border border-gray-800 bg-gray-900 p-6">
            <div className="mb-4 flex items-center justify-between">
              <div className="flex items-center gap-2">
                <h2 className="text-lg font-semibold text-white">Awaiting My Validation</h2>
                <span className="rounded-full border border-blue-500/30 bg-blue-500/10 px-2 py-0.5 text-xs font-medium text-blue-400">
                  {pendingMyValidation.length}
                </span>
              </div>
              <span className="text-xs text-gray-500">Cross-validation — both leads vote independently</span>
            </div>
            <TestTable tests={pendingMyValidation} columns={mainTableColumns} sortKey={sortKey} sortDir={sortDir} handleSort={handleSort} navigate={navigate} formatDate={formatDate} emptyMessage="Nothing awaiting your validation right now." />
          </div>
        </div>
      ) : (
        /* Normal single-table view for admin, viewer, and leads viewing "My Tasks" */
        <div className="rounded-xl border border-gray-800 bg-gray-900 p-6">
          <div className="mb-4 flex items-center justify-between">
            <h2 className="text-lg font-semibold text-white">
              {showMyTasks ? myTasksLabel : "All Tests"}
            </h2>
            <span className="text-sm text-gray-400">{tests.length} tests</span>
          </div>
          <TestTable tests={tests} columns={mainTableColumns} sortKey={sortKey} sortDir={sortDir} handleSort={handleSort} navigate={navigate} formatDate={formatDate} emptyMessage={showMyTasks ? "No pending tasks for your role." : "No tests found matching your filters."} />
        </div>
      )}

      {/* ── Procedure suggestions for leads ───────────────────────────
          GET /procedure-suggestions is already scoped server-side to the
          caller's own team (red_lead sees only red, blue_lead only blue),
          so no client-side filtering is needed here. */}
      {isReviewLead && <ProcedureSuggestionsPanel />}

      {/* ── Team queue overview for leads ─────────────────────────────
          red_lead/blue_lead never hit the plain "All Tests" branch above —
          they're always routed into the review two-queue view or their
          own "My Tasks" — so they had no way to see every test and who's
          working it, which is what they need to spot a stuck ticket or an
          overloaded operator. Always shown at the end, independent of the
          my-tasks toggle above, with assignees visible on both sides. */}
      {isReviewLead && (
        <div className="rounded-xl border border-gray-800 bg-gray-900 p-6">
          <div className="mb-4 flex items-center justify-between">
            <div className="flex items-center gap-2">
              <h2 className="text-lg font-semibold text-white">All Tests — Team Queue Overview</h2>
              <span className="rounded-full border border-gray-600 bg-gray-800 px-2 py-0.5 text-xs font-medium text-gray-300">
                {tests.length}
              </span>
            </div>
            <span className="text-xs text-gray-500">Every test, with who's assigned on each side</span>
          </div>
          <TestTable
            tests={tests}
            columns={mainTableColumns}
            sortKey={sortKey}
            sortDir={sortDir}
            handleSort={handleSort}
            navigate={navigate}
            formatDate={formatDate}
            emptyMessage="No tests found matching your filters."
            showAssignees
          />
        </div>
      )}
    </div>
  );
}

/* ── Procedure suggestions panel (leads only) ─────────────────────── */

function ProcedureSuggestionsPanel() {
  const queryClient = useQueryClient();

  const { data: suggestions = [] } = useQuery({
    queryKey: ["procedure-suggestions"],
    queryFn: getProcedureSuggestions,
  });

  const invalidate = () => queryClient.invalidateQueries({ queryKey: ["procedure-suggestions"] });
  const approveMutation = useMutation({ mutationFn: approveProcedureSuggestion, onSuccess: invalidate });
  const rejectMutation = useMutation({ mutationFn: rejectProcedureSuggestion, onSuccess: invalidate });
  const isBusy = approveMutation.isPending || rejectMutation.isPending;

  if (suggestions.length === 0) return null;

  return (
    <div className="rounded-xl border border-gray-800 bg-gray-900 p-6">
      <div className="mb-4 flex items-center gap-2">
        <Lightbulb className="h-5 w-5 text-yellow-400" />
        <h2 className="text-lg font-semibold text-white">Procedure Suggestions</h2>
        <span className="rounded-full border border-gray-600 bg-gray-800 px-2 py-0.5 text-xs font-medium text-gray-300">
          {suggestions.length}
        </span>
        <span className="text-xs text-gray-500">
          Commands extracted from submitted rounds, proposed as template updates
        </span>
      </div>
      <div className="space-y-3">
        {suggestions.map((s) => (
          <div key={s.id} className="rounded-lg border border-gray-700 bg-gray-800/50 p-4">
            <p className="text-sm font-medium text-gray-200">{s.template_name || "Unknown template"}</p>
            {s.template_current_text && (
              <div className="mt-2">
                <p className="text-xs font-medium uppercase text-gray-500">Current</p>
                <pre className="mt-1 whitespace-pre-wrap rounded bg-gray-900 p-2 font-mono text-xs text-gray-400">
                  {s.template_current_text}
                </pre>
              </div>
            )}
            <div className="mt-2">
              <p className="text-xs font-medium uppercase text-gray-500">Suggested</p>
              <pre className="mt-1 whitespace-pre-wrap rounded bg-gray-900 p-2 font-mono text-xs text-green-400">
                {s.suggested_text}
              </pre>
            </div>
            <div className="mt-3 flex gap-2">
              <button
                onClick={() => approveMutation.mutate(s.id)}
                disabled={isBusy}
                className="flex items-center gap-1 rounded-lg border border-green-500/30 bg-green-900/20 px-3 py-1.5 text-xs font-medium text-green-400 hover:bg-green-900/40 disabled:opacity-50"
              >
                <CheckCircle className="h-3.5 w-3.5" /> Approve
              </button>
              <button
                onClick={() => rejectMutation.mutate(s.id)}
                disabled={isBusy}
                className="flex items-center gap-1 rounded-lg border border-red-500/30 bg-red-900/20 px-3 py-1.5 text-xs font-medium text-red-400 hover:bg-red-900/40 disabled:opacity-50"
              >
                <XCircle className="h-3.5 w-3.5" /> Reject
              </button>
            </div>
          </div>
        ))}
      </div>
    </div>
  );
}

/* ── Shared test table component ────────────────────────────────────── */

function TestTable({
  tests,
  columns,
  sortKey,
  sortDir,
  handleSort,
  navigate,
  formatDate,
  emptyMessage,
  showAssignees = false,
}: {
  tests: Test[];
  columns: { key: SortKey; label: string; cls: string }[];
  sortKey: SortKey;
  sortDir: "asc" | "desc";
  handleSort: (key: SortKey) => void;
  navigate: (path: string) => void;
  formatDate: (d: string | null | undefined) => string;
  emptyMessage: string;
  /** Adds Red/Blue assignee columns — for the leads' team queue overview,
   * where seeing who's working each side is the whole point. */
  showAssignees?: boolean;
}) {
  return (
    <div className="overflow-x-auto">
      <table className="w-full text-left text-sm">
        <thead>
          <tr className="border-b border-gray-800">
            {columns.map(({ key, label, cls }) => (
              <th
                key={key}
                className={`pb-3 ${cls} font-medium text-gray-400 cursor-pointer select-none hover:text-white transition-colors`}
                onClick={() => handleSort(key)}
              >
                <span className="inline-flex items-center gap-1">
                  {key === "waiting_time" && (
                    <Timer className="h-3.5 w-3.5 text-indigo-400" />
                  )}
                  {label}
                  {sortKey === key ? (
                    sortDir === "asc" ? (
                      <ChevronUp className="h-3.5 w-3.5 text-cyan-400" />
                    ) : (
                      <ChevronDown className="h-3.5 w-3.5 text-cyan-400" />
                    )
                  ) : (
                    <ChevronsUpDown className="h-3.5 w-3.5 opacity-30" />
                  )}
                </span>
              </th>
            ))}
            {showAssignees && (
              <>
                <th className="pb-3 px-4 font-medium text-gray-400">Red Assignee</th>
                <th className="pb-3 px-4 font-medium text-gray-400">Blue Assignee</th>
              </>
            )}
            <th className="pb-3 pl-4 font-medium text-gray-400">Action</th>
          </tr>
        </thead>
        <tbody>
          {tests.map((test: Test) => (
            <tr
              key={test.id}
              className="border-b border-gray-800/50 hover:bg-gray-800/30 transition-colors cursor-pointer"
              onClick={() => navigate(`/tests/${test.id}`)}
            >
              <td className="py-3 pr-4">
                <span className="font-medium text-gray-200">{test.name}</span>
              </td>
              <td className="py-3 px-4">
                {test.technique_mitre_id ? (
                  <div className="flex flex-col">
                    <span className="font-mono text-xs text-cyan-400">
                      {test.technique_mitre_id}
                    </span>
                    <span className="text-xs text-gray-500 truncate max-w-[160px]">
                      {test.technique_name}
                    </span>
                  </div>
                ) : (
                  <span className="text-gray-500">-</span>
                )}
              </td>
              <td className="py-3 px-4">
                <span
                  className={`inline-flex rounded-full border px-2 py-0.5 text-xs font-medium ${
                    testStateBadgeColors[test.state]
                  }`}
                >
                  {test.state === "blue_evaluating" && !test.blue_work_started_at
                    ? "Queued Blue Team"
                    : testStateLabels[test.state]}
                </span>
              </td>
              <td className="py-3 px-4 text-gray-400 text-xs">
                {currentTeamForState(test.state)}
              </td>
              <td className="py-3 px-4 text-gray-400 text-xs">
                {test.platform || "-"}
              </td>
              {/* Waiting time — how long since Red submitted to Blue */}
              <td className="py-3 px-4 text-xs whitespace-nowrap">
                {test.state === "blue_evaluating" ? (
                  <span className="font-mono text-indigo-400">
                    {formatElapsed(test.blue_started_at)}
                  </span>
                ) : (
                  <span className="text-gray-700">—</span>
                )}
              </td>
              <td className="py-3 px-4 text-gray-400 text-xs whitespace-nowrap">
                {formatDate(test.created_at)}
              </td>
              <td className="py-3 px-4 text-gray-400 text-xs whitespace-nowrap">
                {formatDate(lastActivityDate(test))}
              </td>
              {showAssignees && (
                <>
                  <td className="py-3 px-4 text-xs text-gray-400 whitespace-nowrap">
                    {test.red_tech_assignee_username || "-"}
                  </td>
                  <td className="py-3 px-4 text-xs text-gray-400 whitespace-nowrap">
                    {test.blue_tech_assignee_username || "-"}
                  </td>
                </>
              )}
              <td className="py-3 pl-4">
                <button
                  onClick={(e) => {
                    e.stopPropagation();
                    navigate(`/tests/${test.id}`);
                  }}
                  className="text-sm text-cyan-400 hover:underline"
                >
                  View
                </button>
              </td>
            </tr>
          ))}
        </tbody>
      </table>

      {tests.length === 0 && (
        <div className="py-12 text-center text-gray-400">{emptyMessage}</div>
      )}
    </div>
  );
}
