import { useEffect, useState, useMemo } from "react";
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
import { useNavigate } from "react-router-dom";
import {
  Loader2,
  AlertCircle,
  TrendingUp,
  TrendingDown,
  Minus,
  ArrowRight,
  RefreshCw,
} from "lucide-react";
import {
  LineChart,
  Line,
  BarChart,
  Bar,
  XAxis,
  YAxis,
  CartesianGrid,
  Tooltip,
  ResponsiveContainer,
  Cell,
} from "recharts";
import { getOrganizationScore, getScoreHistory } from "../api/scores";
import MetricTooltip from "../components/MetricTooltip";
import {
  getOperationalMetrics,
  getMetricsByTeam,
} from "../api/operational-metrics";
import { getCoverageByTactic } from "../api/metrics";
import { getThreatActors } from "../api/threat-actors";
import { getTechniques, type TechniqueSummary } from "../api/techniques";
import { getRiskProfiles, computeRiskScores, type RiskProfile } from "../api/risk";
import { useAuth } from "../context/AuthContext";

// Roles allowed to trigger a risk-score recompute (matches the backend's
// POST /risk/compute role gate) — viewer must never call this endpoint.
const CAN_COMPUTE_RISK_ROLES = ["admin", "red_lead", "blue_lead"];

// ── Score Gauge Component ────────────────────────────────────────────

function ScoreGauge({ score, label }: { score: number; label: string }) {
  const getColor = (s: number) => {
    if (s < 30) return "#ef4444";
    if (s < 50) return "#f97316";
    if (s < 70) return "#eab308";
    return "#22c55e";
  };

  const color = getColor(score);
  const circumference = 2 * Math.PI * 54;
  const strokeDasharray = `${(score / 100) * circumference} ${circumference}`;

  return (
    <div className="flex flex-col items-center">
      <div className="relative h-32 w-32">
        <svg className="h-32 w-32 -rotate-90" viewBox="0 0 120 120">
          <circle
            cx="60"
            cy="60"
            r="54"
            fill="none"
            stroke="#1f2937"
            strokeWidth="8"
          />
          <circle
            cx="60"
            cy="60"
            r="54"
            fill="none"
            stroke={color}
            strokeWidth="8"
            strokeLinecap="round"
            strokeDasharray={strokeDasharray}
            className="transition-all duration-1000"
          />
        </svg>
        <div className="absolute inset-0 flex flex-col items-center justify-center">
          <span className="text-3xl font-bold text-white">{Math.round(score)}</span>
          <span className="text-[10px] text-gray-500">/ 100</span>
        </div>
      </div>
      <div className="mt-2 flex items-center gap-1">
        <span className="text-xs font-medium text-gray-400">{label}</span>
        <MetricTooltip
          title="Overall Programme Score"
          description="A composite score (0–100) reflecting the maturity of the Red/Blue Team testing programme across 4 dimensions: Coverage, Detection maturity, Critical technique coverage, and Response readiness. This score measures the depth and breadth of executed exercises — it does not represent the full real-world security posture of the organisation."
          context="< 30 = Critical programme gaps  |  30–50 = Limited coverage  |  50–70 = Progressing  |  > 70 = Mature programme"
          position="below"
        />
      </div>
    </div>
  );
}

// ── KPI Card Component ──────────────────────────────────────────────

function KPICard({
  label,
  value,
  unit,
  trend,
  tooltip,
}: {
  label: string;
  value: string | number;
  unit?: string;
  trend?: "improving" | "declining" | "stable" | null;
  tooltip?: { description: string; context?: string };
}) {
  const TrendIcon =
    trend === "improving"
      ? TrendingUp
      : trend === "declining"
      ? TrendingDown
      : Minus;

  const trendColor =
    trend === "improving"
      ? "text-green-400"
      : trend === "declining"
      ? "text-red-400"
      : "text-gray-500";

  return (
    <div className="rounded-xl border border-gray-800 bg-gray-900 p-4">
      <p className="text-xs text-gray-500 uppercase tracking-wider flex items-center gap-0.5">
        {label}
        {tooltip && <MetricTooltip title={label} description={tooltip.description} context={tooltip.context} />}
      </p>
      <div className="mt-2 flex items-end justify-between">
        <div>
          <span className="text-2xl font-bold text-white">
            {value === null || value === undefined ? "N/A" : value}
          </span>
          {unit && <span className="ml-1 text-sm text-gray-500">{unit}</span>}
        </div>
        {trend && (
          <TrendIcon className={`h-5 w-5 ${trendColor}`} />
        )}
      </div>
    </div>
  );
}

