"use client";

import { useCallback, useEffect, useMemo, useState, type Key } from "react";
import { Alert, Button, Card, Col, Descriptions, Drawer, InputNumber, Row, Select, Space, Statistic, Table, Tag, Tooltip, Typography, message } from "antd";
import type { ColumnsType, TablePaginationConfig } from "antd/es/table";
import { InfoCircleOutlined, PlusOutlined, ReloadOutlined } from "@ant-design/icons";
import dayjs from "dayjs";
import { useRouter } from "next/navigation";

import { PageStateNotice } from "@/components/common/page-state-notice";
import { exportCaasmPorts, fetchCaasmHighRiskPorts, fetchCaasmPortDetail, fetchCaasmPortStats, fetchCaasmPorts, fetchCaasmServices } from "@/lib/api/caasm";
import { createScanBatch, createScanClientRequestId } from "@/lib/api/scans";
import { useAuth } from "@/lib/hooks/use-auth";
import type { CaasmPortConfidence, CaasmPortDetail, CaasmPortEvidenceSection, CaasmPortEvidenceSignal, CaasmPortRecord, CaasmPortStats } from "@/types/models";

const { Title, Paragraph, Text } = Typography;

const protocolOptions = [
  { label: "TCP", value: "tcp" },
  { label: "UDP", value: "udp" },
  { label: "Other", value: "other" },
];

const exposureOptions = [
  { label: "Public", value: "public" },
  { label: "Internal", value: "internal" },
];

const statusOptions = [
  { label: "Open", value: "open" },
  { label: "Closed", value: "closed" },
  { label: "Filtered", value: "filtered" },
];

const observationSourceLabels: Record<string, string> = {
  security_group: "Security Group",
  security_group_rule: "Security Group Rule",
  listener: "Listener",
  service_endpoint: "Service Endpoint",
  task_mapping: "Task Mapping",
  inferred_web: "Inferred Web",
  scanner_confirmed: "Scanner Confirmed",
  unknown: "Unknown",
};

const evidenceSignalLabels: Record<string, string> = {
  inferred_web: "inferred_web",
  security_group_rule: "security_group_rule",
  scanner_confirmed: "scanner_confirmed",
};

const evidenceSignalColors: Record<string, string> = {
  inferred_web: "geekblue",
  security_group_rule: "gold",
  scanner_confirmed: "green",
};

const confidenceColors: Record<CaasmPortConfidence, string> = {
  low: "default",
  medium: "blue",
  high: "green",
};

const cloudServiceLabels: Record<string, string> = {
  s3: "S3",
  ec2: "EC2",
  rds: "RDS",
  elb: "ELB",
  route53: "Route53",
  cloudfront: "CloudFront",
  apigateway: "APIGateway",
  ecs: "ECS",
  eks: "EKS",
  elasticache: "ElastiCache",
  redshift: "Redshift",
  vpc: "VPC",
};

const EXPORT_PERMISSION = "caasm:export_ports";
const CREATE_SCAN_PERMISSION = "scan:create_batches";

const wrapTextStyle = {
  display: "inline-block",
  maxWidth: "100%",
  overflowWrap: "anywhere",
  whiteSpace: "normal",
  wordBreak: "break-word",
} as const;

function formatCloudServiceLabel(value?: string) {
  const normalized = (value || "").trim().toLowerCase();
  if (!normalized) return "Unknown";
  return cloudServiceLabels[normalized] || value || "Unknown";
}

function stringFromUnknown(value: unknown) {
  if (typeof value === "string") {
    return value.trim();
  }
  if (typeof value === "number" || typeof value === "boolean") {
    return String(value);
  }
  return "";
}

function firstString(...values: unknown[]) {
  for (const value of values) {
    const text = stringFromUnknown(value);
    if (text) {
      return text;
    }
  }
  return "";
}

function arrayFromUnknown(value: unknown): string[] {
  if (!Array.isArray(value)) {
    return [];
  }
  return value.map((item) => stringFromUnknown(item)).filter(Boolean);
}

function recordEvidenceObject(record?: CaasmPortRecord | null) {
  const evidence = record?.evidence;
  if (!evidence || Array.isArray(evidence) || typeof evidence !== "object") {
    return undefined;
  }
  return evidence as Record<string, unknown>;
}

function evidenceValue(record: CaasmPortRecord | undefined, keys: string[]) {
  const evidence = recordEvidenceObject(record);
  if (!evidence) {
    return "";
  }
  return firstString(...keys.map((key) => evidence[key]));
}

function evidenceArray(record: CaasmPortRecord | undefined, keys: string[]) {
  const evidence = recordEvidenceObject(record);
  if (!evidence) {
    return [];
  }
  for (const key of keys) {
    const values = arrayFromUnknown(evidence[key]);
    if (values.length) {
      return values;
    }
  }
  return [];
}

function assetMetadataValue(asset: CaasmPortDetail["asset"] | undefined | null, keys: string[]) {
  const metadata = asset?.metadata;
  if (!metadata) {
    return "";
  }
  return firstString(...keys.map((key) => metadata[key]));
}

function metadataValue(section: CaasmPortEvidenceSection | undefined, key: string) {
  const value = section?.metadata?.[key];
  if (Array.isArray(value)) {
    return value.filter(Boolean).join(", ");
  }
  if (typeof value === "boolean") {
    return value ? "Yes" : "No";
  }
  if (value === null || value === undefined || value === "") {
    return "—";
  }
  return String(value);
}

function metadataFirstValue(section: CaasmPortEvidenceSection | undefined, keys: string[]) {
  for (const key of keys) {
    const value = metadataValue(section, key);
    if (value !== "—") {
      return value;
    }
  }
  return "—";
}

function compactDate(value?: string) {
  return value ? dayjs(value).format("YYYY-MM-DD HH:mm") : "—";
}

function isIPAddressLike(value?: string) {
  const trimmed = value?.trim();
  if (!trimmed) return false;
  const ipv4Pattern =
    /^(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}$/;
  const ipv6Pattern = /^[0-9a-f:]+$/i;
  return ipv4Pattern.test(trimmed) || (trimmed.includes(":") && ipv6Pattern.test(trimmed));
}

