import { useQuery, useQueryClient } from "@tanstack/react-query";
import { useNavigate } from "react-router-dom";
import {
  Shield,
  CheckCircle,
  AlertTriangle,
  XCircle,
  Clock,
  HelpCircle,
  Percent,
  Loader2,
  AlertCircle,
  Play,
  Eye,
  Users,
  TrendingUp,
  ArrowRight,
  RefreshCw,
} from "lucide-react";
import {
  LineChart,
  Line,
  XAxis,
  YAxis,
  CartesianGrid,
  Tooltip,
  ResponsiveContainer,
  Legend,
} from "recharts";
import {
  getCoverageSummary,
  getCoverageByTactic,
  getTestPipeline,
  getTeamActivity,
  getValidationRate,
  getRecentTests,
  type TestPipelineCounts,
  type TeamActivityItem,
  type ValidationRateItem,
  type RecentTestItem,
} from "../api/metrics";
import { getCoverageEvolution } from "../api/snapshots";
import CoverageSummaryCard from "../components/CoverageSummaryCard";
import TacticCoverageChart from "../components/TacticCoverageChart";
import MetricTooltip from "../components/MetricTooltip";
import type { TestState } from "../types/models";

/* ── Badge colours (reused from TestsPage) ─────────────────────────── */

const testStateBadgeColors: Record<string, 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<string, 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",
};

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

