"use client";

import { useEffect, useMemo, useState } from "react";
import {
  Alert,
  Badge,
  Card,
  Col,
  Descriptions,
  Row,
  Space,
  Tag,
  Tooltip,
  Typography,
  message,
  Button,
  Dropdown,
  Steps,
  Input,
  List,
  Modal,
  Select,
  Switch,
} from "antd";
import {
  CloudOutlined,
  DatabaseOutlined,
  EditOutlined,
  ExclamationCircleOutlined,
  FieldTimeOutlined,
  CheckCircleOutlined,
  MoreOutlined,
  ClockCircleOutlined,
  UserSwitchOutlined,
} from "@ant-design/icons";
import dayjs from "dayjs";
import { useParams, useRouter } from "next/navigation";

import EmployeeDropdown from "@/components/common/EmployeeDropdown";
import { VulnerabilityHtml } from "@/components/common/VulnerabilityHtml";
import {
  addVulnerabilityComment,
  assignVulnerability,
  claimVulnerability,
  fetchVulnerability,
  fetchVulnerabilityComments,
  fetchVulnerabilityEvents,
  searchVulnerabilityAuthorizedViewerCandidates,
  transitionVulnerability,
  updateVulnerabilityAuthorizedViewers,
  updateVulnerabilityVisibility,
  updateVulnerabilityMeta,
} from "@/lib/api/vulnerabilities";
import {
  extractApiErrorMessage,
  getPickerReadsBlockedMessage,
  isPickerReadsBlockedError,
} from "@/lib/api/errors";
import { useAuth } from "@/lib/hooks/use-auth";
import type {
  CriticalityLevel,
  EmployeeSummary,
  VulnerabilityComment,
  VulnerabilityDetail,
  VulnerabilityEvent,
  VulnerabilityStatus,
} from "@/types/models";

const { Title, Paragraph, Text } = Typography;

const severityColors: Record<CriticalityLevel, string> = {
  critical: "red",
  high: "volcano",
  medium: "gold",
  low: "blue",
};

const statusMeta: Record<
  VulnerabilityStatus,
  { label: string; color: string }
> = {
  active: { label: "Active", color: "blue" },
  retesting: { label: "Retesting", color: "orange" },
  fixed: { label: "Fixed", color: "green" },
  false_positive: { label: "False Positive", color: "default" },
  risk_accepted: { label: "Risk Accepted", color: "purple" },
};

function FieldLabel({ label }: { label: string }) {
  return (
    <Text
      type="secondary"
      style={{ fontSize: 12, textTransform: "uppercase", letterSpacing: 0.4 }}
    >
      {label}
    </Text>
  );
}

function formatTime(value?: string | null) {
  if (!value) return "—";
  return dayjs(value).format("YYYY-MM-DD HH:mm");
}

function displayVulnerabilityID(id?: number, publicID?: string) {
  return publicID?.trim() || (typeof id === "number" ? `#${id}` : "—");
}

function useDebouncedValue<T>(value: T, delay: number) {
  const [debounced, setDebounced] = useState(value);

  useEffect(() => {
    const timer = window.setTimeout(() => setDebounced(value), delay);
    return () => window.clearTimeout(timer);
  }, [value, delay]);

  return debounced;
}