function getEndpointValue(record: CaasmPortRecord) {
  return record.endpoint || record.ip_address || "";
}

function getEndpointType(record: CaasmPortRecord) {
  return record.endpoint_type || (isIPAddressLike(getEndpointValue(record)) ? "ip" : "hostname");
}

function getIPAddressValue(record: CaasmPortRecord) {
  const value = record.ip_address || record.endpoint || "";
  return isIPAddressLike(value) ? value : "";
}

function renderWrappedValue(value?: string, fallback = "—", maxWidth = 420) {
  const text = value || fallback;
  return (
    <Tooltip title={text}>
      <Text style={{ ...wrapTextStyle, maxWidth }}>{text}</Text>
    </Tooltip>
  );
}

function getPortSourceService(record: CaasmPortRecord, detail?: CaasmPortDetail | null) {
  return firstString(
    record.source_service,
    detail?.evidence.source_service,
    evidenceValue(record, ["source_service", "aws_service"]),
    metadataValue(detail?.evidence.security_group, "source_service"),
    metadataValue(detail?.evidence.route, "source_service"),
    record.asset_service,
    detail?.asset?.service,
  );
}

function getPortResourceID(record: CaasmPortRecord, detail?: CaasmPortDetail | null) {
  return firstString(
    record.resource_id,
    detail?.evidence.resource_id,
    evidenceValue(record, ["resource_id", "owning_resource", "owning_resource_id", "arn", "native_id"]),
    metadataValue(detail?.evidence.security_group, "resource_id"),
    metadataValue(detail?.evidence.route, "resource_id"),
    assetMetadataValue(detail?.asset, ["resource_id", "arn", "native_id"]),
    detail?.asset?.native_id,
    detail?.asset?.name,
  );
}

function getOwnershipStatus(record: CaasmPortRecord, detail?: CaasmPortDetail | null) {
  return firstString(
    record.ownership_status,
    detail?.evidence.ownership_status,
    evidenceValue(record, ["ownership_status"]),
    metadataValue(detail?.evidence.security_group, "ownership_status"),
    metadataValue(detail?.evidence.route, "ownership_status"),
  );
}

function ownershipStatusColor(status?: string) {
  const normalized = status?.toLowerCase();
  if (normalized === "verified" || normalized === "owned") {
    return "green";
  }
  if (normalized === "unverified" || normalized === "dns_unverified") {
    return "gold";
  }
  if (normalized === "external") {
    return "red";
  }
  return "default";
}

function formatDNSRecord(record: unknown) {
  if (typeof record === "string") {
    return record;
  }
  if (!record || typeof record !== "object") {
    return "";
  }
  const item = record as Record<string, unknown>;
  const name = firstString(item.name, item.domain, item.record_name);
  const type = firstString(item.type, item.record_type);
  const values = arrayFromUnknown(item.values);
  const value = firstString(item.value, item.target);
  const alias = item.alias_target && typeof item.alias_target === "object"
    ? firstString((item.alias_target as Record<string, unknown>).dns_name, (item.alias_target as Record<string, unknown>).hosted_zone_id)
    : "";
  return [name, type, values.join(", ") || value || alias].filter(Boolean).join(" ");
}

function normalizeDNSRecords(value: unknown) {
  if (Array.isArray(value)) {
    return value.map(formatDNSRecord).filter(Boolean);
  }
  if (value && typeof value === "object") {
    const objectValue = value as Record<string, unknown>;
    if (Array.isArray(objectValue.records)) {
      return objectValue.records.map(formatDNSRecord).filter(Boolean);
    }
    return [JSON.stringify(objectValue)];
  }
  const text = stringFromUnknown(value);
  return text ? [text] : [];
}

function getDNSRecords(record: CaasmPortRecord, detail?: CaasmPortDetail | null) {
  const direct = normalizeDNSRecords(record.dns_records);
  if (direct.length) {
    return direct;
  }
  const detailRecords = normalizeDNSRecords(detail?.evidence.dns_records);
  if (detailRecords.length) {
    return detailRecords;
  }
  const evidence = recordEvidenceObject(record);
  if (evidence) {
    const evidenceRecords = normalizeDNSRecords(evidence.dns_records);
    if (evidenceRecords.length) {
      return evidenceRecords;
    }
  }
  return normalizeDNSRecords(detail?.evidence.route.metadata?.dns_records ?? detail?.evidence.security_group.metadata?.dns_records);
}

function getResolutionIPs(record: CaasmPortRecord, detail?: CaasmPortDetail | null) {
  return [
    ...(record.resolution_ips || []),
    ...(detail?.evidence.resolution_ips || []),
    ...evidenceArray(record, ["resolution_ips", "resolved_ips", "dns_ips"]),
    ...arrayFromUnknown(detail?.evidence.route.metadata?.resolution_ips),
    ...arrayFromUnknown(detail?.evidence.security_group.metadata?.resolution_ips),
  ].filter((value, index, values) => Boolean(value) && values.indexOf(value) === index);
}

function signalFromObservationSource(source?: string): CaasmPortEvidenceSignal | null {
  if (source === "security_group" || source === "security_group_rule") {
    return "security_group_rule";
  }
  if (source === "inferred_web" || source === "service_endpoint") {
    return "inferred_web";
  }
  return null;
}

function addSignalsFromRecordEvidence(record: CaasmPortRecord, signals: Set<CaasmPortEvidenceSignal>) {
  const evidence = record.evidence;
  if (Array.isArray(evidence)) {
    evidence.forEach((signal) => signals.add(signal));
    return;
  }
  if (!evidence || typeof evidence !== "object") {
    return;
  }
  (Object.keys(evidence) as CaasmPortEvidenceSignal[]).forEach((key) => {
    if (key in evidenceSignalLabels && evidence[key]) {
      signals.add(key);
    }
  });
}

function scannerResultIsConfirmedOpen(result?: string) {
  const normalized = result?.trim().toLowerCase();
  return normalized === "open" || normalized === "confirmed_open" || normalized === "reachable";
}

