import { useState } from "react";
import { useParams, useNavigate } from "react-router-dom";
import MarkdownText from "../components/MarkdownText";
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
import {
  Loader2,
  AlertCircle,
  ArrowLeft,
  Play,
  CheckCircle,
  Target,
  Plus,
  Trash2,
  Zap,
  Calendar,
  Clock,
  Repeat,
  History,
} from "lucide-react";
import {
  getCampaign,
  completeCampaign,
  deleteCampaign,
  removeTestFromCampaign,
  scheduleCampaign,
  getCampaignHistory,
  submitCampaignForApproval,
  approveCampaign,
  rejectCampaign,
  listCampaignModificationRequests,
  approveModificationRequest,
  rejectModificationRequest,
  getCampaignTimeline,
  type Campaign,
  type CampaignHistoryEntry,
} from "../api/campaigns";
import { useAuth } from "../context/AuthContext";
import CampaignTimeline from "../components/CampaignTimeline";
import CampaignAuditTimeline from "../components/CampaignAuditTimeline";
import JiraLinkPanel from "../components/JiraLinkPanel";
import CampaignTimingPanel from "../components/CampaignTimingPanel";
import AddTestToCampaignModal from "../components/AddTestToCampaignModal";
import RequestCampaignModificationModal from "../components/RequestCampaignModificationModal";

const statusColors: Record<string, string> = {
  draft: "bg-gray-800/50 text-gray-400 border-gray-600/30",
  active: "bg-cyan-900/50 text-cyan-400 border-cyan-500/30",
  completed: "bg-green-900/50 text-green-400 border-green-500/30",
  archived: "bg-gray-800/50 text-gray-500 border-gray-700/30",
};

const typeLabels: Record<string, string> = {
  custom: "Custom",
  apt_emulation: "APT Emulation",
  kill_chain: "Kill Chain",
  compliance: "Compliance",
};

const testStateColors: 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",
};