// ── Main Component ──────────────────────────────────────────────────

type TimeRange = "30d" | "90d" | "6m" | "1y" | "all";

const TIME_RANGE_OPTIONS: { value: TimeRange; label: string; days: number | null }[] = [
  { value: "30d",  label: "Last 30 days",  days: 30  },
  { value: "90d",  label: "Last 90 days",  days: 90  },
  { value: "6m",   label: "Last 6 months", days: 182 },
  { value: "1y",   label: "Last 12 months",days: 365 },
  { value: "all",  label: "All time",      days: null },
];

function sinceDate(days: number | null): string | undefined {
  if (!days) return undefined;
  const d = new Date(Date.now() - days * 86400_000);
  return d.toISOString().split("T")[0];
}

export default function ExecutiveDashboardPage() {
  const navigate = useNavigate();
  const { user } = useAuth();
  const canComputeRisk = CAN_COMPUTE_RISK_ROLES.includes(user?.role ?? "");

  const [timeRange, setTimeRange] = useState<TimeRange>("all");
  const rangeOption = TIME_RANGE_OPTIONS.find((o) => o.value === timeRange)!;
  const since = useMemo(() => sinceDate(rangeOption.days), [rangeOption]);

  const { data: orgScore, isLoading: loadingScore } = useQuery({
    queryKey: ["org-score"],
    queryFn: getOrganizationScore,
  });

  const { data: scoreHistory } = useQuery({
    queryKey: ["score-history", "90d"],
    queryFn: () => getScoreHistory("90d"),
  });

  const { data: opMetrics, isLoading: loadingMetrics } = useQuery({
    queryKey: ["operational-metrics", since],
    queryFn: () => getOperationalMetrics(since),
  });

  const { data: teamMetrics } = useQuery({
    queryKey: ["team-metrics", since],
    queryFn: () => getMetricsByTeam(since),
  });

  const { data: tacticCoverage } = useQuery({
    queryKey: ["tactic-coverage"],
    queryFn: getCoverageByTactic,
  });

  // Fetch enough actors to rank properly — sort client-side by uncovered techniques
  const { data: threatActors } = useQuery({
    queryKey: ["threat-actors-top"],
    queryFn: () => getThreatActors({ limit: 100 }),
  });

  const { data: allTechniques } = useQuery({
    queryKey: ["techniques-exec"],
    queryFn: () => getTechniques(),
  });

  const queryClient = useQueryClient();

  const { data: riskProfiles, isLoading: loadingRisk } = useQuery({
    queryKey: ["risk-profiles-exec"],
    queryFn: () => getRiskProfiles({ limit: 500 }),
  });

  const computeMutation = useMutation({
    mutationFn: computeRiskScores,
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ["risk-profiles-exec"] });
    },
  });

  // Auto-compute on first load if no profiles exist — only for roles the
  // backend actually allows to call POST /risk/compute (viewer would 403).
  useEffect(() => {
    if (canComputeRisk && !loadingRisk && riskProfiles !== undefined && riskProfiles.length === 0) {
      computeMutation.mutate();
    }
  // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [loadingRisk, riskProfiles?.length]);

  const isLoading = loadingScore || loadingMetrics;

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

  // Build a lookup: techniqueId → risk profile (already sorted by risk_score DESC server-side)
  const riskByTechniqueId = new Map<string, RiskProfile>(
    (riskProfiles || []).map((p) => [p.technique_id, p])
  );

  // Critical gaps: not_covered or not_evaluated, sorted by risk_score DESC
  // Techniques with a risk profile rank higher; ties broken by status (not_covered first)
  const criticalGaps: TechniqueSummary[] = (allTechniques || [])
    .filter((t) => t.status_global === "not_covered" || t.status_global === "not_evaluated")
    .sort((a, b) => {
      const scoreA = riskByTechniqueId.get(a.id)?.risk_score ?? -1;
      const scoreB = riskByTechniqueId.get(b.id)?.risk_score ?? -1;
      if (scoreB !== scoreA) return scoreB - scoreA;
      // same score: not_covered before not_evaluated
      if (a.status_global === "not_covered" && b.status_global !== "not_covered") return -1;
      if (b.status_global === "not_covered" && a.status_global !== "not_covered") return 1;
      return 0;
    })
    .slice(0, 10);

  // Official MITRE ATT&CK tactic order (slug → display label)
  const MITRE_TACTIC_ORDER: Record<string, string> = {
    "reconnaissance":         "Reconnaissance",
    "resource-development":   "Resource Development",
    "initial-access":         "Initial Access",
    "execution":              "Execution",
    "persistence":            "Persistence",
    "privilege-escalation":   "Privilege Escalation",
    "defense-evasion":        "Defense Evasion",
    "credential-access":      "Credential Access",
    "discovery":              "Discovery",
    "lateral-movement":       "Lateral Movement",
    "collection":             "Collection",
    "command-and-control":    "C2",
    "exfiltration":           "Exfiltration",
    "impact":                 "Impact",
  };

  const tacticDataRaw = (tacticCoverage || []).map((tc) => {
    const slug = tc.tactic.toLowerCase();
    const label = MITRE_TACTIC_ORDER[slug] ||
      tc.tactic.split("-").map((w: string) => w.charAt(0).toUpperCase() + w.slice(1)).join(" ");
    const order = Object.keys(MITRE_TACTIC_ORDER).indexOf(slug);
    return {
      name: label,
      slug,
      order: order === -1 ? 99 : order,
      coverage: tc.total > 0 ? Math.round(((tc.validated + tc.partial) / tc.total) * 100) : 0,
    };
  });

  // Sort by official MITRE order; include any unknown tactics at end
  const tacticData = tacticDataRaw.sort((a, b) => a.order - b.order);

  const getBarColor = (coverage: number) => {
    if (coverage < 30) return "#ef4444";
    if (coverage < 50) return "#f97316";
    if (coverage < 70) return "#eab308";
    return "#22c55e";
  };

  return (
    <div className="space-y-6">
      {/* Header */}
      <div className="flex flex-wrap items-start justify-between gap-4">
        <div>
          <h1 className="text-2xl font-bold text-white">Executive Dashboard</h1>
          <p className="mt-1 text-sm text-gray-400">
            Red/Blue Team programme coverage and maturity overview
          </p>
        </div>

        {/* Time range filter */}
        <div className="flex items-center gap-1.5 rounded-xl border border-gray-800 bg-gray-900 p-1">
          {TIME_RANGE_OPTIONS.map((opt) => (
            <button
              key={opt.value}
              onClick={() => setTimeRange(opt.value)}
              className={`rounded-lg px-3 py-1.5 text-xs font-medium transition-colors ${
                timeRange === opt.value
                  ? "bg-cyan-600 text-white"
                  : "text-gray-400 hover:text-white"
              }`}
            >
              {opt.label}
            </button>
          ))}
        </div>
      </div>

      {/* Section 1: Score Card + Sub-scores */}
      <div className="grid grid-cols-1 gap-6 lg:grid-cols-4">
        <div className="rounded-xl border border-gray-800 bg-gray-900 p-6 lg:col-span-1 flex flex-col items-center justify-center">
          <ScoreGauge
            score={orgScore?.overall_score ?? 0}
            label="Overall Score"
          />
          <div className="mt-4 grid w-full grid-cols-2 gap-2">
            <div className="rounded-lg bg-gray-800 px-3 py-2 text-center">
              <p className="text-lg font-bold text-white">
                {orgScore?.total_coverage ?? 0}
              </p>
                <p className="text-[10px] text-gray-500 flex items-center justify-center gap-0.5">Coverage<MetricTooltip title="Coverage Score" description="Breadth of attack technique coverage — how many of the known MITRE ATT&CK techniques have been tested and detected. Scale 0–100." position="above" /></p>
            </div>
            <div className="rounded-lg bg-gray-800 px-3 py-2 text-center">
              <p className="text-lg font-bold text-white">
                {orgScore?.detection_maturity ?? 0}
              </p>
              <p className="text-[10px] text-gray-500 flex items-center justify-center gap-0.5">Detection<MetricTooltip title="Detection Score" description="Quality and maturity of detection capabilities — based on detection rules, validated tests and Blue Team confirmation rate. Scale 0–100." position="above" /></p>
            </div>
            <div className="rounded-lg bg-gray-800 px-3 py-2 text-center">
              <p className="text-lg font-bold text-white">
                {orgScore?.critical_coverage ?? 0}
              </p>
              <p className="text-[10px] text-gray-500 flex items-center justify-center gap-0.5">Critical<MetricTooltip title="Critical Coverage Score" description="Coverage specifically for high-risk and critical techniques used by known threat actors targeting your sector. Scale 0–100." position="above" /></p>
            </div>
            <div className="rounded-lg bg-gray-800 px-3 py-2 text-center">
              <p className="text-lg font-bold text-white">
                {orgScore?.response_readiness ?? 0}
              </p>
              <p className="text-[10px] text-gray-500 flex items-center justify-center gap-0.5">Response<MetricTooltip title="Response Readiness Score" description="How quickly and efficiently tests flow through the Red/Blue validation process. High score = fast, smooth validation workflow. Scale 0–100." position="above" /></p>
            </div>
          </div>
        </div>

        {/* Section 2: Trend Chart */}
        <div className="rounded-xl border border-gray-800 bg-gray-900 p-4 lg:col-span-3">
          <h2 className="mb-3 text-sm font-semibold text-gray-300 flex items-center gap-1">
            Score Trend (90 days)
            <MetricTooltip title="Score Trend" description="How the programme maturity score has evolved over the past 90 days, based on completed Red/Blue exercises. An upward trend indicates the testing programme is expanding coverage and improving detection validation." context="Aim for a steady upward trend. Sudden drops may indicate newly discovered technique gaps or reduced test activity." />
          </h2>
          <ResponsiveContainer width="100%" height={220}>
            <LineChart data={scoreHistory || []}>
              <CartesianGrid strokeDasharray="3 3" stroke="#1f2937" />
              <XAxis
                dataKey="date"
                tick={{ fill: "#6b7280", fontSize: 10 }}
                tickFormatter={(val) => {
                  const d = new Date(val);
                  return `${d.getMonth() + 1}/${d.getDate()}`;
                }}
              />
              <YAxis
                domain={[0, 100]}
                tick={{ fill: "#6b7280", fontSize: 10 }}
              />
              <Tooltip
                contentStyle={{
                  backgroundColor: "#111827",
                  border: "1px solid #374151",
                  borderRadius: "8px",
                  fontSize: "12px",
                }}
                labelStyle={{ color: "#9ca3af" }}
              />
              <Line
                type="monotone"
                dataKey="score"
                stroke="#06b6d4"
                strokeWidth={2}
                dot={false}
                name="Score"
              />
            </LineChart>
          </ResponsiveContainer>
        </div>
      </div>

      {/* Section 3: Team Performance */}
      {teamMetrics && (
        <div>
        {timeRange !== "all" && (
          <p className="mb-2 text-xs text-cyan-400/70">
            Operational metrics filtered to: <span className="font-medium text-cyan-400">{rangeOption.label}</span>
          </p>
        )}
        <div className="grid grid-cols-1 gap-4 lg:grid-cols-2">
          {/* Red Team */}
          <div className="rounded-xl border border-gray-800 bg-gray-900 p-4">
            <h2 className="mb-3 flex items-center gap-2 text-sm font-semibold text-red-400">
              <div className="h-2 w-2 rounded-full bg-red-500" />
              Red Team
              <MetricTooltip title="Red Team Performance" description="Metrics for the offensive security team that simulates attacks. Tests Done = completed executions; Avg Time = mean execution duration; Rejection = % of results rejected by leads." context="Lower rejection rate = higher quality test documentation." />
            </h2>
            <div className="grid grid-cols-3 gap-3">
              <div className="rounded-lg bg-gray-800 px-3 py-2 text-center">
                <p className="text-lg font-bold text-white">
                  {teamMetrics.red_team.tests_completed}
                </p>
                <p className="text-[10px] text-gray-500 flex items-center justify-center gap-0.5">Tests Done<MetricTooltip title="Tests Done (Red)" description="Total number of attack simulations completed by Red Team and submitted to Blue Team for evaluation." /></p>
              </div>
              <div className="rounded-lg bg-gray-800 px-3 py-2 text-center">
                <p className="text-lg font-bold text-white">
                  {teamMetrics.red_team.avg_completion_hours != null
                    ? `${teamMetrics.red_team.avg_completion_hours}${(teamMetrics.red_team as any).avg_unit ?? "h"}`
                    : "N/A"}
                </p>
                <p className="text-[10px] text-gray-500 flex items-center justify-center gap-0.5">Avg Time<MetricTooltip title="Avg Execution Time (Red)" description="Average hours Red Team spends executing and documenting each attack simulation." /></p>
              </div>
              <div className="rounded-lg bg-gray-800 px-3 py-2 text-center">
                <p className="text-lg font-bold text-white">
                  {teamMetrics.red_team.rejection_rate}%
                </p>
                <p className="text-[10px] text-gray-500 flex items-center justify-center gap-0.5">Rejection<MetricTooltip title="Rejection Rate (Red)" description="Percentage of Red Team submissions rejected by the Red Lead during validation review. High rejection = quality issues in test documentation." /></p>
              </div>
            </div>
          </div>

          {/* Blue Team */}
          <div className="rounded-xl border border-gray-800 bg-gray-900 p-4">
            <h2 className="mb-3 flex items-center gap-2 text-sm font-semibold text-blue-400">
              <div className="h-2 w-2 rounded-full bg-blue-500" />
              Blue Team
              <MetricTooltip title="Blue Team Performance" description="Metrics for the defensive security team that analyses attacks and validates detections. Tests Done = evaluations completed; Avg Time = mean evaluation duration; Rejection = % rejected by Blue Lead." context="Lower rejection rate = consistent, high-quality detection analysis." />
            </h2>
            <div className="grid grid-cols-3 gap-3">
              <div className="rounded-lg bg-gray-800 px-3 py-2 text-center">
                <p className="text-lg font-bold text-white">
                  {teamMetrics.blue_team.tests_completed}
                </p>
                <p className="text-[10px] text-gray-500 flex items-center justify-center gap-0.5">Tests Done<MetricTooltip title="Tests Done (Blue)" description="Total attack simulations evaluated by Blue Team — verified whether security controls detected or missed the attack." /></p>
              </div>
              <div className="rounded-lg bg-gray-800 px-3 py-2 text-center">
                <p className="text-lg font-bold text-white">
                  {teamMetrics.blue_team.avg_completion_hours != null
                    ? `${teamMetrics.blue_team.avg_completion_hours}${(teamMetrics.blue_team as any).avg_unit ?? "h"}`
                    : "N/A"}
                </p>
                <p className="text-[10px] text-gray-500 flex items-center justify-center gap-0.5">Avg Time<MetricTooltip title="Avg Evaluation Time (Blue)" description="Average time Blue Team spends actively evaluating a test — from 'Start Evaluation' click to validation approved. Paused time is excluded." context="⚠ Does NOT include queue wait time (time the test sat unattended before Blue picked it up). Only measures active work time when available." /></p>
              </div>
              <div className="rounded-lg bg-gray-800 px-3 py-2 text-center">
                <p className="text-lg font-bold text-white">
                  {teamMetrics.blue_team.rejection_rate}%
                </p>
                <p className="text-[10px] text-gray-500 flex items-center justify-center gap-0.5">Rejection<MetricTooltip title="Rejection Rate (Blue)" description="Percentage of Blue Team evaluations rejected by the Blue Lead. May indicate unclear detection documentation or disagreement on results." /></p>
              </div>
            </div>
          </div>
        </div>
        </div>
      )}

      {/* Section 4: Threat Actor Exposure vs Detection Strength */}
      {(() => {
        const allActors = [...(threatActors?.items || [])].filter(
          (a) => a.technique_count > 0,
        );

        // Most vulnerable: highest uncovered technique count
        const mostVulnerable = [...allActors]
          .sort((a, b) => {
            const ua = a.technique_count * (1 - a.coverage_pct / 100);
            const ub = b.technique_count * (1 - b.coverage_pct / 100);
            return ub !== ua ? ub - ua : b.technique_count - a.technique_count;
          })
          .slice(0, 5);

        // Best covered: highest coverage_pct with ≥1 technique
        const bestCovered = [...allActors]
          .filter((a) => a.coverage_pct > 0)
          .sort((a, b) =>
            b.coverage_pct !== a.coverage_pct
              ? b.coverage_pct - a.coverage_pct
              : b.technique_count - a.technique_count,
          )
          .slice(0, 5);

        const ActorRow = ({
          actor,
          idx,
          side,
        }: {
          actor: (typeof allActors)[0];
          idx: number;
          side: "risk" | "strength";
        }) => {
          const uncovered = Math.round(
            actor.technique_count * (1 - actor.coverage_pct / 100),
          );
          return (
            <div
              className="flex items-center gap-3 rounded-lg bg-gray-800/50 p-2.5 cursor-pointer hover:bg-gray-800 transition-colors"
              onClick={() => navigate(`/threat-actors/${actor.id}`)}
            >
              <div
                className={`flex h-6 w-6 shrink-0 items-center justify-center rounded-full text-[10px] font-bold ${
                  side === "risk"
                    ? idx === 0
                      ? "bg-red-500/20 text-red-400"
                      : idx === 1
                      ? "bg-orange-500/20 text-orange-400"
                      : "bg-yellow-500/20 text-yellow-400"
                    : "bg-green-500/20 text-green-400"
                }`}
              >
                {idx + 1}
              </div>
              <div className="flex-1 min-w-0">
                <p className="text-xs font-medium text-white truncate">
                  {actor.name}
                </p>
                <p className="text-[10px] text-gray-500 truncate">
                  {side === "risk"
                    ? `${uncovered} uncovered / ${actor.technique_count} techniques`
                    : `${actor.technique_count} techniques covered`}
                </p>
              </div>
              <div className="flex items-center gap-1.5 shrink-0">
                <div className="w-16 h-1.5 rounded-full bg-gray-700 overflow-hidden">
                  <div
                    className="h-full rounded-full transition-all"
                    style={{
                      width: `${actor.coverage_pct}%`,
                      backgroundColor:
                        actor.coverage_pct > 70
                          ? "#22c55e"
                          : actor.coverage_pct > 40
                          ? "#eab308"
                          : "#ef4444",
                    }}
                  />
                </div>
                <span className="w-8 text-right text-[10px] font-medium text-gray-300 tabular-nums">
                  {actor.coverage_pct.toFixed(0)}%
                </span>
              </div>
            </div>
          );
        };

        return (
          <div className="grid gap-4 lg:grid-cols-2">
            {/* Left: highest exposure */}
            <div className="rounded-xl border border-red-900/30 bg-gray-900 p-4">
              <h2 className="mb-1 text-sm font-semibold text-red-400 flex items-center gap-1">
                ⚠ Highest Exposure
                <MetricTooltip
                  title="Highest Exposure Threat Actors"
                  description="Adversary groups whose attack techniques we are LEAST prepared to detect. We have the most uncovered techniques for these groups."
                  context="We are most vulnerable to these groups. Prioritise testing their TTPs urgently."
                />
              </h2>
              <p className="mb-3 text-[10px] text-gray-500 leading-snug">
                These threat actors use techniques we <span className="text-red-400 font-medium">cannot currently detect</span>.
                If they targeted us today, most of their attacks would go unnoticed.
              </p>
              <div className="space-y-1.5">
                {mostVulnerable.map((actor, idx) => (
                  <ActorRow key={actor.id} actor={actor} idx={idx} side="risk" />
                ))}
                {mostVulnerable.length === 0 && (
                  <p className="py-4 text-center text-xs text-gray-500">No data available</p>
                )}
              </div>
            </div>

            {/* Right: best detection capability */}
            <div className="rounded-xl border border-green-900/30 bg-gray-900 p-4">
              <h2 className="mb-1 text-sm font-semibold text-green-400 flex items-center gap-1">
                ✅ Strongest Detection
                <MetricTooltip
                  title="Strongest Detection Capability"
                  description="Adversary groups whose attack techniques we are BEST prepared to detect. High coverage means our Blue Team can identify most of their TTPs."
                  context="These are our strengths. If these groups attacked us, we would likely detect them."
                />
              </h2>
              <p className="mb-3 text-[10px] text-gray-500 leading-snug">
                For these threat actors we have <span className="text-green-400 font-medium">strong detection coverage</span>.
                Their techniques are well tested and our Blue Team would likely identify an intrusion.
              </p>
              <div className="space-y-1.5">
                {bestCovered.map((actor, idx) => (
                  <ActorRow key={actor.id} actor={actor} idx={idx} side="strength" />
                ))}
                {bestCovered.length === 0 && (
                  <p className="py-4 text-center text-xs text-gray-500">No coverage data yet — run tests to populate</p>
                )}
              </div>
            </div>
          </div>
        );
      })()}

      {/* Section 4: Operational KPIs */}
      <div>
      <div className="mb-2 flex items-center justify-between">
        <h2 className="text-sm font-semibold text-gray-400 uppercase tracking-wider">Operational KPIs</h2>
        {timeRange !== "all" && (
          <span className="rounded-full border border-cyan-500/30 bg-cyan-500/10 px-2.5 py-0.5 text-xs text-cyan-400">
            {rangeOption.label}
          </span>
        )}
      </div>
      <div className="grid grid-cols-2 gap-4 lg:grid-cols-4">
        <KPICard
          label="MTTD"
          value={opMetrics?.mttd?.mean_hours != null ? opMetrics.mttd.mean_hours : "N/A"}
          unit={opMetrics?.mttd?.mean_hours != null ? (opMetrics.mttd.mean_hours < 1 ? "min" : "hrs") : undefined}
          tooltip={{ description: "Mean Time To Detect — average time from attack execution start to Blue Team receiving the test. Shows Red Team execution efficiency.", context: "Lower is better." }}
        />
        <KPICard
          label="MTTR"
          value={opMetrics?.mttr?.mean_hours != null ? opMetrics.mttr.mean_hours : "N/A"}
          unit={opMetrics?.mttr?.mean_hours != null ? (opMetrics.mttr.mean_hours < 1 ? "min" : "hrs") : undefined}
          tooltip={{ description: "Mean Time To Respond — average time from Red Team attack start to full validation complete. Measures the total security test cycle time end-to-end.", context: "Lower is better. Long MTTR may indicate bottlenecks in the review pipeline." }}
        />
        <KPICard
          label="Detection Efficacy"
          value={opMetrics?.detection_efficacy?.percentage ?? 0}
          unit="%"
          tooltip={{ description: "Percentage of executed attacks that Blue Team successfully detected. 100% means every simulated attack triggered an alert.", context: "Higher is better. Below 60% indicates significant detection gaps." }}
        />
        <KPICard
          label="Pipeline Conversion"
          value={opMetrics?.validation_throughput?.conversion_rate ?? opMetrics?.validation_throughput?.tests_per_week ?? 0}
          unit="%"
          trend={opMetrics?.validation_throughput?.trend}
          tooltip={{ description: "Percentage of tests that have entered the validation phase and been successfully approved. Formula: Validated ÷ (Validated + Rejected + In Review) × 100.", context: "100% = all reviewed tests approved. < 60% = quality or process issues. High backlog (many In Review) lowers this score." }}
        />
      </div>
      </div>

      {/* Section 5: Coverage by Tactic */}
      <div className="rounded-xl border border-gray-800 bg-gray-900 p-4">
        <h2 className="mb-3 text-sm font-semibold text-gray-300 flex items-center gap-1">
          Coverage by Tactic
          <MetricTooltip title="Coverage by Tactic" description="How well each MITRE ATT&CK tactic (attack phase) is covered by validated tests. Tactics represent different stages of an attack, from Initial Access to Impact." context="Red bars (low coverage) are highest priority. Focus testing on those tactics first." />
        </h2>
        <ResponsiveContainer width="100%" height={260}>
          <BarChart
            data={tacticData}
            margin={{ top: 8, right: 8, bottom: 64, left: 8 }}
            barCategoryGap="20%"
          >
            <CartesianGrid strokeDasharray="3 3" stroke="#1f2937" vertical={false} />
            <XAxis
              dataKey="name"
              tick={{ fill: "#9ca3af", fontSize: 10 }}
              angle={-45}
              textAnchor="end"
              interval={0}
            />
            <YAxis
              domain={[0, 100]}
              tick={{ fill: "#6b7280", fontSize: 10 }}
              tickFormatter={(v) => `${v}%`}
              width={36}
            />
            <Tooltip
              contentStyle={{
                backgroundColor: "#111827",
                border: "1px solid #374151",
                borderRadius: "8px",
                fontSize: "12px",
              }}
              formatter={(value: number) => [`${value}%`, "Coverage"]}
            />
            <Bar dataKey="coverage" radius={[4, 4, 0, 0]}>
              {tacticData.map((entry, index) => (
                <Cell
                  key={`cell-${index}`}
                  fill={getBarColor(entry.coverage)}
                />
              ))}
            </Bar>
          </BarChart>
        </ResponsiveContainer>
      </div>

      {/* Section 6: Critical Gaps */}
      <div className="rounded-xl border border-gray-800 bg-gray-900 p-4">
        <div className="mb-3 flex items-center justify-between">
          <h2 className="text-sm font-semibold text-gray-300 flex items-center gap-1">
            Critical Gaps — Top 10 by Risk Priority
            <MetricTooltip title="Critical Gaps" description="The 10 most dangerous attack techniques with no detection coverage, ranked by a composite risk score based on: how many threat actors use this technique, recent threat intelligence, and test history." context="These are your highest-priority gaps — real adversaries actively use these techniques and you cannot currently detect them." />
          </h2>
          {canComputeRisk && (
            <button
              onClick={() => computeMutation.mutate()}
              disabled={computeMutation.isPending}
              className="flex items-center gap-1.5 rounded-lg border border-gray-700 bg-gray-800 px-2.5 py-1 text-xs text-gray-400 hover:text-cyan-400 hover:border-cyan-500/30 disabled:opacity-50 transition-colors"
              title="Recompute risk scores"
            >
              {computeMutation.isPending ? (
                <Loader2 className="h-3 w-3 animate-spin" />
              ) : (
                <RefreshCw className="h-3 w-3" />
              )}
              {computeMutation.isPending ? "Computing…" : "Refresh scores"}
            </button>
          )}
        </div>
        <div className="overflow-x-auto">
          <table className="w-full text-sm">
            <thead>
              <tr className="border-b border-gray-800 text-left text-xs text-gray-500">
                <th className="pb-2 pr-3">#</th>
                <th className="pb-2 pr-4">Risk</th>
                <th className="pb-2 pr-4">MITRE ID</th>
                <th className="pb-2 pr-4">Name</th>
                <th className="pb-2 pr-4">Tactic</th>
                <th className="pb-2 pr-4">Status</th>
              </tr>
            </thead>
            <tbody>
              {criticalGaps.map((tech, idx) => {
                const profile = riskByTechniqueId.get(tech.id);
                const riskScore = profile?.risk_score;
                const riskLevel = profile?.risk_level;
                const riskLevelColors: Record<string, string> = {
                  critical: "bg-red-500/20 text-red-400 border border-red-500/30",
                  high:     "bg-orange-500/20 text-orange-400 border border-orange-500/30",
                  medium:   "bg-yellow-500/20 text-yellow-400 border border-yellow-500/30",
                  low:      "bg-blue-500/20 text-blue-400 border border-blue-500/30",
                  info:     "bg-gray-500/20 text-gray-400 border border-gray-500/30",
                };
                const scoreColor =
                  riskScore === undefined ? "text-gray-600"
                  : riskScore >= 75 ? "text-red-400"
                  : riskScore >= 50 ? "text-orange-400"
                  : riskScore >= 25 ? "text-yellow-400"
                  : "text-blue-400";

                return (
                  <tr
                    key={tech.mitre_id}
                    className="border-b border-gray-800/50 cursor-pointer hover:bg-gray-800/30"
                    onClick={() => navigate(`/techniques/${tech.mitre_id}`)}
                  >
                    <td className="py-2 pr-3 text-xs text-gray-600 font-mono">{idx + 1}</td>
                    <td className="py-2 pr-4">
                      <div className="flex items-center gap-2">
                        <span className={`text-sm font-bold tabular-nums ${scoreColor}`}>
                          {riskScore !== undefined ? Math.round(riskScore) : "—"}
                        </span>
                        {riskLevel && (
                          <span
                            className={`hidden sm:inline-block rounded-full px-1.5 py-0.5 text-[9px] font-semibold uppercase tracking-wide ${
                              riskLevelColors[riskLevel] || riskLevelColors.info
                            }`}
                          >
                            {riskLevel}
                          </span>
                        )}
                      </div>
                    </td>
                    <td className="py-2 pr-4 font-mono text-xs text-cyan-400">
                      {tech.mitre_id}
                    </td>
                    <td className="py-2 pr-4 text-gray-300 truncate max-w-[180px]">
                      {tech.name}
                    </td>
                    <td className="py-2 pr-4 text-gray-500 text-xs">
                      {tech.tactic
                        ?.split(",")[0]
                        .trim()
                        .split("-")
                        .map((w: string) => w.charAt(0).toUpperCase() + w.slice(1))
                        .join(" ")}
                    </td>
                    <td className="py-2 pr-4">
                      <span
                        className={`inline-block rounded-full px-2 py-0.5 text-[10px] font-medium ${
                          tech.status_global === "not_covered"
                            ? "bg-red-500/10 text-red-400"
                            : "bg-gray-500/10 text-gray-400"
                        }`}
                      >
                        {tech.status_global?.replace(/_/g, " ")}
                      </span>
                    </td>
                  </tr>
                );
              })}
              {criticalGaps.length === 0 && (
                <tr>
                  <td colSpan={6} className="py-4 text-center text-gray-500">
                    No critical gaps found
                  </td>
                </tr>
              )}
            </tbody>
          </table>
        </div>
      </div>

    </div>
  );
}