function getEvidenceSignals(record: CaasmPortRecord, detail?: CaasmPortDetail | null): CaasmPortEvidenceSignal[] {
  const signals = new Set<CaasmPortEvidenceSignal>();
  addSignalsFromRecordEvidence(record, signals);
  record.evidence_sources?.forEach((source) => signals.add(source));
  if (record.evidence_source) {
    signals.add(record.evidence_source);
  }
  const observationSignal = signalFromObservationSource(record.observation_source);
  if (observationSignal) {
    signals.add(observationSignal);
  }
  if (scannerResultIsConfirmedOpen(detail?.evidence.scanner_result?.result)) {
    signals.add("scanner_confirmed");
  }
  return Array.from(signals);
}

function strongestConfidence(signals: CaasmPortEvidenceSignal[], explicit?: CaasmPortConfidence) {
  if (explicit) return explicit;
  if (signals.includes("scanner_confirmed")) return "high";
  if (signals.includes("security_group_rule")) return "medium";
  if (signals.includes("inferred_web")) return "low";
  return undefined;
}

function renderEvidenceTags(record: CaasmPortRecord, detail?: CaasmPortDetail | null) {
  const signals = getEvidenceSignals(record, detail);
  const confidence = strongestConfidence(signals, record.confidence);
  if (!signals.length) {
    return (
      <Space size={[4, 4]} wrap>
        <Tag>Not collected</Tag>
        {confidence ? <Tag color={confidenceColors[confidence]}>{confidence.toUpperCase()} confidence</Tag> : null}
      </Space>
    );
  }
  return (
    <Space size={[4, 4]} wrap>
      {signals.map((signal) => (
        <Tag key={signal} color={evidenceSignalColors[signal]}>
          {evidenceSignalLabels[signal]}
        </Tag>
      ))}
      {confidence ? <Tag color={confidenceColors[confidence]}>{confidence.toUpperCase()} confidence</Tag> : null}
    </Space>
  );
}

function renderScannerEvidenceTags(result?: string) {
  if (scannerResultIsConfirmedOpen(result)) {
    return (
      <Space size={[4, 4]} wrap>
        <Tag color={evidenceSignalColors.scanner_confirmed}>scanner_confirmed</Tag>
        <Tag color={confidenceColors.high}>HIGH confidence</Tag>
      </Space>
    );
  }
  return (
    <Space size={[4, 4]} wrap>
      <Tag>Scanner observed</Tag>
      <Tag color={confidenceColors.low}>LOW confidence</Tag>
    </Space>
  );
}