export default function CampaignDetailPage() {
  const { campaignId } = useParams<{ campaignId: string }>();
  const navigate = useNavigate();
  const queryClient = useQueryClient();
  const { user } = useAuth();

  const [toast, setToast] = useState<{ message: string; type: "success" | "error" } | null>(null);
  const [showAddTestModal, setShowAddTestModal] = useState(false);
  const [showModRequestModal, setShowModRequestModal] = useState(false);
  // 0 = hidden, 1 = first confirmation, 2 = ask about tests
  const [deleteStep, setDeleteStep] = useState<0 | 1 | 2>(0);
  const [approveModalOpen, setApproveModalOpen] = useState(false);
  const [approveStartDate, setApproveStartDate] = useState("");
  const [rejectModalOpen, setRejectModalOpen] = useState(false);
  const [rejectReason, setRejectReason] = useState("");

  const showToast = (message: string, type: "success" | "error") => {
    setToast({ message, type });
    setTimeout(() => setToast(null), 5000);
  };

  const role = user?.role ?? "";
  const canManage = role === "admin" || role === "red_lead" || role === "blue_lead";
  const canComplete = role === "admin" || role === "red_lead";
  const isManager = role === "admin" || role === "manager";

  const {
    data: campaign,
    isLoading,
    error,
  } = useQuery({
    queryKey: ["campaign", campaignId],
    queryFn: () => getCampaign(campaignId!),
    enabled: !!campaignId,
  });

  const submitMutation = useMutation({
    mutationFn: () => submitCampaignForApproval(campaignId!),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ["campaign", campaignId] });
      queryClient.invalidateQueries({ queryKey: ["campaign-timeline", campaignId] });
      showToast("Campaign submitted for approval", "success");
    },
    onError: (err: Error) => showToast(err.message, "error"),
  });

  const approveMutation = useMutation({
    mutationFn: () => approveCampaign(campaignId!, approveStartDate),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ["campaign", campaignId] });
      queryClient.invalidateQueries({ queryKey: ["campaign-timeline", campaignId] });
      setApproveModalOpen(false);
      setApproveStartDate("");
      showToast("Campaign approved and activated", "success");
    },
    onError: (err: Error) => showToast(err.message, "error"),
  });

  const rejectMutation = useMutation({
    mutationFn: () => rejectCampaign(campaignId!, rejectReason),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ["campaign", campaignId] });
      queryClient.invalidateQueries({ queryKey: ["campaign-timeline", campaignId] });
      setRejectModalOpen(false);
      setRejectReason("");
      showToast("Campaign rejected", "success");
    },
    onError: (err: Error) => showToast(err.message, "error"),
  });

  const completeMutation = useMutation({
    mutationFn: () => completeCampaign(campaignId!),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ["campaign", campaignId] });
      queryClient.invalidateQueries({ queryKey: ["campaign-timeline", campaignId] });
      showToast("Campaign completed", "success");
    },
    onError: (err: Error) => showToast(err.message, "error"),
  });

  const removeMutation = useMutation({
    mutationFn: (campaignTestId: string) => removeTestFromCampaign(campaignId!, campaignTestId),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ["campaign", campaignId] });
      showToast("Test removed from campaign", "success");
    },
    onError: (err: Error) => showToast(err.message, "error"),
  });

  const scheduleMutation = useMutation({
    mutationFn: (payload: { is_recurring: boolean; recurrence_pattern?: string; next_run_at?: string }) =>
      scheduleCampaign(campaignId!, payload),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ["campaign", campaignId] });
      queryClient.invalidateQueries({ queryKey: ["campaign-timeline", campaignId] });
      showToast("Schedule updated", "success");
    },
    onError: (err: Error) => showToast(err.message, "error"),
  });

  const deleteMutation = useMutation({
    mutationFn: (deleteTests: boolean) => deleteCampaign(campaignId!, deleteTests),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ["campaigns"] });
      navigate("/campaigns");
    },
    onError: (err: Error) => {
      setDeleteStep(0);
      showToast(err.message, "error");
    },
  });

  const { data: historyData } = useQuery({
    queryKey: ["campaign-history", campaignId],
    queryFn: () => getCampaignHistory(campaignId!),
    enabled: !!campaignId && !!campaign?.is_recurring,
  });

  const { data: modRequests = [] } = useQuery({
    queryKey: ["campaign-modification-requests", campaignId],
    queryFn: () => listCampaignModificationRequests(campaignId!),
    enabled: !!campaignId,
  });

  const { data: timeline = [], isLoading: isTimelineLoading } = useQuery({
    queryKey: ["campaign-timeline", campaignId],
    queryFn: () => getCampaignTimeline(campaignId!),
    enabled: !!campaignId,
  });

  const approveModRequestMutation = useMutation({
    mutationFn: (requestId: string) => approveModificationRequest(requestId),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ["campaign", campaignId] });
      queryClient.invalidateQueries({ queryKey: ["campaign-modification-requests", campaignId] });
      queryClient.invalidateQueries({ queryKey: ["campaign-timeline", campaignId] });
      showToast("Modification approved and applied", "success");
    },
    onError: (err: Error) => showToast(err.message, "error"),
  });

  const rejectModRequestMutation = useMutation({
    mutationFn: ({ requestId, notes }: { requestId: string; notes: string }) =>
      rejectModificationRequest(requestId, notes),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ["campaign-modification-requests", campaignId] });
      queryClient.invalidateQueries({ queryKey: ["campaign-timeline", campaignId] });
      showToast("Modification rejected", "success");
    },
    onError: (err: Error) => showToast(err.message, "error"),
  });

  const [schedRecurring, setSchedRecurring] = useState(false);
  const [schedPattern, setSchedPattern] = useState("monthly");
  const [schedNextRun, setSchedNextRun] = useState("");

  // Sync scheduling state from campaign when loaded
  useState(() => {
    if (campaign) {
      setSchedRecurring(campaign.is_recurring || false);
      setSchedPattern(campaign.recurrence_pattern || "monthly");
      setSchedNextRun(campaign.next_run_at ? campaign.next_run_at.slice(0, 16) : "");
    }
  });

  const handleScheduleSave = () => {
    if (schedRecurring) {
      scheduleMutation.mutate({
        is_recurring: true,
        recurrence_pattern: schedPattern,
        next_run_at: schedNextRun || undefined,
      });
    } else {
      scheduleMutation.mutate({ is_recurring: false });
    }
  };

  const formatDate = (dateStr: string | null) => {
    if (!dateStr) return "\u2014";
    return new Date(dateStr).toLocaleDateString("en-US", {
      year: "numeric",
      month: "short",
      day: "numeric",
      hour: "2-digit",
      minute: "2-digit",
    });
  };

  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 || !campaign) {
    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 campaign</p>
        <button
          onClick={() => navigate("/campaigns")}
          className="mt-2 flex items-center gap-1 text-sm text-cyan-400 hover:underline"
        >
          <ArrowLeft className="h-4 w-4" />
          Back to campaigns
        </button>
      </div>
    );
  }

  const progress = campaign.progress;

  return (
    <div className="space-y-6">
      {/* Back button */}
      <button
        onClick={() => navigate("/campaigns")}
        className="flex items-center gap-1 text-sm text-gray-400 hover:text-cyan-400 transition-colors"
      >
        <ArrowLeft className="h-4 w-4" />
        Back to campaigns
      </button>

      {/* Header */}
      <div className="rounded-xl border border-gray-800 bg-gray-900 p-6">
        <div className="flex items-start justify-between">
          <div className="flex items-start gap-4">
            <div className="rounded-lg bg-cyan-500/10 p-3">
              <Zap className="h-8 w-8 text-cyan-400" />
            </div>
            <div>
              <div className="flex items-center gap-3">
                <h1 className="text-2xl font-bold text-white">{campaign.name}</h1>
                <span
                  className={`inline-flex rounded-full border px-2.5 py-0.5 text-xs font-medium ${
                    statusColors[campaign.status] || statusColors.draft
                  }`}
                >
                  {campaign.status}
                </span>
                <span className="inline-flex rounded-full border border-gray-600/30 bg-gray-800/50 px-2.5 py-0.5 text-xs font-medium text-gray-400">
                  {typeLabels[campaign.type] || campaign.type}
                </span>
              </div>
              {campaign.description && (
                <MarkdownText content={campaign.description} className="mt-1 text-sm text-gray-400" />
              )}
              {campaign.status === "draft" && campaign.rejection_reason && (
                <div className="mt-2 rounded-lg border border-amber-500/30 bg-amber-900/20 px-3 py-2 text-xs text-amber-400">
                  Rejected by manager: {campaign.rejection_reason}
                </div>
              )}
              <div className="mt-2 flex flex-wrap items-center gap-3 text-xs text-gray-500">
                {campaign.threat_actor_name && (
                  <button
                    onClick={() => navigate(`/threat-actors/${campaign.threat_actor_id}`)}
                    className="flex items-center gap-1 text-red-400 hover:underline"
                  >
                    <Target className="h-3.5 w-3.5" />
                    {campaign.threat_actor_name}
                  </button>
                )}
                <span className="flex items-center gap-1">
                  <Calendar className="h-3.5 w-3.5" />
                  Created {formatDate(campaign.created_at)}
                </span>
                {campaign.start_date && (() => {
                  const sd = new Date(campaign.start_date);
                  const now = new Date();
                  const isPast = sd <= now;
                  const diffDays = Math.ceil((sd.getTime() - now.getTime()) / 86400000);
                  return (
                    <span className={`flex items-center gap-1.5 rounded-full border px-2.5 py-0.5 text-xs font-medium ${
                      isPast
                        ? "border-green-500/30 bg-green-500/10 text-green-400"
                        : "border-amber-500/30 bg-amber-500/10 text-amber-400"
                    }`}>
                      <Clock className="h-3 w-3" />
                      {isPast
                        ? `Started ${formatDate(campaign.start_date)}`
                        : `Starts ${formatDate(campaign.start_date)} (${diffDays}d)`}
                    </span>
                  );
                })()}
                {campaign.completed_at && (
                  <span className="flex items-center gap-1 text-green-400">
                    <CheckCircle className="h-3.5 w-3.5" />
                    Completed {formatDate(campaign.completed_at)}
                  </span>
                )}
              </div>
            </div>
          </div>

          {/* Actions */}
          <div className="flex items-center gap-2">
            {/* Delete — only for draft campaigns (admins see it regardless) */}
            {(campaign.status === "draft" || role === "admin") && canManage && (
              <button
                onClick={() => setDeleteStep(1)}
                className="flex items-center gap-1.5 rounded-lg border border-red-500/30 bg-red-900/20 px-3 py-2 text-sm font-medium text-red-400 hover:bg-red-900/40 transition-colors"
                title="Delete campaign"
              >
                <Trash2 className="h-4 w-4" />
                Delete
              </button>
            )}
            {canManage && campaign.status === "draft" && (
              <button
                onClick={() => submitMutation.mutate()}
                disabled={submitMutation.isPending}
                className="flex items-center gap-1.5 rounded-lg bg-cyan-600 px-4 py-2 text-sm font-medium text-white hover:bg-cyan-500 disabled:opacity-50 transition-colors"
              >
                {submitMutation.isPending ? (
                  <Loader2 className="h-4 w-4 animate-spin" />
                ) : (
                  <Play className="h-4 w-4" />
                )}
                Submit for Approval
              </button>
            )}
            {isManager && campaign.status === "pending_approval" && (
              <>
                <button
                  onClick={() => setRejectModalOpen(true)}
                  className="flex items-center gap-1.5 rounded-lg border border-red-500/30 bg-red-900/20 px-4 py-2 text-sm font-medium text-red-400 hover:bg-red-900/40 transition-colors"
                >
                  Reject
                </button>
                <button
                  onClick={() => setApproveModalOpen(true)}
                  className="flex items-center gap-1.5 rounded-lg bg-green-600 px-4 py-2 text-sm font-medium text-white hover:bg-green-500 transition-colors"
                >
                  <CheckCircle className="h-4 w-4" />
                  Approve
                </button>
              </>
            )}
            {canComplete && campaign.status === "active" && (
              <button
                onClick={() => completeMutation.mutate()}
                disabled={completeMutation.isPending}
                className="flex items-center gap-1.5 rounded-lg bg-green-600 px-4 py-2 text-sm font-medium text-white hover:bg-green-500 disabled:opacity-50 transition-colors"
              >
                {completeMutation.isPending ? (
                  <Loader2 className="h-4 w-4 animate-spin" />
                ) : (
                  <CheckCircle className="h-4 w-4" />
                )}
                Mark Completed
              </button>
            )}
          </div>
        </div>
      </div>

      {/* Progress + Timing side by side */}
      <div className="grid gap-6 lg:grid-cols-2">
        {/* Progress Panel */}
        <div className="rounded-xl border border-gray-800 bg-gray-900 p-6">
          <h2 className="mb-4 text-lg font-semibold text-white">Progress</h2>
          <div className="flex items-center gap-6 mb-4">
            <div>
              <span className="text-3xl font-bold text-white">{progress.completion_pct}%</span>
              <span className="ml-1 text-sm text-gray-400">complete</span>
            </div>
            <div className="flex-1">
              <div className="h-3 w-full rounded-full bg-gray-800 overflow-hidden">
                <div
                  className={`h-full rounded-full transition-all ${
                    progress.completion_pct === 100 ? "bg-green-500" : "bg-cyan-500"
                  }`}
                  style={{ width: `${progress.completion_pct}%` }}
                />
              </div>
            </div>
            <span className="text-sm text-gray-400">
              {progress.by_state?.validated || 0} / {progress.total} tests
            </span>
          </div>

          {/* State breakdown */}
          {progress.total > 0 && (
            <div className="flex flex-wrap gap-3">
              {Object.entries(progress.by_state || {}).map(([state, count]) => (
                <div
                  key={state}
                  className={`rounded-lg border px-3 py-1.5 text-xs font-medium ${
                    testStateColors[state] || testStateColors.draft
                  }`}
                >
                  {state.replace(/_/g, " ")}: {count}
                </div>
              ))}
            </div>
          )}
        </div>

        {/* Campaign Timing */}
        <CampaignTimingPanel campaignId={campaignId!} />
      </div>

      {/* Kill Chain Timeline */}
      <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">Kill Chain Timeline</h2>
          {campaign.tags && campaign.tags.length > 0 && (
            <div className="flex gap-1">
              {campaign.tags.map((tag, i) => (
                <span
                  key={i}
                  className="rounded-full bg-gray-800 border border-gray-700 px-2 py-0.5 text-[10px] text-gray-400"
                >
                  {tag}
                </span>
              ))}
            </div>
          )}
        </div>
        <CampaignTimeline tests={campaign.tests} />
      </div>

      {/* Scheduling Panel */}
      {(canManage || campaign.is_recurring) && (
        <div className="rounded-xl border border-gray-800 bg-gray-900 p-6">
          <div className="mb-4 flex items-center gap-2">
            <Repeat className="h-5 w-5 text-cyan-400" />
            <h2 className="text-lg font-semibold text-white">Scheduling</h2>
            {campaign.next_run_at && (
              <span className="ml-auto inline-flex items-center gap-1.5 rounded-full border border-cyan-500/30 bg-cyan-900/30 px-3 py-1 text-xs font-medium text-cyan-400">
                <Calendar className="h-3.5 w-3.5" />
                Next run: {formatDate(campaign.next_run_at)}
              </span>
            )}
          </div>

          {canManage && (
            <div className="space-y-4">
              {/* Recurring toggle */}
              <label className="flex items-center gap-3 cursor-pointer">
                <div
                  className={`relative inline-flex h-6 w-11 shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors ${
                    schedRecurring ? "bg-cyan-600" : "bg-gray-700"
                  }`}
                  onClick={() => setSchedRecurring(!schedRecurring)}
                >
                  <span
                    className={`pointer-events-none inline-block h-5 w-5 transform rounded-full bg-white shadow transition-transform ${
                      schedRecurring ? "translate-x-5" : "translate-x-0"
                    }`}
                  />
                </div>
                <span className="text-sm font-medium text-gray-300">
                  Recurring Campaign
                </span>
              </label>

              {schedRecurring && (
                <div className="grid grid-cols-1 gap-4 md:grid-cols-2">
                  <div>
                    <label className="mb-1 block text-xs font-medium text-gray-500">
                      Frequency
                    </label>
                    <select
                      value={schedPattern}
                      onChange={(e) => setSchedPattern(e.target.value)}
                      className="w-full rounded-lg border border-gray-700 bg-gray-800 px-3 py-2 text-sm text-white focus:border-cyan-500 focus:outline-none"
                    >
                      <option value="weekly">Weekly</option>
                      <option value="monthly">Monthly</option>
                      <option value="quarterly">Quarterly</option>
                    </select>
                  </div>
                  <div>
                    <label className="mb-1 block text-xs font-medium text-gray-500">
                      Next Run At
                    </label>
                    <input
                      type="datetime-local"
                      value={schedNextRun}
                      onChange={(e) => setSchedNextRun(e.target.value)}
                      className="w-full rounded-lg border border-gray-700 bg-gray-800 px-3 py-2 text-sm text-white focus:border-cyan-500 focus:outline-none"
                    />
                  </div>
                </div>
              )}

              <button
                onClick={handleScheduleSave}
                disabled={scheduleMutation.isPending}
                className="flex items-center gap-1.5 rounded-lg bg-cyan-600 px-4 py-2 text-sm font-medium text-white hover:bg-cyan-500 disabled:opacity-50 transition-colors"
              >
                {scheduleMutation.isPending && <Loader2 className="h-4 w-4 animate-spin" />}
                Save Schedule
              </button>
            </div>
          )}

          {!canManage && campaign.is_recurring && (
            <div className="text-sm text-gray-400">
              This campaign runs <span className="text-white font-medium">{campaign.recurrence_pattern}</span>.
              {campaign.last_run_at && (
                <span className="ml-1">Last run: {formatDate(campaign.last_run_at)}</span>
              )}
            </div>
          )}
        </div>
      )}

      {/* Execution History */}
      {campaign.is_recurring && historyData && historyData.items.length > 0 && (
        <div className="rounded-xl border border-gray-800 bg-gray-900 p-6">
          <div className="mb-4 flex items-center gap-2">
            <History className="h-5 w-5 text-gray-400" />
            <h2 className="text-lg font-semibold text-white">
              Execution History ({historyData.items.length})
            </h2>
          </div>
          <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">Date</th>
                  <th className="pb-3 px-4 font-medium text-gray-400">Name</th>
                  <th className="pb-3 px-4 font-medium text-gray-400">Tests</th>
                  <th className="pb-3 px-4 font-medium text-gray-400">Progress</th>
                  <th className="pb-3 px-4 font-medium text-gray-400">Status</th>
                </tr>
              </thead>
              <tbody>
                {historyData.items.map((entry: CampaignHistoryEntry) => (
                  <tr
                    key={entry.id}
                    className="border-b border-gray-800/50 hover:bg-gray-800/30 transition-colors cursor-pointer"
                    onClick={() => navigate(`/campaigns/${entry.id}`)}
                  >
                    <td className="py-3 pr-4 text-xs text-gray-400">
                      {formatDate(entry.created_at)}
                    </td>
                    <td className="py-3 px-4 text-sm text-gray-200">
                      {entry.name}
                    </td>
                    <td className="py-3 px-4 text-sm text-gray-400">
                      {entry.test_count}
                    </td>
                    <td className="py-3 px-4">
                      <div className="flex items-center gap-2">
                        <div className="h-2 w-20 rounded-full bg-gray-800 overflow-hidden">
                          <div
                            className={`h-full rounded-full ${
                              entry.completion_pct === 100 ? "bg-green-500" : "bg-cyan-500"
                            }`}
                            style={{ width: `${entry.completion_pct}%` }}
                          />
                        </div>
                        <span className="text-xs text-gray-400">{entry.completion_pct}%</span>
                      </div>
                    </td>
                    <td className="py-3 px-4">
                      <span
                        className={`inline-flex rounded-full border px-2 py-0.5 text-xs font-medium ${
                          statusColors[entry.status] || statusColors.draft
                        }`}
                      >
                        {entry.status}
                      </span>
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        </div>
      )}

      {/* Tests Table */}
      <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">
            Tests ({campaign.tests.length})
          </h2>
          {canManage && campaign.status === "draft" && (
            <button
              onClick={() => setShowAddTestModal(true)}
              className="flex items-center gap-1.5 rounded-lg border border-cyan-500/30 bg-cyan-500/10 px-3 py-1.5 text-sm font-medium text-cyan-400 hover:bg-cyan-500/20 transition-colors"
            >
              <Plus className="h-4 w-4" />
              Add Test
            </button>
          )}
          {canManage && campaign.status === "active" && (
            <button
              onClick={() => setShowModRequestModal(true)}
              className="flex items-center gap-1.5 rounded-lg border border-amber-500/30 bg-amber-500/10 px-3 py-1.5 text-sm font-medium text-amber-400 hover:bg-amber-500/20 transition-colors"
            >
              Request Modification
            </button>
          )}
        </div>

        {campaign.tests.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">#</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">Test Name</th>
                  <th className="pb-3 px-4 font-medium text-gray-400">Phase</th>
                  <th className="pb-3 px-4 font-medium text-gray-400">State</th>
                  <th className="pb-3 px-4 font-medium text-gray-400">Platform</th>
                  <th className="pb-3 pl-4 font-medium text-gray-400">Actions</th>
                </tr>
              </thead>
              <tbody>
                {campaign.tests
                  .sort((a, b) => a.order_index - b.order_index)
                  .map((ct) => (
                    <tr
                      key={ct.id}
                      className="border-b border-gray-800/50 hover:bg-gray-800/30 transition-colors"
                    >
                      <td className="py-3 pr-4">
                        <span className="text-xs text-gray-500">{ct.order_index + 1}</span>
                      </td>
                      <td className="py-3 px-4">
                        <span className="font-mono text-xs text-cyan-400">
                          {ct.technique_mitre_id || "\u2014"}
                        </span>
                      </td>
                      <td className="py-3 px-4">
                        <button
                          onClick={() => navigate(`/tests/${ct.test_id}`)}
                          className="text-sm font-medium text-gray-200 hover:text-cyan-400 transition-colors"
                        >
                          {ct.test_name || "Unnamed test"}
                        </button>
                      </td>
                      <td className="py-3 px-4">
                        <span className="text-xs text-gray-400 capitalize">
                          {ct.phase?.replace(/_/g, " ") || "\u2014"}
                        </span>
                      </td>
                      <td className="py-3 px-4">
                        <span
                          className={`inline-flex rounded-full border px-2 py-0.5 text-xs font-medium ${
                            testStateColors[ct.test_state || "draft"] || testStateColors.draft
                          }`}
                        >
                          {(ct.test_state || "draft").replace(/_/g, " ")}
                        </span>
                      </td>
                      <td className="py-3 px-4">
                        <span className="text-xs text-gray-400 capitalize">
                          {ct.platform || "\u2014"}
                        </span>
                      </td>
                      <td className="py-3 pl-4">
                        <div className="flex items-center gap-2">
                          <button
                            onClick={() => navigate(`/tests/${ct.test_id}`)}
                            className="rounded p-1 text-gray-400 hover:bg-gray-800 hover:text-cyan-400"
                            title="View Test"
                          >
                            <Clock className="h-4 w-4" />
                          </button>
                          {canManage && campaign.status === "draft" && (
                            <button
                              onClick={() => removeMutation.mutate(ct.id)}
                              disabled={removeMutation.isPending}
                              className="rounded p-1 text-gray-400 hover:bg-red-900/50 hover:text-red-400"
                              title="Remove from campaign"
                            >
                              <Trash2 className="h-4 w-4" />
                            </button>
                          )}
                        </div>
                      </td>
                    </tr>
                  ))}
              </tbody>
            </table>
          </div>
        ) : (
          <div className="flex flex-col items-center justify-center py-8 text-gray-400">
            <Zap className="mb-2 h-8 w-8 text-gray-600" />
            <p>No tests in this campaign yet.</p>
          </div>
        )}
      </div>

      {/* Modification Requests */}
      {modRequests.length > 0 && (
        <div className="rounded-xl border border-gray-800 bg-gray-900 p-6">
          <h2 className="mb-4 text-lg font-semibold text-white">Modification Requests</h2>
          <div className="space-y-3">
            {modRequests.map((r) => (
              <div key={r.id} className="rounded-lg border border-gray-800 p-4">
                <div className="flex items-start justify-between gap-4">
                  <div>
                    <p className="text-sm text-gray-200">
                      <span className="font-medium capitalize">{r.action.replace("_", " ")}</span>
                      {" — "}
                      {r.test_name || r.test_id || "deleted test"}
                    </p>
                    <p className="mt-1 text-xs text-gray-400">{r.justification}</p>
                    {r.review_notes && (
                      <p className="mt-1 text-xs text-amber-400">Manager notes: {r.review_notes}</p>
                    )}
                  </div>
                  <span
                    className={`shrink-0 rounded-full border px-2 py-0.5 text-[10px] font-medium ${
                      r.status === "pending"
                        ? "border-amber-500/30 bg-amber-900/30 text-amber-400"
                        : r.status === "approved"
                          ? "border-green-500/30 bg-green-900/30 text-green-400"
                          : "border-red-500/30 bg-red-900/30 text-red-400"
                    }`}
                  >
                    {r.status}
                  </span>
                </div>
                {isManager && r.status === "pending" && (
                  <div className="mt-3 flex gap-2">
                    <button
                      onClick={() => approveModRequestMutation.mutate(r.id)}
                      className="rounded-lg bg-green-600 px-3 py-1.5 text-xs font-medium text-white hover:bg-green-500 transition-colors"
                    >
                      Approve
                    </button>
                    <button
                      onClick={() => {
                        const notes = window.prompt("Reason for rejecting this request:");
                        if (notes && notes.trim()) {
                          rejectModRequestMutation.mutate({ requestId: r.id, notes: notes.trim() });
                        }
                      }}
                      className="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 transition-colors"
                    >
                      Reject
                    </button>
                  </div>
                )}
              </div>
            ))}
          </div>
        </div>
      )}

      {/* Timeline */}
      <div className="rounded-xl border border-gray-800 bg-gray-900 p-6">
        <h2 className="mb-4 text-lg font-semibold text-white">Timeline</h2>
        <CampaignAuditTimeline entries={timeline} isLoading={isTimelineLoading} />
      </div>

      {/* Jira */}
      <JiraLinkPanel entityType="campaign" entityId={campaignId!} readOnly label={campaign.name} />

      {/* Add Test to Campaign Modal */}
      <AddTestToCampaignModal
        campaignId={campaignId!}
        existingTestIds={campaign.tests.map((ct) => ct.test_id)}
        open={showAddTestModal}
        onClose={() => setShowAddTestModal(false)}
        onSuccess={() => showToast("Test added to campaign", "success")}
      />

      {/* Request Modification Modal */}
      <RequestCampaignModificationModal
        campaignId={campaignId!}
        tests={campaign.tests}
        open={showModRequestModal}
        onClose={() => setShowModRequestModal(false)}
        onSuccess={() => showToast("Modification request submitted", "success")}
      />

      {/* Approve modal */}
      {approveModalOpen && (
        <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/70 backdrop-blur-sm">
          <div className="mx-4 w-full max-w-md rounded-xl border border-green-500/30 bg-gray-900 p-6 shadow-2xl">
            <h3 className="mb-4 text-lg font-semibold text-white">Approve Campaign</h3>
            <label className="mb-1.5 block text-sm font-medium text-gray-300">
              Start date <span className="text-red-400">*</span>
            </label>
            <input
              type="datetime-local"
              value={approveStartDate}
              onChange={(e) => setApproveStartDate(e.target.value)}
              className="w-full rounded-lg border border-gray-700 bg-gray-800 px-3 py-2 text-sm text-gray-200 focus:border-cyan-500 focus:outline-none [color-scheme:dark]"
            />
            <div className="mt-6 flex justify-end gap-3">
              <button
                onClick={() => setApproveModalOpen(false)}
                className="rounded-lg border border-gray-700 px-4 py-2 text-sm text-gray-400 hover:bg-gray-800 transition-colors"
              >
                Cancel
              </button>
              <button
                onClick={() => approveMutation.mutate()}
                disabled={!approveStartDate || approveMutation.isPending}
                className="flex items-center gap-1.5 rounded-lg bg-green-600 px-4 py-2 text-sm font-medium text-white hover:bg-green-500 disabled:opacity-50 transition-colors"
              >
                {approveMutation.isPending && <Loader2 className="h-4 w-4 animate-spin" />}
                Approve &amp; Activate
              </button>
            </div>
          </div>
        </div>
      )}

      {/* Reject modal */}
      {rejectModalOpen && (
        <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/70 backdrop-blur-sm">
          <div className="mx-4 w-full max-w-md rounded-xl border border-red-500/30 bg-gray-900 p-6 shadow-2xl">
            <h3 className="mb-4 text-lg font-semibold text-white">Reject Campaign</h3>
            <label className="mb-1.5 block text-sm font-medium text-gray-300">
              Reason <span className="text-red-400">*</span>
            </label>
            <textarea
              value={rejectReason}
              onChange={(e) => setRejectReason(e.target.value)}
              rows={3}
              placeholder="Explain what needs to change before this can be approved…"
              className="w-full rounded-lg border border-gray-700 bg-gray-800 px-3 py-2 text-sm text-gray-200 placeholder-gray-500 focus:border-cyan-500 focus:outline-none"
            />
            <div className="mt-6 flex justify-end gap-3">
              <button
                onClick={() => setRejectModalOpen(false)}
                className="rounded-lg border border-gray-700 px-4 py-2 text-sm text-gray-400 hover:bg-gray-800 transition-colors"
              >
                Cancel
              </button>
              <button
                onClick={() => rejectMutation.mutate()}
                disabled={!rejectReason.trim() || rejectMutation.isPending}
                className="flex items-center gap-1.5 rounded-lg bg-red-600 px-4 py-2 text-sm font-medium text-white hover:bg-red-500 disabled:opacity-50 transition-colors"
              >
                {rejectMutation.isPending && <Loader2 className="h-4 w-4 animate-spin" />}
                Reject
              </button>
            </div>
          </div>
        </div>
      )}

      {/* Toast notification */}
      {toast && (
        <div
          className={`fixed bottom-6 right-6 z-50 rounded-lg border px-4 py-3 text-sm shadow-lg backdrop-blur transition-all ${
            toast.type === "success"
              ? "border-green-500/30 bg-green-900/90 text-green-300"
              : "border-red-500/30 bg-red-900/90 text-red-300"
          }`}
        >
          {toast.message}
        </div>
      )}

      {/* Delete confirmation — Step 1 */}
      {deleteStep === 1 && (
        <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/70 backdrop-blur-sm">
          <div className="mx-4 w-full max-w-md rounded-xl border border-red-500/30 bg-gray-900 p-6 shadow-2xl">
            <div className="mb-4 flex items-center gap-3">
              <div className="rounded-lg bg-red-500/10 p-2">
                <Trash2 className="h-5 w-5 text-red-400" />
              </div>
              <h3 className="text-lg font-semibold text-white">Delete Campaign</h3>
            </div>
            <p className="mb-1 text-sm text-gray-300">
              Are you sure you want to delete{" "}
              <span className="font-semibold text-white">{campaign.name}</span>?
            </p>
            <p className="mb-6 text-xs text-gray-500">This action cannot be undone.</p>
            <div className="flex justify-end gap-3">
              <button
                onClick={() => setDeleteStep(0)}
                className="rounded-lg border border-gray-700 bg-gray-800 px-4 py-2 text-sm font-medium text-gray-300 hover:bg-gray-700 transition-colors"
              >
                Cancel
              </button>
              <button
                onClick={() => setDeleteStep(2)}
                className="rounded-lg bg-red-600 px-4 py-2 text-sm font-medium text-white hover:bg-red-500 transition-colors"
              >
                Continue
              </button>
            </div>
          </div>
        </div>
      )}

      {/* Delete confirmation — Step 2: ask about tests */}
      {deleteStep === 2 && (
        <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/70 backdrop-blur-sm">
          <div className="mx-4 w-full max-w-md rounded-xl border border-red-500/30 bg-gray-900 p-6 shadow-2xl">
            <div className="mb-4 flex items-center gap-3">
              <div className="rounded-lg bg-red-500/10 p-2">
                <Trash2 className="h-5 w-5 text-red-400" />
              </div>
              <h3 className="text-lg font-semibold text-white">Delete Associated Tests?</h3>
            </div>
            <p className="mb-6 text-sm text-gray-300">
              This campaign has{" "}
              <span className="font-semibold text-white">{campaign.tests.length}</span>{" "}
              associated test{campaign.tests.length !== 1 ? "s" : ""}. Do you also want to
              delete them?
            </p>
            <div className="flex flex-col gap-2 sm:flex-row sm:justify-end">
              <button
                onClick={() => setDeleteStep(0)}
                className="rounded-lg border border-gray-700 bg-gray-800 px-4 py-2 text-sm font-medium text-gray-300 hover:bg-gray-700 transition-colors"
              >
                Cancel
              </button>
              <button
                onClick={() => deleteMutation.mutate(false)}
                disabled={deleteMutation.isPending}
                className="flex items-center justify-center gap-1.5 rounded-lg border border-gray-600 bg-gray-800 px-4 py-2 text-sm font-medium text-gray-200 hover:bg-gray-700 disabled:opacity-50 transition-colors"
              >
                {deleteMutation.isPending ? (
                  <Loader2 className="h-4 w-4 animate-spin" />
                ) : null}
                Keep Tests
              </button>
              <button
                onClick={() => deleteMutation.mutate(true)}
                disabled={deleteMutation.isPending}
                className="flex items-center justify-center gap-1.5 rounded-lg bg-red-600 px-4 py-2 text-sm font-medium text-white hover:bg-red-500 disabled:opacity-50 transition-colors"
              >
                {deleteMutation.isPending ? (
                  <Loader2 className="h-4 w-4 animate-spin" />
                ) : null}
                Delete Tests Too
              </button>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}