export default function DashboardPage() {
  const navigate = useNavigate();

  // Existing coverage queries
  const {
    data: summary,
    isLoading: summaryLoading,
    error: summaryError,
  } = useQuery({
    queryKey: ["metrics", "summary"],
    queryFn: getCoverageSummary,
  });

  const {
    data: tactics,
    isLoading: tacticsLoading,
    error: tacticsError,
  } = useQuery({
    queryKey: ["metrics", "by-tactic"],
    queryFn: getCoverageByTactic,
  });

  const queryClient = useQueryClient();

  // Refresh all V2 metric widgets manually
  const refreshMetrics = () => {
    queryClient.invalidateQueries({ queryKey: ["metrics", "test-pipeline"] });
    queryClient.invalidateQueries({ queryKey: ["metrics", "team-activity"] });
    queryClient.invalidateQueries({ queryKey: ["metrics", "validation-rate"] });
    queryClient.invalidateQueries({ queryKey: ["metrics", "recent-tests"] });
  };

  // V2 queries — retry:3 + refetchOnMount:'always' so queries re-run even
  // when cached in error state (happens if backend was still starting on first load)
  const { data: pipeline, isLoading: pipelineLoading, isError: pipelineError, isFetching: pipelineFetching } = useQuery({
    queryKey: ["metrics", "test-pipeline"],
    queryFn: getTestPipeline,
    retry: 3,
    refetchOnMount: "always",
    gcTime: 0,
  });

  const { data: teamActivity, isLoading: teamLoading, isError: teamError } = useQuery({
    queryKey: ["metrics", "team-activity"],
    queryFn: getTeamActivity,
    retry: 3,
    refetchOnMount: "always",
    gcTime: 0,
  });

  const { data: validationRates, isLoading: validationLoading, isError: validationError } = useQuery({
    queryKey: ["metrics", "validation-rate"],
    queryFn: getValidationRate,
    retry: 3,
    refetchOnMount: "always",
    gcTime: 0,
  });

  const { data: recentTests, isLoading: recentLoading, isError: recentError } = useQuery({
    queryKey: ["metrics", "recent-tests"],
    queryFn: getRecentTests,
    retry: 3,
    refetchOnMount: "always",
    gcTime: 0,
  });

  const { data: coverageEvolution, isLoading: evolutionLoading } = useQuery({
    queryKey: ["snapshots", "evolution", 6],
    queryFn: () => getCoverageEvolution(6),
  });

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

  if (summaryError || tacticsError) {
    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 metrics</p>
        <p className="text-sm text-gray-500">
          {summaryError?.message || tacticsError?.message || "Unknown error"}
        </p>
      </div>
    );
  }

  return (
    <div className="space-y-6">
      {/* Header */}
      <div className="flex items-center justify-between">
        <div>
          <h1 className="text-2xl font-bold text-white">Dashboard</h1>
          <p className="mt-1 text-sm text-gray-400">
            MITRE ATT&CK coverage overview
          </p>
        </div>
        <div className="flex items-center gap-3">
          {/* Manual refresh for metric widgets */}
          <button
            onClick={refreshMetrics}
            disabled={pipelineLoading || pipelineFetching}
            className="flex items-center gap-1.5 rounded-lg border border-gray-700 bg-gray-800 px-3 py-2 text-xs text-gray-400 hover:bg-gray-700 hover:text-white transition-colors disabled:opacity-50"
            title="Refresh dashboard metrics"
          >
            <RefreshCw className={`h-3.5 w-3.5 ${pipelineFetching ? "animate-spin" : ""}`} />
            Refresh
          </button>
          {summary && (
          <div className="flex items-center gap-2 rounded-lg border border-cyan-500/30 bg-cyan-500/10 px-4 py-2">
            <Percent className="h-5 w-5 text-cyan-400" />
            <span className="text-lg font-bold text-cyan-400">
              {summary.coverage_percentage.toFixed(1)}%
            </span>
            <span className="text-sm text-gray-400">Coverage</span>
          </div>
          )}
        </div>
      </div>

      {/* Summary Cards */}
      {summary && (
        <div className="grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-6">
          <CoverageSummaryCard
            title="Total Techniques"
            value={summary.total_techniques}
            icon={<Shield className="h-6 w-6 text-cyan-400" />}
            colorClass="text-cyan-400"
            bgClass="bg-gray-900"
            tooltip={{ description: "Total number of MITRE ATT&CK attack techniques tracked in the platform. This is the full universe of known attack methods we measure coverage against.", context: "A higher total means broader threat visibility." }}
          />
          <CoverageSummaryCard
            title="Validated"
            value={summary.validated}
            total={summary.total_techniques}
            icon={<CheckCircle className="h-6 w-6 text-green-400" />}
            colorClass="text-green-400"
            bgClass="bg-green-950/20"
            tooltip={{ description: "Techniques confirmed as detectable by Blue Team with ≥2 successful tests. These attacks would be caught if a real adversary used them.", context: "Goal: maximise this number. Higher = stronger defence." }}
          />
          <CoverageSummaryCard
            title="Partial"
            value={summary.partial}
            total={summary.total_techniques}
            icon={<AlertTriangle className="h-6 w-6 text-yellow-400" />}
            colorClass="text-yellow-400"
            bgClass="bg-yellow-950/20"
            tooltip={{ description: "Techniques with incomplete coverage: only 1 validated test, mixed detection results, or tests still in progress.", context: "These need attention — detection is not yet reliable." }}
          />
          <CoverageSummaryCard
            title="In Progress"
            value={summary.in_progress}
            total={summary.total_techniques}
            icon={<Clock className="h-6 w-6 text-blue-400" />}
            colorClass="text-blue-400"
            bgClass="bg-blue-950/20"
            tooltip={{ description: "Techniques with active tests currently being executed or awaiting review by leads. Not yet counted as covered.", context: "Indicates active testing work underway." }}
          />
          <CoverageSummaryCard
            title="Not Covered"
            value={summary.not_covered}
            total={summary.total_techniques}
            icon={<XCircle className="h-6 w-6 text-red-400" />}
            colorClass="text-red-400"
            bgClass="bg-red-950/20"
            tooltip={{ description: "Techniques that were tested but Blue Team failed to detect the attack. These are confirmed security gaps — a real attack would go unnoticed.", context: "High priority: invest in detection rules and monitoring." }}
          />
          <CoverageSummaryCard
            title="Not Evaluated"
            value={summary.not_evaluated}
            total={summary.total_techniques}
            icon={<HelpCircle className="h-6 w-6 text-gray-400" />}
            colorClass="text-gray-400"
            bgClass="bg-gray-900"
            tooltip={{ description: "Techniques with no tests created yet. We have no data on whether these attacks would be detected or not.", context: "Unknown risk — prioritise testing the most common ones." }}
          />
        </div>
      )}

      {/* Coverage evolution (snapshots) */}
      <div className="rounded-xl border border-gray-800 bg-gray-900 p-6">
        <h2 className="mb-4 text-lg font-semibold text-white flex items-center gap-2">
          <TrendingUp className="h-5 w-5 text-cyan-400" />
          Coverage Evolution (6 months)
          <MetricTooltip title="Coverage Evolution" description="How ATT&CK coverage % and programme score have changed over the last 6 months based on completed exercises. An upward trend means the testing programme is maturing and technique coverage is expanding." context="Programme Score reflects depth of validated testing; Coverage % reflects breadth of techniques exercised." />
        </h2>
        {evolutionLoading ? (
          <div className="flex h-48 items-center justify-center">
            <Loader2 className="h-6 w-6 animate-spin text-cyan-400" />
          </div>
        ) : coverageEvolution && coverageEvolution.length > 0 ? (
          <ResponsiveContainer width="100%" height={240}>
            <LineChart data={coverageEvolution}>
              <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" }}
              />
              <Legend />
              <Line
                type="monotone"
                dataKey="org_score"
                stroke="#06b6d4"
                strokeWidth={2}
                dot={{ r: 3 }}
                name="Org score"
              />
              <Line
                type="monotone"
                dataKey="coverage_pct"
                stroke="#22c55e"
                strokeWidth={2}
                dot={{ r: 3 }}
                name="Coverage %"
              />
            </LineChart>
          </ResponsiveContainer>
        ) : (
          <p className="text-sm text-gray-500 py-8 text-center">
            No snapshots yet. Weekly snapshots populate this chart automatically.
          </p>
        )}
      </div>

      {/* ── V2 Section: Test Pipeline ────────────────────────────────── */}
      <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 flex items-center gap-2">
            <TrendingUp className="h-5 w-5 text-cyan-400" />
            Test Pipeline
            <MetricTooltip title="Test Pipeline" description="Shows how many security tests are at each stage of the Red/Blue workflow: Draft → Red Executing → Blue Evaluating → In Review → Validated / Rejected." context="A healthy pipeline has tests flowing through to Validated. Backlogs in any stage indicate bottlenecks." />
          </h2>
          <button
            onClick={() => navigate("/tests")}
            className="text-sm text-cyan-400 hover:underline flex items-center gap-1"
          >
            View all tests <ArrowRight className="h-3.5 w-3.5" />
          </button>
        </div>

        {pipelineLoading ? (
          <div className="flex items-center justify-center py-8">
            <Loader2 className="h-6 w-6 animate-spin text-cyan-400" />
          </div>
        ) : pipelineError ? (
          <p className="py-8 text-center text-sm text-gray-500">Could not load pipeline data.</p>
        ) : pipeline ? (
          <PipelineFunnel pipeline={pipeline} />
        ) : null}
      </div>

      {/* ── V2 Section: Team Activity + Validation Rate ──────────────── */}
      <div className="grid gap-6 lg:grid-cols-2">
        {/* Team Activity */}
        <div className="rounded-xl border border-gray-800 bg-gray-900 p-6">
          <h2 className="mb-4 text-lg font-semibold text-white flex items-center gap-2">
            <Users className="h-5 w-5 text-cyan-400" />
            Team Activity
            <MetricTooltip title="Team Activity" description="Shows Red Team (attackers) and Blue Team (defenders) productivity. 'Completed' = tests passed through their phase; 'Pending' = tests waiting for action." context="Low completion rate may indicate resource constraints or bottlenecks." />
          </h2>

          {teamLoading ? (
            <div className="flex items-center justify-center py-8">
              <Loader2 className="h-6 w-6 animate-spin text-cyan-400" />
            </div>
          ) : teamError ? (
            <p className="py-8 text-center text-sm text-gray-500">Could not load team activity.</p>
          ) : teamActivity ? (
            <div className="space-y-4">
              {teamActivity.map((team: TeamActivityItem) => {
                const isRed = team.team.toLowerCase().includes("red");
                const total = team.tests_completed + team.tests_pending;
                const pct = total > 0 ? (team.tests_completed / total) * 100 : 0;
                return (
                  <div key={team.team} className="rounded-lg border border-gray-800 bg-gray-800/50 p-4">
                    <div className="flex items-center justify-between mb-3">
                      <div className="flex items-center gap-2">
                        <div
                          className={`h-3 w-3 rounded-full ${
                            isRed ? "bg-red-500" : "bg-blue-500"
                          }`}
                        />
                        <span className="font-medium text-white">{team.team}</span>
                      </div>
                      <span className="text-sm text-gray-400">
                        {team.tests_completed} completed / {team.tests_pending} pending
                      </span>
                    </div>
                    <div className="h-2 rounded-full bg-gray-700 overflow-hidden">
                      <div
                        className={`h-full rounded-full transition-all ${
                          isRed ? "bg-red-500" : "bg-blue-500"
                        }`}
                        style={{ width: `${pct}%` }}
                      />
                    </div>
                    <p className="mt-1 text-xs text-gray-500">
                      {pct.toFixed(0)}% completion rate
                    </p>
                  </div>
                );
              })}
            </div>
          ) : null}
        </div>

        {/* Validation Rate */}
        <div className="rounded-xl border border-gray-800 bg-gray-900 p-6">
          <h2 className="mb-4 text-lg font-semibold text-white flex items-center gap-2">
            <CheckCircle className="h-5 w-5 text-cyan-400" />
            Validation Rate
            <MetricTooltip title="Validation Rate" description="How many test results Red Lead and Blue Lead have reviewed and approved vs rejected. High approval = good quality tests and clear detection results." context="High rejection rate may indicate unclear test procedures or disagreement on results." />
          </h2>

          {validationLoading ? (
            <div className="flex items-center justify-center py-8">
              <Loader2 className="h-6 w-6 animate-spin text-cyan-400" />
            </div>
          ) : validationError ? (
            <p className="py-8 text-center text-sm text-gray-500">Could not load validation data.</p>
          ) : validationRates ? (
            <div className="space-y-4">
              {validationRates.map((rate: ValidationRateItem) => {
                const isRed = rate.role === "red_lead";
                return (
                  <div key={rate.role} className="rounded-lg border border-gray-800 bg-gray-800/50 p-4">
                    <div className="flex items-center justify-between mb-3">
                      <div className="flex items-center gap-2">
                        <div
                          className={`h-3 w-3 rounded-full ${
                            isRed ? "bg-red-500" : "bg-blue-500"
                          }`}
                        />
                        <span className="font-medium text-white">
                          {isRed ? "Red Lead" : "Blue Lead"}
                        </span>
                      </div>
                      <span className="text-sm text-gray-400">
                        {rate.total_reviewed} reviewed
                      </span>
                    </div>
                    <div className="flex gap-4 text-sm">
                      <div className="flex items-center gap-1">
                        <CheckCircle className="h-3.5 w-3.5 text-green-400" />
                        <span className="text-green-400">{rate.approved} approved</span>
                      </div>
                      <div className="flex items-center gap-1">
                        <XCircle className="h-3.5 w-3.5 text-red-400" />
                        <span className="text-red-400">{rate.rejected} rejected</span>
                      </div>
                    </div>
                    <div className="mt-3 h-2 rounded-full bg-gray-700 overflow-hidden">
                      <div
                        className="h-full rounded-full bg-green-500 transition-all"
                        style={{ width: `${rate.approval_rate}%` }}
                      />
                    </div>
                    <p className="mt-1 text-xs text-gray-500">
                      {rate.approval_rate}% approval rate
                    </p>
                  </div>
                );
              })}
            </div>
          ) : null}
        </div>
      </div>

      {/* ── V2 Section: Recent Tests ─────────────────────────────────── */}
      <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">Recent Tests</h2>
          <button
            onClick={() => navigate("/tests")}
            className="text-sm text-cyan-400 hover:underline flex items-center gap-1"
          >
            View all <ArrowRight className="h-3.5 w-3.5" />
          </button>
        </div>

        {recentLoading ? (
          <div className="flex items-center justify-center py-8">
            <Loader2 className="h-6 w-6 animate-spin text-cyan-400" />
          </div>
        ) : recentError ? (
          <p className="py-8 text-center text-sm text-gray-500">Could not load recent tests — refresh the page.</p>
        ) : recentTests && recentTests.length > 0 ? (
          <div className="overflow-x-auto">
            <table className="w-full text-left text-sm">
              <thead>
                <tr className="border-b border-gray-800">
                  <th className="pb-3 pr-4 font-medium text-gray-400">Name</th>
                  <th className="pb-3 px-4 font-medium text-gray-400">Technique</th>
                  <th className="pb-3 px-4 font-medium text-gray-400">State</th>
                  <th className="pb-3 pl-4 font-medium text-gray-400">Created</th>
                </tr>
              </thead>
              <tbody>
                {recentTests.map((t: RecentTestItem) => (
                  <tr
                    key={t.id}
                    className="border-b border-gray-800/50 hover:bg-gray-800/30 transition-colors cursor-pointer"
                    onClick={() => navigate(`/tests/${t.id}`)}
                  >
                    <td className="py-3 pr-4 font-medium text-gray-200">{t.name}</td>
                    <td className="py-3 px-4">
                      {t.technique_mitre_id ? (
                        <span className="font-mono text-xs text-cyan-400">
                          {t.technique_mitre_id}
                        </span>
                      ) : (
                        <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[t.state] || "bg-gray-800 text-gray-400 border-gray-600"
                        }`}
                      >
                        {testStateLabels[t.state] || t.state}
                      </span>
                    </td>
                    <td className="py-3 pl-4 text-gray-400 text-xs">
                      {t.created_at
                        ? new Date(t.created_at).toLocaleDateString("en-US", {
                            month: "short",
                            day: "numeric",
                          })
                        : "-"}
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        ) : (
          <div className="py-8 text-center text-gray-400">
            No tests created yet.
          </div>
        )}
      </div>

      {/* Tactic Coverage Table (original V1) */}
      {tactics && <TacticCoverageChart data={tactics} />}
    </div>
  );
}

/* ── Pipeline Funnel Sub-component ─────────────────────────────────── */

function PipelineFunnel({ pipeline }: { pipeline: TestPipelineCounts }) {
  const stages: { key: keyof TestPipelineCounts; label: string; color: string; icon: React.ReactNode }[] = [
    { key: "draft", label: "Draft", color: "bg-gray-600", icon: <Clock className="h-4 w-4 text-gray-400" /> },
    { key: "red_executing", label: "Red Executing", color: "bg-orange-500", icon: <Play className="h-4 w-4 text-orange-400" /> },
    { key: "blue_evaluating", label: "Blue Evaluating", color: "bg-indigo-500", icon: <Shield className="h-4 w-4 text-indigo-400" /> },
    { key: "in_review", label: "In Review", color: "bg-blue-500", icon: <Eye className="h-4 w-4 text-blue-400" /> },
    { key: "validated", label: "Validated", color: "bg-green-500", icon: <CheckCircle className="h-4 w-4 text-green-400" /> },
    { key: "rejected", label: "Rejected", color: "bg-red-500", icon: <XCircle className="h-4 w-4 text-red-400" /> },
  ];

  const maxCount = Math.max(...stages.map((s) => pipeline[s.key] as number), 1);

  return (
    <div className="space-y-3">
      {stages.map((stage) => {
        const count = pipeline[stage.key] as number;
        const pct = (count / maxCount) * 100;
        return (
          <div key={stage.key} className="flex items-center gap-3">
            <div className="flex items-center gap-2 w-36 shrink-0">
              {stage.icon}
              <span className="text-sm text-gray-300 truncate">{stage.label}</span>
            </div>
            <div className="flex-1 h-6 rounded bg-gray-800 overflow-hidden">
              <div
                className={`h-full rounded ${stage.color} transition-all flex items-center justify-end px-2`}
                style={{ width: `${Math.max(pct, count > 0 ? 8 : 0)}%` }}
              >
                {count > 0 && (
                  <span className="text-xs font-medium text-white">{count}</span>
                )}
              </div>
            </div>
            <span className="text-sm font-mono text-gray-400 w-8 text-right">{count}</span>
          </div>
        );
      })}
      <div className="pt-2 border-t border-gray-800 flex justify-between text-sm">
        <span className="text-gray-400">Total tests</span>
        <span className="font-medium text-white">{pipeline.total}</span>
      </div>
    </div>
  );
}