export default function PortIndexPage() {
  const router = useRouter();
  const { hasPermission } = useAuth();
  const [records, setRecords] = useState<CaasmPortRecord[]>([]);
  const [total, setTotal] = useState(0);
  const [loading, setLoading] = useState(false);
  const [exporting, setExporting] = useState(false);
  const [loadError, setLoadError] = useState<string | null>(null);
  const [stats, setStats] = useState<CaasmPortStats | null>(null);
  const [highRiskPorts, setHighRiskPorts] = useState<CaasmPortRecord[]>([]);
  const [filters, setFilters] = useState({
    port: undefined as number | undefined,
    protocol: undefined as string | undefined,
    exposure: undefined as string | undefined,
    status: undefined as string | undefined,
    asset_service: undefined as string | undefined,
  });
  const [pagination, setPagination] = useState<TablePaginationConfig>({ current: 1, pageSize: 20 });
  const [cloudServiceOptions, setCloudServiceOptions] = useState<{ label: string; value: string }[]>([]);
  const [selectedRowKeys, setSelectedRowKeys] = useState<Key[]>([]);
  const [selectedPortRows, setSelectedPortRows] = useState<CaasmPortRecord[]>([]);
  const [creatingScan, setCreatingScan] = useState(false);
  const [detailOpen, setDetailOpen] = useState(false);
  const [detailLoading, setDetailLoading] = useState(false);
  const [selectedPortDetail, setSelectedPortDetail] = useState<CaasmPortDetail | null>(null);
  const canExportPorts = hasPermission(EXPORT_PERMISSION);
  const canCreateScan = hasPermission(CREATE_SCAN_PERMISSION);
  const defaultFilters = useMemo(
    () => ({
      port: undefined as number | undefined,
      protocol: undefined as string | undefined,
      exposure: undefined as string | undefined,
      status: undefined as string | undefined,
      asset_service: undefined as string | undefined,
    }),
    [],
  );

  const loadData = useCallback(
    async (page: number, pageSize: number) => {
      setLoading(true);
      try {
        const payload = await fetchCaasmPorts({
          page,
          page_size: pageSize,
          port: filters.port,
          protocol: filters.protocol,
          exposure: filters.exposure,
          status: filters.status,
          asset_service: filters.asset_service,
        });
        setRecords(payload.items ?? []);
        setTotal(payload.total ?? 0);
        setLoadError(null);
      } catch (error) {
        console.error("Failed to load port index", error);
        message.error("Failed to load port inventory");
        setLoadError("The port inventory is temporarily unavailable.");
        setRecords([]);
        setTotal(0);
      } finally {
        setLoading(false);
      }
    },
    [filters],
  );

  const loadStats = useCallback(async () => {
    try {
      const payload = await fetchCaasmPortStats();
      setStats(payload);
    } catch (error) {
      console.error("Failed to load port stats", error);
    }
  }, []);

  const loadHighRiskPorts = useCallback(async () => {
    try {
      const data = await fetchCaasmHighRiskPorts();
      setHighRiskPorts(data);
    } catch (error) {
      console.error("Failed to load high-risk ports", error);
    }
  }, []);

  const activeFilters = useMemo(() => {
    const items: { label: string; value: string }[] = [];
    if (filters.port != null) {
      items.push({ label: "Port", value: String(filters.port) });
    }
    if (filters.protocol) {
      items.push({ label: "Protocol", value: filters.protocol.toUpperCase() });
    }
    if (filters.exposure) {
      items.push({ label: "Exposure", value: filters.exposure.toUpperCase() });
    }
    if (filters.status) {
      items.push({ label: "Status", value: filters.status.toUpperCase() });
    }
    if (filters.asset_service) {
      items.push({
        label: "Cloud service",
        value: formatCloudServiceLabel(filters.asset_service),
      });
    }
    return items;
  }, [filters.asset_service, filters.exposure, filters.port, filters.protocol, filters.status]);

  const hasActiveFilters = activeFilters.length > 0;
  const unsupportedSelectedRows = useMemo(
    () =>
      selectedPortRows.filter(
        (record) =>
          record.protocol?.toLowerCase() !== "tcp" ||
          record.exposure?.toLowerCase() !== "public" ||
          !record.ip_address,
      ),
    [selectedPortRows],
  );

  const resetFilters = useCallback(() => {
    setFilters(defaultFilters);
    setPagination((prev) => ({ ...prev, current: 1 }));
  }, [defaultFilters]);

  const handleExportPorts = useCallback(async () => {
    if (!canExportPorts || exporting) {
      return;
    }

    setExporting(true);
    try {
      const { blob, filename } = await exportCaasmPorts();
      const url = URL.createObjectURL(blob);
      const anchor = document.createElement("a");
      anchor.href = url;
      anchor.download = filename;
      anchor.rel = "noopener noreferrer";
      anchor.style.display = "none";
      document.body.appendChild(anchor);
      anchor.click();
      window.setTimeout(() => {
        URL.revokeObjectURL(url);
        anchor.remove();
      }, 0);
    } catch (error) {
      console.error("Failed to export port inventory", error);
      message.error("Failed to export port inventory");
    } finally {
      setExporting(false);
    }
  }, [canExportPorts, exporting]);

  const openPortDetail = useCallback(async (record: CaasmPortRecord) => {
    setDetailOpen(true);
    setDetailLoading(true);
    setSelectedPortDetail(null);
    try {
      const detail = await fetchCaasmPortDetail(record.id);
      setSelectedPortDetail(detail);
    } catch (error) {
      console.error("Failed to load port detail", error);
      message.error("Failed to load port exposure detail");
    } finally {
      setDetailLoading(false);
    }
  }, []);

  const handleCreateScan = useCallback(async () => {
    if (!canCreateScan || creatingScan || !selectedRowKeys.length || unsupportedSelectedRows.length) {
      return;
    }

    setCreatingScan(true);
    try {
      const batch = await createScanBatch({
        client_request_id: createScanClientRequestId(),
        source: "caasm_ports",
        target_ids: selectedRowKeys.map((key) => Number(key)).filter((id) => Number.isInteger(id) && id > 0),
        metadata: {
          source_page: "caasm_ports",
          filters,
        },
      });
      message.success("Port exposure scan created");
      setSelectedRowKeys([]);
      setSelectedPortRows([]);
      router.push(`/dashboard/scans/port-exposure/${batch.id}`);
    } catch (error) {
      console.error("Failed to create port exposure scan", error);
      message.error("Failed to create port exposure scan");
    } finally {
      setCreatingScan(false);
    }
  }, [canCreateScan, creatingScan, filters, router, selectedRowKeys, unsupportedSelectedRows.length]);

  useEffect(() => {
    const current = pagination.current ?? 1;
    const size = pagination.pageSize ?? 20;
    loadData(current, size);
  }, [loadData, pagination]);

  useEffect(() => {
    loadStats();
    loadHighRiskPorts();
  }, [loadStats, loadHighRiskPorts]);

  useEffect(() => {
    fetchCaasmServices()
      .then((services) =>
        setCloudServiceOptions(
          services.map((service) => ({
            label: formatCloudServiceLabel(service),
            value: service,
          })),
        ),
      )
      .catch((error) => {
        console.error("Failed to load cloud service options", error);
      });
  }, []);

  const columns: ColumnsType<CaasmPortRecord> = useMemo(
    () => [
      {
        title: "Asset ID",
        dataIndex: "asset_id",
        width: 120,
        render: (value: number) => <span style={{ whiteSpace: "nowrap" }}>{value}</span>,
      },
      {
        title: "Endpoint",
        dataIndex: "endpoint",
        width: 240,
        render: (_: string, record) => {
          const endpoint = getEndpointValue(record);
          const endpointType = getEndpointType(record);
          return (
            <Space direction="vertical" size={0} style={{ maxWidth: "100%" }}>
              {renderWrappedValue(endpoint, "—", 220)}
              <Tag color={endpointType === "ip" ? "blue" : "purple"} style={{ width: "fit-content" }}>
                {endpointType === "ip" ? "IP endpoint" : "Hostname endpoint"}
              </Tag>
            </Space>
          );
        },
      },
      {
        title: "IP Address",
        dataIndex: "ip_address",
        width: 180,
        ellipsis: { showTitle: false },
        render: (_: string, record) => {
          const ipAddress = getIPAddressValue(record);
          return ipAddress ? (
            <Tooltip title={ipAddress}>
              <Text code style={{ display: "block", maxWidth: 160 }} ellipsis>
                {ipAddress}
              </Text>
            </Tooltip>
          ) : (
            <Tooltip title="This port row is keyed by a hostname endpoint. No resolved IP address is present in the current payload.">
              <Tag>Not resolved</Tag>
            </Tooltip>
          );
        },
      },
      {
        title: "Port",
        dataIndex: "port",
        width: 80,
        render: (value: number) => <span style={{ whiteSpace: "nowrap" }}>{value}</span>,
      },
      {
        title: "Protocol",
        dataIndex: "protocol",
        width: 100,
        render: (value: string) => <span style={{ whiteSpace: "nowrap" }}>{value?.toUpperCase() || "—"}</span>,
      },
      {
        title: "Port Service",
        dataIndex: "service_name",
        width: 180,
        render: (value: string) => renderWrappedValue(value, "Unknown", 160),
      },
      {
        title: "Observed From",
        dataIndex: "observation_source",
        width: 170,
        render: (value: string | undefined) => {
          const label = observationSourceLabels[value ?? "unknown"] ?? value ?? "Unknown";
          return <Tag style={{ whiteSpace: "nowrap" }}>{label}</Tag>;
        },
      },
      {
        title: "Evidence / Confidence",
        key: "evidence",
        width: 240,
        render: (_: unknown, record) => renderEvidenceTags(record),
      },
      {
        title: "Source Service",
        key: "source_service",
        width: 170,
        render: (_: unknown, record) => renderWrappedValue(getPortSourceService(record), "Unknown", 150),
      },
      {
        title: "Ownership",
        key: "ownership_status",
        width: 150,
        render: (_: unknown, record) => {
          const status = getOwnershipStatus(record);
          return status ? (
            <Tooltip title={status === "unverified" ? "DNS observation is not independently attributed to an owned cloud resource." : status}>
              <Tag color={ownershipStatusColor(status)}>{status.replaceAll("_", " ").toUpperCase()}</Tag>
            </Tooltip>
          ) : (
            <Tag>Not reported</Tag>
          );
        },
      },
      {
        title: "Cloud Service",
        dataIndex: "asset_service",
        width: 160,
        render: (value: string) => renderWrappedValue(formatCloudServiceLabel(value), "Unknown", 140),
      },
      {
        title: "Exposure",
        dataIndex: "exposure",
        width: 110,
        render: (value: string) => (
          <Tag color={value === "public" ? "red" : "green"} style={{ whiteSpace: "nowrap" }}>
            {value?.toUpperCase() || "—"}
          </Tag>
        ),
      },
      {
        title: "Status",
        dataIndex: "status",
        width: 100,
        render: (value: string) => <Tag style={{ whiteSpace: "nowrap" }}>{value?.toUpperCase() || "—"}</Tag>,
      },
      {
        title: "Last seen",
        dataIndex: "last_seen_at",
        width: 180,
        render: (value: string | undefined) => (
          <span style={{ whiteSpace: "nowrap" }}>{value ? dayjs(value).format("YYYY-MM-DD HH:mm") : "—"}</span>
        ),
      },
      {
        title: "Action",
        key: "action",
        width: 120,
        fixed: "right",
        render: (_, record) => (
          <Button onClick={() => void openPortDetail(record)}>
            Details
          </Button>
        ),
      },
    ],
    [openPortDetail],
  );

  const handleFilterChange = (field: string, value: string | number | null) => {
    setFilters((prev) => ({ ...prev, [field]: value ?? undefined }));
    setPagination((prev) => ({ ...prev, current: 1 }));
  };

  const statsCardStyle = {
    height: "100%",
    width: "100%",
  } as const;

  const statsCardBodyStyle = {
    height: "100%",
  } as const;

  const statsGridStyle = {
    display: "grid",
    gap: 16,
    gridTemplateColumns: "repeat(auto-fit, minmax(280px, 1fr))",
    width: "100%",
  } as const;

  const filterGridStyle = {
    display: "grid",
    gap: 16,
    gridTemplateColumns: "repeat(auto-fit, minmax(220px, 1fr))",
    width: "100%",
  } as const;

  return (
    <Space direction="vertical" size={24} style={{ width: "100%" }}>
      <div style={statsGridStyle}>
        <div style={{ display: "flex" }}>
          <Card style={statsCardStyle} styles={{ body: statsCardBodyStyle }}>
            <Statistic title="Open ports indexed" value={stats?.total ?? 0} />
            <Paragraph type="secondary" style={{ marginTop: 8 }}>
              Updated {stats?.last_updated ? dayjs(stats.last_updated).format("YYYY-MM-DD HH:mm") : "recently"}
            </Paragraph>
          </Card>
        </div>
        <div style={{ display: "flex" }}>
          <Card style={statsCardStyle} styles={{ body: statsCardBodyStyle }}>
            <Statistic title="Public exposure" value={stats?.public ?? 0} />
            <Paragraph type="secondary" style={{ marginTop: 8 }}>
              {stats ? `${stats.public} internet-facing` : "No data"}
            </Paragraph>
          </Card>
        </div>
        <div style={{ display: "flex" }}>
          <Card style={statsCardStyle} styles={{ body: statsCardBodyStyle }}>
            <Statistic title="Internal exposure" value={stats?.internal ?? 0} />
            <Paragraph type="secondary" style={{ marginTop: 8 }}>
              {stats ? `${stats.internal} internal-only` : "No data"}
            </Paragraph>
          </Card>
        </div>
      </div>

      <Card>
        <Space direction="vertical" size={16} style={{ width: "100%" }}>
          <Space align="start" style={{ justifyContent: "space-between", width: "100%" }} wrap>
            <div>
              <Title level={4} style={{ marginBottom: 0 }}>
                Port search
              </Title>
              <Paragraph type="secondary">
                Filter indexed ports by protocol, exposure, status, or cloud service source.
              </Paragraph>
            </div>
            <Space wrap>
              {canCreateScan ? (
                <Tooltip
                  title={
                    unsupportedSelectedRows.length
                      ? "The scanner accepts only public IPv4 TCP rows. Unsupported rows will be rejected by backend validation."
                      : selectedRowKeys.length
                        ? "Create a port exposure scan from the selected CAASM port rows."
                        : "Select public TCP port rows to start a port exposure scan."
                  }
                >
                  <Button
                    type="primary"
                    icon={<PlusOutlined />}
                    loading={creatingScan}
                    disabled={!selectedRowKeys.length || Boolean(unsupportedSelectedRows.length)}
                    onClick={() => void handleCreateScan()}
                  >
                    Start Port Exposure Scan
                  </Button>
                </Tooltip>
              ) : null}
              {canExportPorts ? (
                <Button loading={exporting} onClick={() => void handleExportPorts()}>
                  Export
                </Button>
              ) : null}
              <Button icon={<ReloadOutlined />} onClick={resetFilters} disabled={!hasActiveFilters}>
                Reset filters
              </Button>
            </Space>
          </Space>
          <div style={filterGridStyle}>
            <div>
              <Space size={6} style={{ display: "flex", marginBottom: 8 }}>
                <Text type="secondary">Port</Text>
                <Tooltip title="Leave this blank to browse every indexed port, or enter a specific port like 22 or 443 to narrow the list.">
                  <InfoCircleOutlined style={{ color: "#64748b", cursor: "help" }} />
                </Tooltip>
              </Space>
              <InputNumber
                value={filters.port}
                placeholder="e.g. 22 or 443"
                style={{ width: "100%" }}
                min={1}
                max={65535}
                onChange={(value) => handleFilterChange("port", value ?? null)}
              />
            </div>
            <div>
              <Text type="secondary" style={{ display: "block", marginBottom: 8 }}>
                Protocol
              </Text>
              <Select
                allowClear
                style={{ width: "100%" }}
                options={protocolOptions}
                value={filters.protocol}
                onChange={(value) => handleFilterChange("protocol", value)}
              />
            </div>
            <div>
              <Text type="secondary" style={{ display: "block", marginBottom: 8 }}>
                Exposure
              </Text>
              <Select
                allowClear
                style={{ width: "100%" }}
                options={exposureOptions}
                value={filters.exposure}
                onChange={(value) => handleFilterChange("exposure", value)}
              />
            </div>
            <div>
              <Text type="secondary" style={{ display: "block", marginBottom: 8 }}>
                Status
              </Text>
              <Select
                allowClear
                style={{ width: "100%" }}
                options={statusOptions}
                value={filters.status}
                onChange={(value) => handleFilterChange("status", value)}
              />
            </div>
            <div>
              <Text type="secondary" style={{ display: "block", marginBottom: 8 }}>
                Cloud Service
              </Text>
              <Select
                allowClear
                style={{ width: "100%" }}
                options={cloudServiceOptions}
                value={filters.asset_service}
                onChange={(value) => handleFilterChange("asset_service", value)}
              />
            </div>
          </div>
          <div>
            <Space align="center" size={8} wrap style={{ marginBottom: 8 }}>
              <Text strong>Active filters</Text>
              <Tag color={hasActiveFilters ? "blue" : "default"}>{hasActiveFilters ? `${activeFilters.length} active` : "None"}</Tag>
            </Space>
            {hasActiveFilters ? (
              <Space wrap>
                {activeFilters.map((item) => (
                  <Tag key={`${item.label}:${item.value}`}>{item.label}: {item.value}</Tag>
                ))}
              </Space>
            ) : (
              <Paragraph type="secondary" style={{ marginBottom: 0 }}>
                No filters are applied. Leave the port field blank to review the full indexed inventory.
              </Paragraph>
            )}
          </div>
          <Table
            rowKey="id"
            dataSource={records}
            columns={columns}
            loading={loading}
            rowSelection={
              canCreateScan
                ? {
                    selectedRowKeys,
                    onChange: (nextKeys, nextRows) => {
                      setSelectedRowKeys(nextKeys);
                      setSelectedPortRows(nextRows);
                    },
                    getCheckboxProps: (record) => ({
                      disabled: record.protocol?.toLowerCase() !== "tcp" || record.exposure?.toLowerCase() !== "public",
                      title:
                        record.protocol?.toLowerCase() !== "tcp" || record.exposure?.toLowerCase() !== "public"
                          ? "Port exposure scans support public TCP rows only."
                          : "Select this public TCP row for a port exposure scan.",
                    }),
                  }
                : undefined
            }
            locale={{
              emptyText: loadError ? (
                <PageStateNotice
                  tone="error"
                  compact
                  title="Port inventory unavailable"
                  description={`${loadError} Refresh the page or return after the next CAASM sync.`}
                  actions={
                    <Space wrap>
                      <Button icon={<ReloadOutlined />} onClick={() => void loadData(pagination.current ?? 1, pagination.pageSize ?? 20)}>
                        Retry
                      </Button>
                      <Button type="primary" href="/dashboard/caasm/overview">
                        Open CAASM overview
                      </Button>
                    </Space>
                  }
                />
              ) : hasActiveFilters ? (
                <PageStateNotice
                  tone="empty"
                  compact
                  title="No ports match the current filters"
                  description="Clear or broaden the filters to keep exploring the indexed port inventory."
                  actions={
                    <Space wrap>
                      <Button icon={<ReloadOutlined />} onClick={resetFilters}>
                        Reset filters
                      </Button>
                      <Button type="primary" href="/dashboard/caasm/cloud-accounts">
                        Review cloud accounts
                      </Button>
                    </Space>
                  }
                />
              ) : (
                <PageStateNotice
                  tone="empty"
                  compact
                  title="No ports have been indexed yet"
                  description="Leave the port field blank to browse everything once inventory data is available, or run another CAASM sync if you expect exposure data to exist."
                  actions={
                    <Space wrap>
                      <Button icon={<ReloadOutlined />} onClick={() => void loadData(pagination.current ?? 1, pagination.pageSize ?? 20)}>
                        Refresh inventory
                      </Button>
                      <Button type="primary" href="/dashboard/caasm/cloud-accounts">
                        Open cloud accounts
                      </Button>
                    </Space>
                  }
                />
              ),
            }}
            pagination={{ ...pagination, total }}
            onChange={(pager) => setPagination(pager)}
            scroll={{ x: 2000 }}
          />
        </Space>
      </Card>

      <Row gutter={[16, 16]}>
        <Col xs={24} md={12}>
          <Card title="Top open ports">
            {stats?.top_open_ports?.length ? (
              <Space direction="vertical" style={{ width: "100%" }}>
                {stats.top_open_ports.map((entry) => (
                  <div key={entry.port} style={{ display: "flex", justifyContent: "space-between" }}>
                    <span>Port {entry.port}</span>
                    <Tag>{entry.count}</Tag>
                  </div>
                ))}
              </Space>
            ) : (
              <Paragraph type="secondary">No aggregated data yet.</Paragraph>
            )}
          </Card>
        </Col>
        <Col xs={24} md={12}>
          <Card title="Status distribution">
            {stats ? (
              <Space direction="vertical" style={{ width: "100%" }}>
                {Object.entries(stats.by_status ?? {}).map(([key, value]) => (
                  <div key={key} style={{ display: "flex", justifyContent: "space-between" }}>
                    <span>{key.toUpperCase()}</span>
                    <Tag>{value}</Tag>
                  </div>
                ))}
              </Space>
            ) : (
              <Paragraph type="secondary">No data</Paragraph>
            )}
          </Card>
        </Col>
      </Row>

      {highRiskPorts?.length > 0 && (
        <Card title="High-risk ports detected" style={{ borderColor: "#ff4d4f" }}>
          <Table
            rowKey="id"
            dataSource={highRiskPorts}
            columns={columns}
            pagination={false}
            size="small"
            scroll={{ x: 1100 }}
          />
        </Card>
      )}

      <Drawer
        title="Port exposure detail"
        width={640}
        open={detailOpen}
        onClose={() => setDetailOpen(false)}
        destroyOnClose
      >
        {detailLoading ? (
          <PageStateNotice tone="empty" compact title="Loading exposure evidence" description="Fetching asset, route, rule, and scanner context." />
        ) : selectedPortDetail ? (
          <Space direction="vertical" size={16} style={{ width: "100%" }}>
            <Card size="small" title="Exposure reason">
              <Paragraph>{selectedPortDetail.evidence.exposure_reason}</Paragraph>
              <Descriptions size="small" column={1}>
                <Descriptions.Item label="Endpoint">
                  {renderWrappedValue(getEndpointValue(selectedPortDetail.port))}
                </Descriptions.Item>
                <Descriptions.Item label="Endpoint type">
                  <Tag color={getEndpointType(selectedPortDetail.port) === "ip" ? "blue" : "purple"}>
                    {getEndpointType(selectedPortDetail.port) === "ip" ? "IP endpoint" : "Hostname endpoint"}
                  </Tag>
                </Descriptions.Item>
                <Descriptions.Item label="IP address">
                  {getIPAddressValue(selectedPortDetail.port) ? (
                    <Text code>{getIPAddressValue(selectedPortDetail.port)}</Text>
                  ) : (
                    <Tooltip title="This endpoint is a hostname. The current port payload does not include a resolved IP address.">
                      <Tag>Not resolved</Tag>
                    </Tooltip>
                  )}
                </Descriptions.Item>
                <Descriptions.Item label="Port">{selectedPortDetail.port.port}/{selectedPortDetail.port.protocol?.toUpperCase()}</Descriptions.Item>
                <Descriptions.Item label="Exposure">
                  <Tag color={selectedPortDetail.port.exposure === "public" ? "red" : "green"}>
                    {selectedPortDetail.port.exposure?.toUpperCase() || "—"}
                  </Tag>
                </Descriptions.Item>
                <Descriptions.Item label="Observed from">
                  {observationSourceLabels[selectedPortDetail.port.observation_source ?? "unknown"] ?? selectedPortDetail.port.observation_source ?? "Unknown"}
                </Descriptions.Item>
                <Descriptions.Item label="Source service">
                  {renderWrappedValue(getPortSourceService(selectedPortDetail.port, selectedPortDetail), "Unknown")}
                </Descriptions.Item>
                <Descriptions.Item label="Owning resource">
                  {renderWrappedValue(getPortResourceID(selectedPortDetail.port, selectedPortDetail))}
                </Descriptions.Item>
                <Descriptions.Item label="Ownership status">
                  {(() => {
                    const status = getOwnershipStatus(selectedPortDetail.port, selectedPortDetail);
                    return status ? (
                      <Tooltip title={status === "unverified" ? "DNS evidence is observed but not independently attributed to an owned resource." : status}>
                        <Tag color={ownershipStatusColor(status)}>{status.replaceAll("_", " ").toUpperCase()}</Tag>
                      </Tooltip>
                    ) : (
                      <Tag>Not reported</Tag>
                    );
                  })()}
                </Descriptions.Item>
                <Descriptions.Item label="Evidence / confidence">
                  {renderEvidenceTags(selectedPortDetail.port, selectedPortDetail)}
                </Descriptions.Item>
                <Descriptions.Item label="Last seen">{compactDate(selectedPortDetail.port.last_seen_at)}</Descriptions.Item>
              </Descriptions>
            </Card>

            <Card size="small" title="DNS observed">
              {(() => {
                const dnsRecords = getDNSRecords(selectedPortDetail.port, selectedPortDetail);
                const resolutionIPs = getResolutionIPs(selectedPortDetail.port, selectedPortDetail);
                const ownershipStatus = getOwnershipStatus(selectedPortDetail.port, selectedPortDetail);
                if (!dnsRecords.length && !resolutionIPs.length && !ownershipStatus) {
                  return <Alert type="info" showIcon message="No DNS evidence is attached to this port observation." />;
                }
                return (
                  <Space direction="vertical" size={12} style={{ width: "100%" }}>
                    {ownershipStatus ? (
                      <Alert
                        type={ownershipStatus === "unverified" || ownershipStatus === "dns_unverified" ? "warning" : "info"}
                        showIcon
                        message={`Ownership ${ownershipStatus.replaceAll("_", " ")}`}
                        description={
                          ownershipStatus === "unverified" || ownershipStatus === "dns_unverified"
                            ? "DNS-derived observations remain evidence only until independently attributed to an owned resource."
                            : undefined
                        }
                      />
                    ) : null}
                    {dnsRecords.length ? (
                      <Descriptions size="small" column={1}>
                        <Descriptions.Item label="DNS records">
                          <Space direction="vertical" size={4} style={{ width: "100%" }}>
                            {dnsRecords.map((record, index) => (
                              <span key={`${record}:${index}`}>{renderWrappedValue(record)}</span>
                            ))}
                          </Space>
                        </Descriptions.Item>
                      </Descriptions>
                    ) : null}
                    {resolutionIPs.length ? (
                      <Descriptions size="small" column={1}>
                        <Descriptions.Item label="Resolution IPs">
                          <Space size={[4, 4]} wrap>
                            {resolutionIPs.map((ip) => (
                              <Tooltip key={ip} title="DNS resolution evidence only. This is not displayed as the asset IP unless the backend reports it as ip_address.">
                                <Tag>{ip}</Tag>
                              </Tooltip>
                            ))}
                          </Space>
                        </Descriptions.Item>
                      </Descriptions>
                    ) : null}
                  </Space>
                );
              })()}
            </Card>

            <Card size="small" title="Asset">
              {selectedPortDetail.asset ? (
                <Descriptions size="small" column={1}>
                  <Descriptions.Item label="Name">{renderWrappedValue(selectedPortDetail.asset.name)}</Descriptions.Item>
                  <Descriptions.Item label="Native ID">{renderWrappedValue(selectedPortDetail.asset.native_id)}</Descriptions.Item>
                  <Descriptions.Item label="Service">{formatCloudServiceLabel(selectedPortDetail.asset.service)}</Descriptions.Item>
                  <Descriptions.Item label="Cloud account">{selectedPortDetail.asset.cloud_account?.name || selectedPortDetail.asset.cloud_account_id || "—"}</Descriptions.Item>
                  <Descriptions.Item label="Region">{selectedPortDetail.asset.region || "—"}</Descriptions.Item>
                  <Descriptions.Item label="Owner">{selectedPortDetail.asset.owner_employee?.name || "—"}</Descriptions.Item>
                  <Descriptions.Item label="Asset last seen">{compactDate(selectedPortDetail.asset.last_seen_at)}</Descriptions.Item>
                </Descriptions>
              ) : (
                <Paragraph type="secondary">No asset context is attached to this port.</Paragraph>
              )}
            </Card>

            <Card size="small" title="Security group rule">
              <Alert
                type={selectedPortDetail.evidence.security_group.available ? "info" : "warning"}
                showIcon
                message={selectedPortDetail.evidence.security_group.summary}
              />
              <Descriptions size="small" column={1} style={{ marginTop: 12 }}>
                <Descriptions.Item label="Evidence">
                  {selectedPortDetail.evidence.security_group.available ? (
                    <Space size={[4, 4]} wrap>
                      <Tag color={evidenceSignalColors.security_group_rule}>security_group_rule</Tag>
                      <Tag color={confidenceColors.medium}>MEDIUM confidence</Tag>
                    </Space>
                  ) : (
                    <Tag>Not collected</Tag>
                  )}
                </Descriptions.Item>
                <Descriptions.Item label="Security groups">
                  {renderWrappedValue(metadataValue(selectedPortDetail.evidence.security_group, "security_groups"))}
                </Descriptions.Item>
                <Descriptions.Item label="Rule">
                  {renderWrappedValue(metadataFirstValue(selectedPortDetail.evidence.security_group, ["security_group_rule", "rule", "ingress_rule"]))}
                </Descriptions.Item>
                <Descriptions.Item label="CIDR/source">
                  {renderWrappedValue(metadataFirstValue(selectedPortDetail.evidence.security_group, ["cidr", "source_cidr", "source_group", "source"]))}
                </Descriptions.Item>
                <Descriptions.Item label="Observation source">
                  {metadataValue(selectedPortDetail.evidence.security_group, "observation_source")}
                </Descriptions.Item>
              </Descriptions>
            </Card>

            <Card size="small" title="Route and network posture">
              <Alert
                type={selectedPortDetail.evidence.route.available ? "info" : "warning"}
                showIcon
                message={selectedPortDetail.evidence.route.summary}
              />
              <Descriptions size="small" column={1} style={{ marginTop: 12 }}>
                <Descriptions.Item label="Evidence">
                  {selectedPortDetail.evidence.route.available ? <Tag color="blue">Route metadata collected</Tag> : <Tag>Not collected</Tag>}
                </Descriptions.Item>
                <Descriptions.Item label="VPC">{metadataValue(selectedPortDetail.evidence.route, "vpc_id")}</Descriptions.Item>
                <Descriptions.Item label="Subnet">{metadataValue(selectedPortDetail.evidence.route, "subnet_id")}</Descriptions.Item>
                <Descriptions.Item label="Subnet public">{metadataValue(selectedPortDetail.evidence.route, "is_public")}</Descriptions.Item>
                <Descriptions.Item label="Route table">
                  {renderWrappedValue(metadataFirstValue(selectedPortDetail.evidence.route, ["route_table_id", "route_table"]))}
                </Descriptions.Item>
                <Descriptions.Item label="Internet route">
                  {renderWrappedValue(metadataFirstValue(selectedPortDetail.evidence.route, ["internet_gateway_id", "egress", "route"]))}
                </Descriptions.Item>
              </Descriptions>
            </Card>

            <Card size="small" title="Scanner result">
              {selectedPortDetail.evidence.scanner_result ? (
                <Descriptions size="small" column={1}>
                  <Descriptions.Item label="Evidence">
                    {renderScannerEvidenceTags(selectedPortDetail.evidence.scanner_result.result)}
                  </Descriptions.Item>
                  <Descriptions.Item label="Result">
                    <Tag>{selectedPortDetail.evidence.scanner_result.result.replaceAll("_", " ").toUpperCase()}</Tag>
                  </Descriptions.Item>
                  <Descriptions.Item label="Reason">{selectedPortDetail.evidence.scanner_result.reason_code || "—"}</Descriptions.Item>
                  <Descriptions.Item label="Request ID">
                    {renderWrappedValue(selectedPortDetail.evidence.scanner_result.request_id)}
                  </Descriptions.Item>
                  <Descriptions.Item label="Connect time">
                    {typeof selectedPortDetail.evidence.scanner_result.connect_ms === "number"
                      ? `${selectedPortDetail.evidence.scanner_result.connect_ms} ms`
                      : "—"}
                  </Descriptions.Item>
                  <Descriptions.Item label="Observed at">{compactDate(selectedPortDetail.evidence.scanner_result.observed_at)}</Descriptions.Item>
                </Descriptions>
              ) : (
                <Alert type="warning" showIcon message="No scanner result is linked to this endpoint and port yet." />
              )}
            </Card>

            {selectedPortDetail.evidence.warnings?.length ? (
              <Alert
                type="warning"
                showIcon
                message="Evidence limitations"
                description={
                  <Space direction="vertical" size={4}>
                    {selectedPortDetail.evidence.warnings.map((warning) => (
                      <Text key={warning}>{warning}</Text>
                    ))}
                  </Space>
                }
              />
            ) : null}
          </Space>
        ) : (
          <PageStateNotice tone="empty" compact title="No detail loaded" description="Select a port row to inspect exposure evidence." />
        )}
      </Drawer>
    </Space>
  );
}