export default function VulnerabilityDetailPage() {
  const params = useParams<{ publicId: string }>();
  const router = useRouter();
  const { user } = useAuth();
  const [data, setData] = useState<VulnerabilityDetail | null>(null);
  const [actions, setActions] = useState<string[]>([]);
  const [loading, setLoading] = useState(false);
  const [loadError, setLoadError] = useState<string | null>(null);
  const [accessDenied, setAccessDenied] = useState(false);
  const [events, setEvents] = useState<VulnerabilityEvent[]>([]);
  const [comments, setComments] = useState<VulnerabilityComment[]>([]);
  const [tagsInput, setTagsInput] = useState<string>("");
  const [verificationStepsInput, setVerificationStepsInput] =
    useState<string>("");
  const [pocTextInput, setPocTextInput] = useState<string>("");
  const [commentInput, setCommentInput] = useState<string>("");
  const [assignModalOpen, setAssignModalOpen] = useState(false);
  const [assignEmployeeId, setAssignEmployeeId] = useState<number | undefined>(
    undefined,
  );
  const [authorizedViewerIds, setAuthorizedViewerIds] = useState<number[]>([]);
  const [employeeOptions, setEmployeeOptions] = useState<EmployeeSummary[]>([]);
  const [employeeSearchQuery, setEmployeeSearchQuery] = useState("");
  const [loadingEmployees, setLoadingEmployees] = useState(false);
  const [employeeSearchError, setEmployeeSearchError] = useState<string | null>(
    null,
  );
  const [savingAuthorizedViewers, setSavingAuthorizedViewers] = useState(false);
  const [savingPublicVisibility, setSavingPublicVisibility] = useState(false);
  const [savingMeta, setSavingMeta] = useState(false);
  const [actionLoading, setActionLoading] = useState<string | null>(null);
  const isLoading = loading || !data;
  const routePublicId = params.publicId?.trim() || "";
  const debouncedEmployeeSearchQuery = useDebouncedValue(
    employeeSearchQuery,
    300,
  );

  useEffect(() => {
    if (!routePublicId) {
      message.error("Invalid vulnerability public ID");
      router.push("/dashboard/vulnerabilities/list");
      return;
    }
    const load = async () => {
      setLoading(true);
      setLoadError(null);
      setAccessDenied(false);
      try {
        const payload = await fetchVulnerability(routePublicId);
        if (!payload.vulnerability.public_id?.trim()) {
          setLoadError("Vulnerability public ID is missing from the response.");
          return;
        }
        setData(payload.vulnerability);
        setActions(payload.actions || []);
        setAuthorizedViewerIds(
          payload.vulnerability.authorized_viewer_employee_ids ?? [],
        );
        try {
          const ev = await fetchVulnerabilityEvents(routePublicId);
          setEvents(ev || []);
        } catch (eventsErr) {
          if (getErrorStatus(eventsErr) !== 403) {
            throw eventsErr;
          }
          setEvents([]);
        }
        try {
          const cmts = await fetchVulnerabilityComments(routePublicId);
          setComments(cmts || []);
        } catch (commentsErr) {
          if (getErrorStatus(commentsErr) !== 403) {
            throw commentsErr;
          }
          setComments([]);
        }
      } catch (err) {
        console.error("Failed to load vulnerability", err);
        if (getErrorStatus(err) === 403) {
          setAccessDenied(true);
          setLoadError("You are not authorized to view this vulnerability.");
        } else {
          setLoadError("Failed to load vulnerability.");
          message.error("Failed to load vulnerability");
        }
      } finally {
        setLoading(false);
      }
    };
    load();
  }, [routePublicId, router]);

  useEffect(() => {
    if (!data) {
      return;
    }
    setTagsInput((data.tags || []).join(", "));
    setVerificationStepsInput(data.verification_steps || "");
    setPocTextInput(data.poc_text || "");
    setAuthorizedViewerIds(data.authorized_viewer_employee_ids ?? []);
  }, [data]);

  useEffect(() => {
    if (!actions.includes("authorize_viewers") || !routePublicId) {
      return;
    }
    const query = debouncedEmployeeSearchQuery.trim();
    if (!query && authorizedViewerIds.length === 0) {
      setEmployeeSearchError(null);
      setLoadingEmployees(false);
      return;
    }

    let cancelled = false;
    const searchEmployees = async () => {
      setLoadingEmployees(true);
      setEmployeeSearchError(null);
      try {
        const items = await searchVulnerabilityAuthorizedViewerCandidates(
          routePublicId,
          query,
          authorizedViewerIds,
        );
        if (!cancelled) {
          setEmployeeOptions(items);
        }
      } catch (err) {
        console.error("Failed to load employees", err);
        const errorMessage = isPickerReadsBlockedError(err)
          ? getPickerReadsBlockedMessage()
          : extractApiErrorMessage(err) ?? "Failed to load employees";
        if (!cancelled) {
          setEmployeeSearchError(errorMessage);
        }
      } finally {
        if (!cancelled) {
          setLoadingEmployees(false);
        }
      }
    };
    void searchEmployees();
    return () => {
      cancelled = true;
    };
  }, [actions, authorizedViewerIds, debouncedEmployeeSearchQuery, routePublicId]);

  const statusInfo = data
    ? statusMeta[data.status]
    : { label: "Loading", color: "default" as const };
  const availableActions = useMemo(() => new Set(actions), [actions]);
  const hasAction = (action: string) => availableActions.has(action);
  const submittedAt = formatTime(data?.submitted_at);
  const slaDeadline = formatTime(data?.sla_deadline);

  const lifecycleItems = useMemo(() => {
    if (events.length) {
      return events.map((event) => {
        const meta = (event.metadata as Record<string, unknown>) || {};
        const actor =
          (meta["actor_name"] as string) ||
          (meta["actor"] as string) ||
          (meta["user"] as string) ||
          "System";
        const action = event.message || event.event_type;
        return {
          title: action,
          actor,
          time: formatTime(event.created_at),
          status: event.event_type === "status_changed" ? "process" : "wait",
        };
      });
    }
    if (!data) return [];
    const items: {
      title: string;
      time?: string | null;
      status?: "process" | "wait";
      actor?: string;
    }[] = [
      {
        title: "Submitted",
        time: data.submitted_at,
        status: "process",
        actor: data.submitter?.name,
      },
      {
        title: "Claimed",
        time: data.claimed_at,
        status: "process",
        actor: data.owner_employee?.name,
      },
      {
        title: "Fix requested",
        time: data.fix_requested_at,
        status: "process",
        actor: data.owner_employee?.name,
      },
      {
        title: "Fixed",
        time: data.fixed_at,
        status: "process",
        actor: data.owner_employee?.name,
      },
      {
        title: "Closed",
        time: data.closed_at,
        status: "wait",
        actor: data.owner_employee?.name,
      },
    ];
    return items.filter((item) => item.time);
  }, [data, events]);

  const triggerTransition = async (
    status: VulnerabilityStatus,
    label: string,
    messageText?: string,
    loadingKey?: string,
  ) => {
    if (!data) return;
    const currentPublicId = data.public_id?.trim();
    if (!currentPublicId) {
      message.error("Vulnerability public ID is missing.");
      return;
    }
    setActionLoading(loadingKey || status);
    try {
      await transitionVulnerability(
        currentPublicId,
        status,
        messageText || `Status updated to ${status}`,
      );
      const payload = await fetchVulnerability(currentPublicId);
      setData(payload.vulnerability);
      setActions(payload.actions || []);
      const ev = await fetchVulnerabilityEvents(currentPublicId);
      setEvents(ev || []);
      const cmts = await fetchVulnerabilityComments(currentPublicId);
      setComments(cmts || []);
      message.success(`Marked as ${label}`);
    } catch (err) {
      console.error("Failed to update status", err);
      message.error(
        getErrorStatus(err) === 403
          ? "You are not allowed to update this vulnerability."
          : "Failed to update status",
      );
    } finally {
      setActionLoading(null);
    }
  };

  const submitRetestRequest = () =>
    triggerTransition(
      "retesting",
      "Retesting",
      "Fix submitted for retest",
    );

  const handleRequestRetest = () => {
    if (!data) return;
    if (data.code_repository?.trim()) {
      submitRetestRequest();
      return;
    }

    const editPublicId = data.public_id?.trim();
    Modal.confirm({
      title: "Code repository is missing",
      icon: <ExclamationCircleOutlined />,
      content: (
        <Space direction="vertical" size={8}>
          <Text>
            We recommend adding the code repository before requesting a retest
            so the reviewer can find the fix quickly.
          </Text>
          <Text>
            If this vulnerability has no repository or the repository is not
            applicable, you can continue the retest request.
          </Text>
        </Space>
      ),
      okText: "Continue Retest",
      cancelText: "Go to Edit",
      onOk: submitRetestRequest,
      onCancel: () => {
        if (!editPublicId) {
          message.error("Vulnerability public ID is missing.");
          return;
        }
        router.push(`/dashboard/vulnerabilities/${editPublicId}/edit`);
      },
    });
  };

  const handleSaveMeta = async () => {
    if (!data) return;
    const currentPublicId = data.public_id?.trim();
    if (!currentPublicId) {
      message.error("Vulnerability public ID is missing.");
      return;
    }
    setSavingMeta(true);
    try {
      const tags = canEditTags
        ? tagsInput
            .split(",")
            .map((t) => t.trim())
            .filter(Boolean)
        : undefined;
      const updated = await updateVulnerabilityMeta(currentPublicId, {
        tags,
        verification_steps: canEditSensitive
          ? verificationStepsInput
          : undefined,
        poc_text: canEditSensitive ? pocTextInput : undefined,
      });
      setData(updated);
      const ev = await fetchVulnerabilityEvents(currentPublicId);
      setEvents(ev || []);
      message.success(
        canEditSensitive ? "Updated vulnerability metadata" : "Updated tags",
      );
    } catch (err) {
      console.error("Failed to update meta", err);
      message.error(
        getErrorStatus(err) === 403
          ? "You are not allowed to update vulnerability metadata."
          : "Failed to update vulnerability metadata",
      );
    } finally {
      setSavingMeta(false);
    }
  };

  const handleSaveAuthorizedViewers = async () => {
    if (!data) return;
    const currentPublicId = data.public_id?.trim();
    if (!currentPublicId) {
      message.error("Vulnerability public ID is missing.");
      return;
    }
    setSavingAuthorizedViewers(true);
    try {
      const payload = await updateVulnerabilityAuthorizedViewers(currentPublicId, {
        authorized_viewer_employee_ids: authorizedViewerIds,
      });
      setData(payload);
      setAuthorizedViewerIds(payload.authorized_viewer_employee_ids ?? []);
      message.success("Updated authorized viewers");
    } catch (err) {
      console.error("Failed to update authorized viewers", err);
      message.error(
        getErrorStatus(err) === 403
          ? "You are not allowed to manage authorized viewers."
          : "Failed to update authorized viewers",
      );
    } finally {
      setSavingAuthorizedViewers(false);
    }
  };

  const handlePublicVisibilityChange = async (isPublicViewable: boolean) => {
    if (!data) return;
    const currentPublicId = data.public_id?.trim();
    if (!currentPublicId) {
      message.error("Vulnerability public ID is missing.");
      return;
    }
    setSavingPublicVisibility(true);
    try {
      const updated = await updateVulnerabilityVisibility(currentPublicId, {
        is_public_viewable: isPublicViewable,
      });
      const nextAuthorizedViewerIds =
        updated.authorized_viewer_employee_ids ?? authorizedViewerIds;
      setData((previous) => ({
        ...(previous ?? updated),
        ...updated,
        is_public_viewable: updated.is_public_viewable ?? isPublicViewable,
        authorized_viewer_employee_ids: nextAuthorizedViewerIds,
      }));
      if (Array.isArray(updated.authorized_viewer_employee_ids)) {
        setAuthorizedViewerIds(updated.authorized_viewer_employee_ids);
      }
      message.success(
        isPublicViewable
          ? "Enabled public vulnerability visibility"
          : "Disabled public vulnerability visibility",
      );
    } catch (err) {
      console.error("Failed to update vulnerability visibility", err);
      message.error(
        getErrorStatus(err) === 403
          ? "You are not allowed to manage public visibility."
          : "Failed to update public visibility",
      );
    } finally {
      setSavingPublicVisibility(false);
    }
  };

  const handleAddComment = async () => {
    if (!data || !commentInput.trim()) return;
    const currentPublicId = data.public_id?.trim();
    if (!currentPublicId) {
      message.error("Vulnerability public ID is missing.");
      return;
    }
    try {
      await addVulnerabilityComment(currentPublicId, { content: commentInput });
      const cmts = await fetchVulnerabilityComments(currentPublicId);
      setComments(cmts || []);
      const ev = await fetchVulnerabilityEvents(currentPublicId);
      setEvents(ev || []);
      setCommentInput("");
    } catch (err) {
      console.error("Failed to add comment", err);
      message.error(
        getErrorStatus(err) === 403
          ? "You are not allowed to comment on this vulnerability."
          : "Failed to add comment",
      );
    }
  };

  const handleClaim = async () => {
    if (!data) return;
    const currentPublicId = data.public_id?.trim();
    if (!currentPublicId) {
      message.error("Vulnerability public ID is missing.");
      return;
    }
    setActionLoading("claim");
    try {
      await claimVulnerability(currentPublicId, {});
      const payload = await fetchVulnerability(currentPublicId);
      setData(payload.vulnerability);
      setActions(payload.actions || []);
      const ev = await fetchVulnerabilityEvents(currentPublicId);
      setEvents(ev || []);
      const cmts = await fetchVulnerabilityComments(currentPublicId);
      setComments(cmts || []);
      message.success("Claimed and assigned");
    } catch (err) {
      console.error("Failed to claim", err);
      message.error(
        getErrorStatus(err) === 403
          ? "You are not allowed to claim this vulnerability."
          : "Failed to claim",
      );
    } finally {
      setActionLoading(null);
    }
  };

  const handleAssign = async () => {
    if (!data) return;
    const currentPublicId = data.public_id?.trim();
    if (!currentPublicId) {
      message.error("Vulnerability public ID is missing.");
      return;
    }
    setActionLoading("assign");
    try {
      if (!assignEmployeeId) {
        message.error("Select an owner");
        return;
      }
      await assignVulnerability(currentPublicId, {
        owner_employee_id: assignEmployeeId,
      });
      const payload = await fetchVulnerability(currentPublicId);
      setData(payload.vulnerability);
      setActions(payload.actions || []);
      const ev = await fetchVulnerabilityEvents(currentPublicId);
      setEvents(ev || []);
      const cmts = await fetchVulnerabilityComments(currentPublicId);
      setComments(cmts || []);
      message.success("Assigned to owner");
    } catch (err) {
      console.error("Failed to assign", err);
      message.error(
        getErrorStatus(err) === 403
          ? "You are not allowed to assign a remediation owner."
          : "Failed to assign",
      );
    } finally {
      setActionLoading(null);
      setAssignModalOpen(false);
    }
  };

  const ownerLabel =
    data?.owner_employee?.name || data?.owner_employee?.email || "Unassigned";
  const isOwner = Boolean(
    user?.employeeId &&
    data?.owner_employee_id &&
    user.employeeId === data.owner_employee_id,
  );
  const canComment = hasAction("comment");
  const canClaim = hasAction("claim");
  const canAssign = hasAction("assign_owner");
  const canViewSensitiveFields =
    hasAction("view_sensitive_details") ||
    hasAction("edit_sensitive_details") ||
    hasAction("edit_details");
  const canEditSensitive = hasAction("edit_sensitive_details");
  const canEditTags = hasAction("edit_tags");
  const canMarkFixed = hasAction("mark_fixed");
  const canEditDetails = hasAction("edit_details");
  const canRequestRetest = hasAction("request_retest");
  const canReopen = hasAction("reopen");
  const canMarkFalsePositive = hasAction("mark_false_positive");
  const canMarkRiskAccepted = hasAction("mark_risk_accepted");
  const canManageAuthorizedViewers = hasAction("authorize_viewers");
  const shouldShowAuthorizedViewers = canManageAuthorizedViewers;

  if (accessDenied || loadError) {
    return (
      <Card>
        <Alert
          type={accessDenied ? "warning" : "error"}
          showIcon
          message={
            accessDenied ? "Access restricted" : "Unable to load vulnerability"
          }
          description={loadError}
          action={
            <Button
              type="primary"
              onClick={() => router.push("/dashboard/vulnerabilities/list")}
            >
              Back to vulnerabilities
            </Button>
          }
        />
      </Card>
    );
  }

  return (
    <Space direction="vertical" size={16} style={{ width: "100%" }}>
      <Card>
        <Space direction="vertical" size={4} style={{ width: "100%" }}>
          <Space
            align="center"
            size={12}
            style={{ width: "100%", justifyContent: "space-between" }}
            wrap
          >
            <Space align="center" size={12} wrap>
              <Title level={3} style={{ margin: 0, maxWidth: 520 }}>
                <Text ellipsis={{ tooltip: data?.title }}>
                  {data?.title ?? "Loading..."}
                </Text>
              </Title>
              <Tag
                color={data ? severityColors[data.severity_level] : "default"}
                style={{ textTransform: "uppercase" }}
              >
                {data?.severity_level ?? ""}
              </Tag>
              <Tag color={statusInfo.color}>{statusInfo.label}</Tag>
              {data?.is_overdue && (
                <Tag color="red" icon={<ExclamationCircleOutlined />}>
                  Overdue
                </Tag>
              )}
            </Space>
            {data && canEditDetails ? (
              <Button
                type="primary"
                icon={<EditOutlined />}
                onClick={() =>
                  router.push(
                    `/dashboard/vulnerabilities/${data.public_id}/edit`,
                  )
                }
              >
                Edit
              </Button>
            ) : null}
          </Space>
          <Paragraph type="secondary" style={{ marginBottom: 0 }}>
            {displayVulnerabilityID(data?.id, data?.public_id)} • Submitted{" "}
            {submittedAt} • SLA deadline {slaDeadline}
          </Paragraph>
          {data?.tags?.length ? (
            <Space wrap>
              {data.tags.slice(0, 6).map((tag) => (
                <Tag key={tag}>{tag}</Tag>
              ))}
              {data.tags.length > 6 && <Tag>+{data.tags.length - 6}</Tag>}
            </Space>
          ) : null}
        </Space>
      </Card>

      <Row gutter={16}>
        <Col span={16}>
          <Card title="Overview" loading={loading} style={{ marginBottom: 16 }}>
            <Descriptions
              column={2}
              size="small"
              labelStyle={{ fontWeight: 600 }}
            >
              <Descriptions.Item label="Application">
                <Text ellipsis={{ tooltip: data?.application }}>
                  {data?.application || "—"}
                </Text>
              </Descriptions.Item>
              <Descriptions.Item label="Code Repository">
                {data?.code_repository ? (
                  <a
                    href={data.code_repository}
                    target="_blank"
                    rel="noreferrer"
                  >
                    <Text ellipsis={{ tooltip: data.code_repository }}>
                      {data.code_repository}
                    </Text>
                  </a>
                ) : (
                  "—"
                )}
              </Descriptions.Item>
              <Descriptions.Item label="Type">
                <Text ellipsis={{ tooltip: data?.vulnerability_type }}>
                  {data?.vulnerability_type || "—"}
                </Text>
              </Descriptions.Item>
              <Descriptions.Item label="Discovery Channel">
                <Text ellipsis={{ tooltip: data?.discovery_channel }}>
                  {data?.discovery_channel || "—"}
                </Text>
              </Descriptions.Item>
              <Descriptions.Item label="Discovery Phase">
                <Text ellipsis={{ tooltip: data?.discovery_phase }}>
                  {data?.discovery_phase || "—"}
                </Text>
              </Descriptions.Item>
              <Descriptions.Item label="Network Env">
                <Text ellipsis={{ tooltip: data?.network_env }}>
                  {data?.network_env || "—"}
                </Text>
              </Descriptions.Item>
              <Descriptions.Item label="Interface Path">
                <Text ellipsis={{ tooltip: data?.interface_path }}>
                  {data?.interface_path || "—"}
                </Text>
              </Descriptions.Item>
              <Descriptions.Item label="Source">
                <Text ellipsis={{ tooltip: data?.source }}>
                  {data?.source || "—"}
                </Text>
              </Descriptions.Item>
              <Descriptions.Item label="POC Verified">
                {data?.has_poc_verification ? "Yes" : "No"}
              </Descriptions.Item>
              <Descriptions.Item label="Third Party">
                {data?.is_third_party ? "Yes" : "No"}
              </Descriptions.Item>
              <Descriptions.Item label="SLA Deadline">
                {slaDeadline}
              </Descriptions.Item>
            </Descriptions>
          </Card>

          <Card title="Description" loading={loading}>
            <VulnerabilityHtml html={data?.description || ""} />
          </Card>
          {canViewSensitiveFields ? (
            <>
              <Card
                title="Verification Steps"
                style={{ marginTop: 16 }}
                loading={loading}
              >
                {canEditSensitive ? (
                  <Space
                    direction="vertical"
                    size={10}
                    style={{ width: "100%" }}
                  >
                    <Input.TextArea
                      rows={4}
                      value={verificationStepsInput}
                      placeholder="Document how the issue can be reproduced and verified."
                      onChange={(e) =>
                        setVerificationStepsInput(e.target.value)
                      }
                    />
                    <Button
                      type="primary"
                      loading={savingMeta}
                      onClick={handleSaveMeta}
                    >
                      Save Metadata
                    </Button>
                  </Space>
                ) : (
                  <Paragraph
                    style={{ whiteSpace: "pre-wrap", wordBreak: "break-word" }}
                  >
                    {data?.verification_steps || "Not provided."}
                  </Paragraph>
                )}
              </Card>
              <Card
                title="Proof of Concept"
                style={{ marginTop: 16 }}
                loading={loading}
              >
                {canEditSensitive ? (
                  <Space
                    direction="vertical"
                    size={10}
                    style={{ width: "100%" }}
                  >
                    <Input.TextArea
                      rows={4}
                      value={pocTextInput}
                      placeholder="Add proof-of-concept notes or links."
                      onChange={(e) => setPocTextInput(e.target.value)}
                    />
                    <Button
                      type="primary"
                      loading={savingMeta}
                      onClick={handleSaveMeta}
                    >
                      Save Metadata
                    </Button>
                  </Space>
                ) : (
                  <Paragraph
                    style={{ whiteSpace: "pre-wrap", wordBreak: "break-word" }}
                  >
                    {data?.poc_text || "Not provided."}
                  </Paragraph>
                )}
              </Card>
            </>
          ) : null}
        </Col>
        <Col span={8}>
          <Card title="Actions" loading={isLoading}>
            <Space direction="vertical" size={14} style={{ width: "100%" }}>
              <Space wrap>
                <Button
                  size="small"
                  loading={actionLoading === "claim"}
                  onClick={handleClaim}
                  disabled={!canClaim}
                >
                  Claim & Assign to Me
                </Button>
                <Button
                  size="small"
                  icon={<UserSwitchOutlined />}
                  disabled={!canAssign}
                  onClick={() => {
                    setAssignEmployeeId(data?.owner_employee_id ?? undefined);
                    setAssignModalOpen(true);
                  }}
                >
                  Assign Owner
                </Button>
                <Button
                  size="small"
                  icon={<CheckCircleOutlined />}
                  disabled={!canRequestRetest}
                  loading={actionLoading === "retesting"}
                  onClick={handleRequestRetest}
                >
                  Request Retest
                </Button>
                {canReopen && (
                  <Button
                    size="small"
                    icon={<ClockCircleOutlined />}
                    disabled={!canReopen}
                    loading={actionLoading === "active"}
                    onClick={() =>
                      triggerTransition(
                        "active",
                        "Active",
                        "Vulnerability reopened",
                      )
                    }
                  >
                    Reopen
                  </Button>
                )}
                <Dropdown
                  trigger={["click"]}
                  menu={{
                    items: [
                      {
                        key: "false_positive",
                        label: "False Positive",
                        onClick: () =>
                          triggerTransition("false_positive", "False Positive"),
                        disabled:
                          actionLoading === "false_positive" ||
                          !canMarkFalsePositive,
                      },
                      {
                        key: "risk_accepted",
                        label: "Risk Accepted",
                        onClick: () =>
                          triggerTransition("risk_accepted", "Risk Accepted"),
                        disabled:
                          actionLoading === "risk_accepted" ||
                          !canMarkRiskAccepted,
                      },
                    ],
                  }}
                >
                  <Button
                    size="small"
                    icon={<MoreOutlined />}
                    disabled={!canMarkFalsePositive && !canMarkRiskAccepted}
                  >
                    Close
                  </Button>
                </Dropdown>
                <Button
                  size="small"
                  icon={<CheckCircleOutlined />}
                  disabled={!canMarkFixed}
                  loading={actionLoading === "fixed"}
                  onClick={() => triggerTransition("fixed", "Fixed")}
                >
                  Mark Fixed
                </Button>
              </Space>
            </Space>
          </Card>

          <Card
            title={
              <Space>
                <ClockCircleOutlined />
                <span>Lifecycle</span>
              </Space>
            }
            style={{ marginTop: 16 }}
            loading={isLoading}
          >
            <div style={{ padding: "8px 0" }}>
              {lifecycleItems.length > 0 ? (
                <Steps
                  size="small"
                  direction="vertical"
                  items={lifecycleItems.map((item) => ({
                    title: (
                      <Space direction="vertical" size={2}>
                        <Text strong>{item.title}</Text>
                        {item.actor && (
                          <Text type="secondary" style={{ fontSize: 12 }}>
                            {item.actor}
                          </Text>
                        )}
                        <Text type="secondary" style={{ fontSize: 12 }}>
                          {item.time}
                        </Text>
                      </Space>
                    ),
                    status: item.status as
                      | "wait"
                      | "process"
                      | "finish"
                      | "error"
                      | undefined,
                  }))}
                />
              ) : (
                <Text type="secondary">No lifecycle events recorded.</Text>
              )}
            </div>
          </Card>

          <Card
            title="People & Time"
            style={{ marginTop: 16 }}
            loading={isLoading}
          >
            <Space direction="vertical" size={10}>
              <Space>
                <FieldTimeOutlined />
                <FieldLabel label="Submitted" />
                <Text>{submittedAt}</Text>
              </Space>
              <Space>
                <FieldTimeOutlined />
                <FieldLabel label="SLA Deadline" />
                <Text>{slaDeadline}</Text>
              </Space>
              {data?.claimed_at && (
                <Space>
                  <FieldTimeOutlined />
                  <FieldLabel label="Claimed" />
                  <Text>
                    {dayjs(data.claimed_at).format("YYYY-MM-DD HH:mm")}
                  </Text>
                </Space>
              )}
              {data?.fixed_at && (
                <Space>
                  <FieldTimeOutlined />
                  <FieldLabel label="Fixed" />
                  <Text>{dayjs(data.fixed_at).format("YYYY-MM-DD HH:mm")}</Text>
                </Space>
              )}
              {data?.closed_at && (
                <Space>
                  <FieldTimeOutlined />
                  <FieldLabel label="Closed" />
                  <Text>
                    {dayjs(data.closed_at).format("YYYY-MM-DD HH:mm")}
                  </Text>
                </Space>
              )}
              <Space>
                <DatabaseOutlined />
                <FieldLabel label="Owner" />
                <Text>{ownerLabel}</Text>
                {isOwner ? <Tag color="blue">You are the owner</Tag> : null}
              </Space>
              <Space>
                <CloudOutlined />
                <FieldLabel label="Submitter" />
                <Text>{data?.submitter?.name ?? "—"}</Text>
              </Space>
              <Space>
                <CloudOutlined />
                <FieldLabel label="Discoverer" />
                <Text>
                  {data?.discoverer?.name ?? data?.discoverer?.email ?? "—"}
                </Text>
              </Space>
              <Space>
                <CloudOutlined />
                <FieldLabel label="Fixer" />
                <Text>{data?.fixer?.name ?? data?.fixer?.email ?? "—"}</Text>
              </Space>
              <Space>
                <CloudOutlined />
                <FieldLabel label="Department" />
                <Text>
                  {data?.department?.name ?? data?.department_id ?? "—"}
                </Text>
              </Space>
            </Space>
          </Card>

          <Card title="Tags" style={{ marginTop: 16 }} loading={isLoading}>
            <Space direction="vertical" size={10} style={{ width: "100%" }}>
              <Input
                placeholder="Tags (comma separated)"
                value={tagsInput}
                disabled={!canEditTags}
                onChange={(e) => setTagsInput(e.target.value)}
              />
              <Button
                type="primary"
                loading={savingMeta}
                onClick={handleSaveMeta}
                disabled={!canEditTags}
              >
                Save
              </Button>
            </Space>
          </Card>

          <Card title="Comments" style={{ marginTop: 16 }} loading={isLoading}>
            <Space direction="vertical" size={10} style={{ width: "100%" }}>
              <List
                dataSource={comments}
                locale={{ emptyText: "No comments yet." }}
                renderItem={(item) => (
                  <List.Item>
                    <Space direction="vertical" size={2}>
                      <Text strong>{item.author_name || "System"}</Text>
                      <Text>{item.content}</Text>
                      <Text type="secondary" style={{ fontSize: 12 }}>
                        {formatTime(item.created_at)}
                      </Text>
                    </Space>
                  </List.Item>
                )}
              />
              <Input.TextArea
                rows={3}
                placeholder="Add a comment..."
                value={commentInput}
                disabled={!canComment}
                onChange={(e) => setCommentInput(e.target.value)}
              />
              <Button
                type="primary"
                onClick={handleAddComment}
                disabled={!canComment || !commentInput.trim()}
              >
                Post Comment
              </Button>
            </Space>
          </Card>

          {shouldShowAuthorizedViewers ? (
            <Card
              title="Authorized Viewers"
              style={{ marginTop: 16 }}
              loading={isLoading}
            >
              <Space direction="vertical" size={12} style={{ width: "100%" }}>
                <Space
                  align="center"
                  style={{ width: "100%", justifyContent: "space-between" }}
                >
                  <Space direction="vertical" size={0}>
                    <Text strong>Public visibility</Text>
                    <Text type="secondary" style={{ fontSize: 12 }}>
                      Allow all logged-in users to view this vulnerability without
                      being listed below.
                    </Text>
                  </Space>
                  <Switch
                    checked={Boolean(data?.is_public_viewable)}
                    loading={savingPublicVisibility}
                    disabled={!canManageAuthorizedViewers || isLoading}
                    onChange={handlePublicVisibilityChange}
                  />
                </Space>
                <Select<number[]>
                  mode="multiple"
                  showSearch
                  filterOption={false}
                  style={{ width: "100%" }}
                  value={authorizedViewerIds}
                  onChange={(value) => setAuthorizedViewerIds(value)}
                  onSearch={setEmployeeSearchQuery}
                  loading={loadingEmployees}
                  notFoundContent={
                    loadingEmployees
                      ? "Loading..."
                      : employeeSearchError ??
                        (employeeSearchQuery.trim()
                          ? "No employees"
                          : "Type to search employees")
                  }
                  placeholder="Select employees allowed to view this vulnerability before it is fixed"
                  options={employeeOptions.map((employee) => ({
                    value: employee.id,
                    label: `${employee.name}${employee.email ? ` (${employee.email})` : ""}`,
                  }))}
                />
                {employeeSearchError ? (
                  <Alert type="warning" showIcon message={employeeSearchError} />
                ) : null}
                <Button
                  type="primary"
                  onClick={handleSaveAuthorizedViewers}
                  loading={savingAuthorizedViewers}
                  disabled={!canManageAuthorizedViewers}
                >
                  Save Authorized Viewers
                </Button>
              </Space>
            </Card>
          ) : null}
        </Col>
      </Row>
      <Modal
        title="Assign Owner"
        open={assignModalOpen}
        onCancel={() => setAssignModalOpen(false)}
        onOk={handleAssign}
        okButtonProps={{ loading: actionLoading === "assign" }}
        okText="Assign"
        destroyOnClose
      >
        <Space direction="vertical" size={8} style={{ width: "100%" }}>
          <Text type="secondary">
            Select the employee responsible for remediation.
          </Text>
          <EmployeeDropdown
            value={assignEmployeeId}
            onChange={(val) => setAssignEmployeeId(val as number)}
          />
        </Space>
      </Modal>
    </Space>
  );
}

function getErrorStatus(error: unknown): number | undefined {
  if (typeof error !== "object" || error === null) return undefined;
  return (error as { response?: { status?: number } }).response?.status;
}
