import { type ReactNode, useMemo, useState } from "react";
import {
  ArrowRight,
  ChevronRight,
  Eye,
  MoreHorizontal,
  PackageCheck,
  Printer,
  RefreshCw,
  Ruler,
  Trash,
  Truck,
} from "lucide-react";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import type { ColumnDef } from "@edr/ui-common";
import { DataTable, DataTableFooter, usePagination } from "@edr/ui-common";
import {
  ActionIcon,
  Badge,
  Box,
  Button,
  Card,
  Checkbox,
  Divider,
  Group,
  Menu,
  Modal,
  NumberInput,
  Select,
  SimpleGrid,
  Stack,
  Text,
  TextInput,
  UnstyledButton,
  Alert,
} from "@mantine/core";

import { ruleEngineTable } from "@/components/ruleEngine/ruleEngineStyles";
import { FirstMileContainerAllocationTable } from "@/components/FirstMileContainerAllocationTable";
import { ReceiveInventoryModal } from "@/components/warehouses/ReceiveInventoryModal";
import { QUERY_KEYS } from "@/constants/QUERY_KEYS";
import { useToast } from "@/hooks/use-toast";
import {
  FIRST_MILE_STATUSES,
  type FirstMileApiStatus,
  type FirstMileRecord,
  firstMileService,
} from "@/services/first-mile.service";
import { bookingsService } from "@/services/bookings.service";
import { vehiclesService } from "@/services/vehicles.service";
import { ratesService } from "@/services/rates.service";
import { api } from "@/auth/http";
import type { BookingDetail } from "@/types/booking";

const formatPrice = (amount: number) =>
  `ETB ${amount.toLocaleString("en-US", {
    minimumFractionDigits: 2,
    maximumFractionDigits: 2,
  })}`;

const STATUS_META: Record<FirstMileApiStatus, { label: string; color: string }> = {
  PAYMENT_PENDING: { label: "Payment Pending", color: "yellow" },
  READY_TO_TRANSIT: { label: "Ready to Transit", color: "blue" },
  IN_TRANSIT: { label: "In Transit", color: "indigo" },
  RECEIVED_TO_PORT: { label: "Received to Port", color: "green" },
};

const NEXT_STATUS: Partial<Record<FirstMileApiStatus, FirstMileApiStatus>> = {
  PAYMENT_PENDING: "READY_TO_TRANSIT",
  READY_TO_TRANSIT: "IN_TRANSIT",
  IN_TRANSIT: "RECEIVED_TO_PORT",
};

type AssignmentStatus = "ASSIGNED" | "UNASSIGNED";
type StatusFilter = "ALL" | FirstMileApiStatus | AssignmentStatus;

const FILTER_OPTIONS: { value: StatusFilter; label: string }[] = [
  { value: "ALL", label: "All" },
  ...FIRST_MILE_STATUSES.filter((s) => s !== "PAYMENT_PENDING").map((s) => ({ value: s as StatusFilter, label: STATUS_META[s].label })),
  { value: "ASSIGNED", label: "Assigned" },
  { value: "UNASSIGNED", label: "Unassigned" },
];

const vehicleLabel = (record: FirstMileRecord) => {
  if (!record.vehicle) return null;
  const v = record.vehicle;
  const parts = [`${v.manufacturer} ${v.model}`, v.plateNumber];
  if (v.code) parts.unshift(v.code);
  const plates = [v.powerPlateNo, v.trailerPlateNo].filter(Boolean).join(" / ");
  if (plates) parts.push(plates);
  return parts.join(" · ");
};

const isAssigned = (record: FirstMileRecord) => Boolean(record.vehicleId);

// Map API record → display fields used in modals and trip slip
const bookingRef = (r: FirstMileRecord) => r.booking?.reference ?? r.bookingId;
const customerName = (r: FirstMileRecord) => r.booking?.company?.name ?? "—";
const pickupLocation = (r: FirstMileRecord) => r.booking?.firstMilePickupAddress ?? "—";
const cargoDesc = (r: FirstMileRecord) => {
  const parts = [r.booking?.cargoType?.label ?? r.booking?.cargoFreeText].filter(Boolean);
  if (r.booking?.cargoTotalWeightVgm) parts.push(`${r.booking.cargoTotalWeightVgm} t`);
  return parts.join(" · ") || "—";
};
// First-mile destination is the origin yard (pickup → origin yard)
const destinationYardName = (r: FirstMileRecord) =>
  r.booking?.originYard?.label ?? "—";
const contactPersonName = (r: FirstMileRecord) =>
  r.booking?.company?.contactPersonName ?? "—";
const contactPhone = (r: FirstMileRecord) =>
  r.booking?.company?.contactPersonPhone ?? r.booking?.company?.phone ?? "—";
const requestedDate = (r: FirstMileRecord) => {
  const d = r.booking?.scheduledDate;
  return d ? new Date(d).toISOString().slice(0, 10) : "—";
};
const serviceTypeName = (r: FirstMileRecord) =>
  r.booking?.serviceType?.label ?? "—";

const InfoRow = ({ label, value }: { label: string; value: string }) => (
  <Stack gap={2}>
    <Text size="xs" c="dimmed" tt="uppercase" fw={600}>
      {label}
    </Text>
    <Text size="sm">{value}</Text>
  </Stack>
);

const BookingInfo = ({ record }: { record: FirstMileRecord }) => {
  const hasPickupAddress = record.booking?.firstMilePickupAddress != null;
  return (
    <Card radius="md" padding="md" withBorder bg="var(--mantine-color-gray-0)">
      <Stack gap="sm">
        <Group justify="space-between">
          <Text fw={600}>{bookingRef(record)}</Text>
          <Group gap="xs">
            <Badge color={STATUS_META[record.status].color} variant="light" size="sm">
              {STATUS_META[record.status].label}
            </Badge>
            <Badge
              color={isAssigned(record) ? "green" : "orange"}
              variant="light"
              size="sm"
            >
              {isAssigned(record) ? "Assigned" : "Unassigned"}
            </Badge>
          </Group>
        </Group>
        <SimpleGrid cols={2} spacing="sm">
          <InfoRow label="Customer" value={customerName(record)} />
          <InfoRow label="Service type" value={serviceTypeName(record)} />
          {hasPickupAddress && <InfoRow label="Pickup location" value={pickupLocation(record)} />}
          <InfoRow label="Destination (origin yard)" value={destinationYardName(record)} />
          <InfoRow label="Cargo" value={cargoDesc(record)} />
          <InfoRow label="Advanced Payment" value={formatPrice(record.advancedPayment)} />
          <InfoRow label="Post Payment" value={formatPrice(record.remainingPayment)} />
          <InfoRow label="Contact" value={contactPersonName(record)} />
          <InfoRow label="Phone" value={contactPhone(record)} />
          <InfoRow label="Requested date" value={requestedDate(record)} />
          <InfoRow label="Assigned vehicle" value={vehicleLabel(record) ?? "—"} />
          <InfoRow label="Est. Distance (KM)" value={record.estimatedKm != null ? String(record.estimatedKm) : "—"} />
          <InfoRow label="Actual Distance (KM)" value={record.exactKm != null ? String(record.exactKm) : "—"} />
        </SimpleGrid>
      </Stack>
    </Card>
  );
};

const tripSlipRows = (record: FirstMileRecord): [string, string][] => [
  ["Customer", customerName(record)],
  ["Service", serviceTypeName(record)],
  ["Pickup location", pickupLocation(record)],
  ["Destination yard", destinationYardName(record)],
  ["Cargo", cargoDesc(record)],
  ["Advanced Payment", formatPrice(record.advancedPayment)],
  ["Post Payment", formatPrice(record.remainingPayment)],
  ["Vehicle", vehicleLabel(record) ?? "Unassigned"],
  ["Contact", `${contactPersonName(record)} · ${contactPhone(record)}`],
  ["Requested date", requestedDate(record)],
  ["Est. Distance (KM)", record.estimatedKm != null ? String(record.estimatedKm) : "—"],
  ["Actual Distance (KM)", record.exactKm != null ? String(record.exactKm) : "—"],
  ["Status", STATUS_META[record.status].label],
];

const SampleStamp = () => (
  <Box style={{ height: 96, display: "flex", alignItems: "center" }}>
    <Box
      style={{
        width: 96,
        height: 96,
        borderRadius: "50%",
        border: "2px solid var(--mantine-color-teal-7)",
        transform: "rotate(-12deg)",
        display: "flex",
        alignItems: "center",
        justifyContent: "center",
      }}
    >
      <Box
        style={{
          width: 82,
          height: 82,
          borderRadius: "50%",
          border: "1px solid var(--mantine-color-teal-7)",
          color: "var(--mantine-color-teal-7)",
          display: "flex",
          flexDirection: "column",
          alignItems: "center",
          justifyContent: "center",
          textAlign: "center",
          lineHeight: 1.1,
        }}
      >
        <Text size="9px" fw={700} style={{ letterSpacing: 1 }}>
          EDR FREIGHT
        </Text>
        <Text size="sm" fw={800}>
          APPROVED
        </Text>
        <Text size="8px" fw={600}>
          OPERATIONS
        </Text>
      </Box>
    </Box>
  </Box>
);

const SignatureBlock = ({ title, stamp }: { title: string; stamp?: ReactNode }) => (
  <Stack gap="sm" style={{ flex: 1, position: "relative", minHeight: stamp ? 130 : undefined }}>
    <Text fw={600} size="sm">
      {title}
    </Text>
    <Group gap="xs" align="flex-end">
      <Text size="sm" c="dimmed">Name:</Text>
      <Box style={{ flex: 1, borderBottom: "1px solid var(--mantine-color-gray-5)", height: 18 }} />
    </Group>
    <Group gap="xs" align="flex-end">
      <Text size="sm" c="dimmed">Signature:</Text>
      <Box style={{ flex: 1, borderBottom: "1px solid var(--mantine-color-gray-5)", height: 18 }} />
    </Group>
    {stamp && (
      <Box style={{ position: "absolute", right: 4, top: 22, opacity: 0.85, pointerEvents: "none" }}>
        {stamp}
      </Box>
    )}
  </Stack>
);

const TripSlipDocument = ({ record }: { record: FirstMileRecord }) => (
  <Stack gap="md">
    <Stack gap={2} align="center">
      <Text fw={700}>EDR Freight</Text>
      <Text size="sm" c="dimmed" tt="uppercase" fw={600}>First Mile Trip Slip</Text>
    </Stack>
    <Group justify="space-between">
      <Text size="sm" fw={600}>{bookingRef(record)}</Text>
      <Text size="sm" c="dimmed">{requestedDate(record)}</Text>
    </Group>
    <Divider />
    <SimpleGrid cols={2} spacing="xs">
      {tripSlipRows(record).map(([label, value]) => (
        <InfoRow key={label} label={label} value={value} />
      ))}
    </SimpleGrid>
    <Divider label="Acknowledgement" labelPosition="center" />
    <Group align="flex-start" gap="xl" wrap="nowrap">
      <SignatureBlock title="Driver" />
      <SignatureBlock title="Operator" stamp={<SampleStamp />} />
    </Group>
  </Stack>
);

const escapeHtml = (v: string) =>
  v.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");

const buildTripSlipHtml = (record: FirstMileRecord) => {
  const rows = tripSlipRows(record)
    .map(([l, v]) => `<tr><td class="lbl">${escapeHtml(l)}</td><td>${escapeHtml(v)}</td></tr>`)
    .join("");
  const sig = (title: string, withStamp: boolean) => `
    <div class="sign-col">
      <div class="sign-title">${title}</div>
      <div class="sign-field"><span>Name:</span><span class="line"></span></div>
      <div class="sign-field"><span>Signature:</span><span class="line"></span></div>
      ${withStamp ? '<div class="stamp"><div class="ring"><div class="ring-inner"><span>EDR FREIGHT</span><strong>APPROVED</strong><span>OPERATIONS</span></div></div></div>' : ""}
    </div>`;
  return `<!doctype html><html><head><meta charset="utf-8" />
    <title>Trip Slip ${escapeHtml(bookingRef(record))}</title>
    <style>
      * { box-sizing: border-box; }
      body { font-family: Arial, Helvetica, sans-serif; color: #111; margin: 32px; }
      .head { text-align: center; margin-bottom: 16px; }
      .head h1 { font-size: 18px; margin: 0; }
      .head p { font-size: 12px; letter-spacing: 1px; text-transform: uppercase; color: #555; margin: 2px 0 0; }
      .meta { display: flex; justify-content: space-between; font-size: 13px; font-weight: 600; margin: 8px 0; }
      table { width: 100%; border-collapse: collapse; font-size: 13px; margin: 8px 0 20px; }
      td { padding: 5px 6px; border-bottom: 1px solid #eee; vertical-align: top; }
      td.lbl { color: #666; text-transform: uppercase; font-size: 11px; font-weight: 700; width: 40%; }
      .ack { text-align: center; font-size: 11px; text-transform: uppercase; letter-spacing: 1px; color: #777; margin: 16px 0 8px; }
      .signs { display: flex; gap: 32px; }
      .sign-col { flex: 1; position: relative; min-height: 130px; }
      .sign-title { font-weight: 700; font-size: 13px; margin-bottom: 12px; }
      .sign-field { display: flex; gap: 6px; align-items: flex-end; font-size: 12px; color: #666; margin-bottom: 10px; }
      .sign-field .line { flex: 1; border-bottom: 1px solid #888; height: 16px; }
      .stamp { position: absolute; right: 4px; top: 22px; opacity: 0.85; }
      .ring { width: 96px; height: 96px; border-radius: 50%; border: 2px solid #0c7a57; transform: rotate(-12deg); display: flex; align-items: center; justify-content: center; }
      .ring-inner { width: 82px; height: 82px; border-radius: 50%; border: 1px solid #0c7a57; color: #0c7a57; display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; line-height: 1.1; }
      .ring-inner span { font-size: 9px; font-weight: 700; letter-spacing: 1px; }
      .ring-inner strong { font-size: 13px; font-weight: 800; }
    </style></head>
    <body onload="window.print()">
      <div class="head"><h1>EDR Freight</h1><p>First Mile Trip Slip</p></div>
      <div class="meta"><span>${escapeHtml(bookingRef(record))}</span><span>${escapeHtml(requestedDate(record))}</span></div>
      <table>${rows}</table>
      <div class="ack">Acknowledgement</div>
      <div class="signs">${sig("Driver", false)}${sig("Operator", true)}</div>
    </body></html>`;
};

const FirstMilePage = () => {
  const { toast } = useToast();
  const qc = useQueryClient();
  const { pagination, setPagination } = usePagination({ pageSize: 10 });

  const [search, setSearch] = useState("");
  const [statusFilter, setStatusFilter] = useState<StatusFilter>("ALL");
  const [filterPostPaymentPending, setFilterPostPaymentPending] = useState(false);
  const [rowSelection, setRowSelection] = useState<Record<string, boolean>>({});

  const [assignOpen, setAssignOpen] = useState(false);
  const [bulkMode, setBulkMode] = useState(false);
  const [detailOpen, setDetailOpen] = useState(false);
  const [tripSlipOpen, setTripSlipOpen] = useState(false);
  const [tripSlipRecord, setTripSlipRecord] = useState<FirstMileRecord | null>(null);
  const [activeId, setActiveId] = useState<string | null>(null);
  const [vehicleValue, setVehicleValue] = useState<string | null>(null);

  const [acceptOpen, setAcceptOpen] = useState(false);
  const [acceptStep, setAcceptStep] = useState<1 | 2>(1);
  const [selectedBooking, setSelectedBooking] = useState<BookingDetail | null>(null);
  const [acceptVehicleValue, setAcceptVehicleValue] = useState<string | null>(null);
  const [bookingSearch, setBookingSearch] = useState("");

  const [distanceOpen, setDistanceOpen] = useState(false);
  const [distanceValue, setDistanceValue] = useState("");
  const [invoiceOpen, setInvoiceOpen] = useState(false);
  const [invoiceRecord, setInvoiceRecord] = useState<FirstMileRecord | null>(null);
  const [warehouseReceiveOpen, setWarehouseReceiveOpen] = useState(false);
  const [warehouseReceiveRecord, setWarehouseReceiveRecord] = useState<FirstMileRecord | null>(null);

  const [containerAllocationOpen, setContainerAllocationOpen] = useState(false);
  const [containerAllocationFirstMileId, setContainerAllocationFirstMileId] = useState<string | null>(null);

  const { data: listData, isLoading } = useQuery({
    queryKey: QUERY_KEYS.FIRST_MILE.list(),
    queryFn: async () => {
      const res = await firstMileService.list();
      return res.data;
    },
  });

  const { data: vehiclesData } = useQuery({
    queryKey: ["vehicles", "free"],
    queryFn: async () => {
      const res = await vehiclesService.getAll({ status: "ACTIVE", availability: "FREE" });
      return res.data;
    },
  });

  const { data: ratesData } = useQuery({
    queryKey: ["rates", "FIRST_MILE"],
    queryFn: async () => {
      const res = await ratesService.getByType("FIRST_MILE");
      return res.data;
    },
  });

  const { data: paidBookingsData, isLoading: bookingsLoading } = useQuery({
    queryKey: QUERY_KEYS.BOOKINGS.list({ status: "PAID" }),
    queryFn: () => bookingsService.list({ status: "PAID", pageSize: 100 }),
    enabled: acceptOpen,
  });
  const paidBookings = paidBookingsData?.items ?? [];

  const records = listData?.data ?? [];
  const existingFirstMileBookingIds = useMemo(
    () => new Set(records.map((record) => record.bookingId)),
    [records],
  );

  const vehicleOptions = useMemo(
    () =>
      (Array.isArray(vehiclesData) ? vehiclesData : []).map((v) => {
        const parts = [`${v.manufacturer} ${v.model}`, v.plateNumber];
        if (v.code) parts.unshift(v.code);
        const plates = [v.powerPlateNo, v.trailerPlateNo].filter(Boolean).join(" / ");
        if (plates) parts.push(plates);
        return { value: v.id, label: parts.join(" · ") };
      }),
    [vehiclesData],
  );

  const updateMutation = useMutation({
    mutationFn: ({ id, data }: { id: string; data: { status?: FirstMileApiStatus; vehicleId?: string | null } }) =>
      firstMileService.update(id, data),
    onSuccess: () => {
      void qc.invalidateQueries({ queryKey: QUERY_KEYS.FIRST_MILE.list() });
      void qc.invalidateQueries({ queryKey: ["vehicles"] });
    },
    onError: () => {
      toast({ title: "Update failed", variant: "destructive" });
    },
  });

  const updateDistanceMutation = useMutation({
    mutationFn: ({ id, exactKm, remainingPayment }: { id: string; exactKm: number; remainingPayment?: number }) =>
      firstMileService.update(id, { exactKm, ...(remainingPayment != null && { remainingPayment }) }),
    onSuccess: () => {
      void qc.invalidateQueries({ queryKey: QUERY_KEYS.FIRST_MILE.list() });
      if (activeRecord) {
        toast({ title: "Distance updated", description: `${bookingRef(activeRecord)} → ${distanceValue} km` });
      }
      closeDistance();
    },
    onError: () => {
      toast({ title: "Update failed", variant: "destructive" });
    },
  });

  const deleteMutation = useMutation({
    mutationFn: (id: string) => firstMileService.remove(id),
    onSuccess: () => {
      void qc.invalidateQueries({ queryKey: QUERY_KEYS.FIRST_MILE.list() });
      toast({ title: "Record deleted", description: "First-mile record removed successfully." });
    },
    onError: () => {
      toast({ title: "Delete failed", variant: "destructive" });
    },
  });

  const acceptMutation = useMutation({
    mutationFn: async ({ reference, vehicleId }: { reference: string; vehicleId: string | null }) => {
      const res = await firstMileService.accept(reference);
      const created = res.data;
      if (!created?.id) {
        throw new Error("First-mile leg was not created for this booking.");
      }
      if (vehicleId) await firstMileService.update(created.id, { vehicleId });
      return created;
    },
    onSuccess: () => {
      void qc.invalidateQueries({ queryKey: QUERY_KEYS.FIRST_MILE.ROOT });
      void qc.invalidateQueries({ queryKey: ["vehicles"] });
      toast({ title: "Booking accepted", description: "First-mile leg created successfully." });
      closeAccept();
    },
    onError: (err: unknown) => {
      const description =
        (err as { response?: { data?: { message?: string } } })?.response?.data?.message ??
        (err instanceof Error ? err.message : undefined);
      toast({ title: "Accept failed", description, variant: "destructive" });
    },
  });

  const allocateMutation = useMutation({
    mutationFn: (data) => api.post(`/first-mile/${containerAllocationFirstMileId}/allocate-containers`, data),
    onSuccess: () => {
      toast({ title: "Containers allocated" });
      void qc.invalidateQueries({ queryKey: QUERY_KEYS.FIRST_MILE.byId(containerAllocationFirstMileId ?? "") });
      void qc.invalidateQueries({ queryKey: ["vehicles"] });
      setContainerAllocationOpen(false);
      setContainerAllocationFirstMileId(null);
    },
    onError: () => {
      toast({ title: "Allocation failed", variant: "destructive" });
    },
  });

  const activeRecord = useMemo(
    () => records.find((r) => r.id === activeId) ?? null,
    [records, activeId],
  );

  const selectedIds = useMemo(
    () => Object.keys(rowSelection).filter((id) => rowSelection[id]),
    [rowSelection],
  );

  const firstMileEligiblePaidBookings = useMemo(
    () =>
      paidBookings.filter(
        (booking) => {
          if (existingFirstMileBookingIds.has(booking.id)) return false;
          if (booking.paymentStatus !== "PAID") return false;
          if (booking.tradeDirection !== "EXPORT") return false;
          const hasPickupAddress = booking.firstMilePickupAddress?.trim() ?? false;
          const includesFirstMile = booking.serviceType?.includesFirstMile ?? false;
          return hasPickupAddress || includesFirstMile;
        },
      ),
    [existingFirstMileBookingIds, paidBookings],
  );

  const filteredPaidBookings = useMemo(() => {
    const term = bookingSearch.trim().toLowerCase();
    if (!term) return firstMileEligiblePaidBookings;
    return firstMileEligiblePaidBookings.filter((b) =>
      [b.reference, b.company?.name, b.company?.companyName]
        .join(" ")
        .toLowerCase()
        .includes(term),
    );
  }, [firstMileEligiblePaidBookings, bookingSearch]);

  const openAccept = () => {
    setAcceptOpen(true);
    setAcceptStep(1);
    setSelectedBooking(null);
    setAcceptVehicleValue(null);
    setBookingSearch("");
  };

  const closeAccept = () => {
    setAcceptOpen(false);
    setAcceptStep(1);
    setSelectedBooking(null);
    setAcceptVehicleValue(null);
    setBookingSearch("");
  };

  const handleAcceptConfirm = () => {
    if (!selectedBooking) return;
    acceptMutation.mutate({ reference: selectedBooking.reference, vehicleId: acceptVehicleValue });
  };

  const openDistance = (id: string) => {
    setActiveId(id);
    setDistanceValue("");
    setDistanceOpen(true);
  };

  const closeDistance = () => {
    setDistanceOpen(false);
    setActiveId(null);
    setDistanceValue("");
  };

  const openInvoice = (record: FirstMileRecord) => {
    setInvoiceRecord(record);
    setInvoiceOpen(true);
  };

  const closeInvoice = () => {
    setInvoiceOpen(false);
    setInvoiceRecord(null);
  };

  const openWarehouseReceive = (record: FirstMileRecord) => {
    setWarehouseReceiveRecord(record);
    setWarehouseReceiveOpen(true);
  };

  const closeWarehouseReceive = () => {
    setWarehouseReceiveOpen(false);
    setWarehouseReceiveRecord(null);
  };

  const openContainerAllocation = (firstMileId: string) => {
    setContainerAllocationFirstMileId(firstMileId);
    setContainerAllocationOpen(true);
  };

  const closeContainerAllocation = () => {
    setContainerAllocationOpen(false);
    setContainerAllocationFirstMileId(null);
  };

  const handleSaveDistance = () => {
    const distance = parseFloat(distanceValue);
    if (!activeId || isNaN(distance) || distance < 0) {
      toast({ title: "Invalid distance", description: "Enter a valid distance value.", variant: "destructive" });
      return;
    }

    let remainingPayment: number | undefined;
    if (ratesData?.data) {
      const firstMileRate = ratesData.data.find(
        (r) => r.rateType === "FIRST_MILE" && (r.status === "LIVE" || r.status === "DRAFT")
      );
      if (firstMileRate) {
        const rateValue = parseFloat(firstMileRate.rateValue);
        remainingPayment = distance * rateValue;
      }
    }

    updateDistanceMutation.mutate({ id: activeId, exactKm: distance, remainingPayment });
  };

  const matchesFilter = (r: FirstMileRecord) => {
    switch (statusFilter) {
      case "ALL": return true;
      case "ASSIGNED": return isAssigned(r);
      case "UNASSIGNED": return !isAssigned(r);
      default: return r.status === statusFilter;
    }
  };

  const statusCounts = useMemo(() => {
    const counts: Record<StatusFilter, number> = {
      ALL: records.length,
      PAYMENT_PENDING: 0,
      READY_TO_TRANSIT: 0,
      IN_TRANSIT: 0,
      RECEIVED_TO_PORT: 0,
      ASSIGNED: 0,
      UNASSIGNED: 0,
    };
    for (const r of records) {
      counts[r.status] = (counts[r.status] ?? 0) + 1;
      if (isAssigned(r)) counts.ASSIGNED += 1;
      else counts.UNASSIGNED += 1;
    }
    return counts;
  }, [records]);

  const filteredRecords = useMemo(() => {
    const term = search.trim().toLowerCase();
    return records.filter((r) => {
      if (!matchesFilter(r)) return false;
      if (!term) return true;
      return [bookingRef(r), customerName(r), pickupLocation(r), cargoDesc(r)]
        .join(" ")
        .toLowerCase()
        .includes(term);
    });
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [records, search, statusFilter, filterPostPaymentPending]);

  const pageCount = Math.max(1, Math.ceil(filteredRecords.length / pagination.pageSize));
  const pagedRecords = useMemo(() => {
    const start = pagination.pageIndex * pagination.pageSize;
    return filteredRecords.slice(start, start + pagination.pageSize);
  }, [filteredRecords, pagination]);

  const openAssign = (id: string | null) => {
    const resolved = id ?? filteredRecords.find((r) => !isAssigned(r))?.id ?? null;
    setBulkMode(false);
    setActiveId(resolved);
    setVehicleValue(null);
    setAssignOpen(true);
  };

  const openBulkAssign = () => {
    setBulkMode(true);
    setActiveId(null);
    setVehicleValue(null);
    setAssignOpen(true);
  };

  const closeAssign = () => {
    setAssignOpen(false);
    setBulkMode(false);
    setActiveId(null);
    setVehicleValue(null);
  };

  const handleAssign = () => {
    if (!vehicleValue) {
      toast({ title: "Select a vehicle", description: "Choose a vehicle to assign.", variant: "destructive" });
      return;
    }

    const targetIds = bulkMode
      ? selectedIds
      : [activeId ?? filteredRecords.find((r) => !isAssigned(r))?.id].filter((id): id is string => Boolean(id));

    if (!targetIds.length) return;

    const selectedLabel = vehicleOptions.find((o) => o.value === vehicleValue)?.label ?? vehicleValue;

    Promise.all(targetIds.map((id) => updateMutation.mutateAsync({ id, data: { vehicleId: vehicleValue } })))
      .then(() => {
        toast({
          title: "Vehicle assigned",
          description: bulkMode ? `${targetIds.length} pickups → ${selectedLabel}` : selectedLabel,
        });
        if (bulkMode) setRowSelection({});
        closeAssign();
      })
      .catch(() => void 0);
  };

  const handleAdvanceStatus = (record: FirstMileRecord) => {
    const next = NEXT_STATUS[record.status];
    if (!next) return;
    updateMutation.mutate(
      { id: record.id, data: { status: next } },
      {
        onSuccess: () =>
          toast({ title: "Status updated", description: `${bookingRef(record)} → ${STATUS_META[next].label}` }),
      },
    );
  };

  const handlePrintTripSlip = (record: FirstMileRecord) => {
    setTripSlipRecord(record);
    setTripSlipOpen(true);
  };

  const printTripSlip = () => {
    if (!tripSlipRecord) return;
    const win = window.open("", "_blank", "width=820,height=920");
    if (!win) {
      toast({ title: "Pop-up blocked", description: "Allow pop-ups to print the trip slip.", variant: "destructive" });
      return;
    }
    win.document.write(buildTripSlipHtml(tripSlipRecord));
    win.document.close();
  };

  const columns = useMemo((): ColumnDef<FirstMileRecord>[] => {
    const headerClassName = ruleEngineTable.headerCell;
    const cellClassName = ruleEngineTable.bodyCell;
    return [
      {
        id: "select",
        size: 40,
        meta: { headerClassName, cellClassName },
        header: ({ table }) => (
          <Checkbox
            aria-label="Select all"
            checked={table.getIsAllPageRowsSelected()}
            indeterminate={table.getIsSomePageRowsSelected() && !table.getIsAllPageRowsSelected()}
            onChange={(e) => table.toggleAllPageRowsSelected(e.currentTarget.checked)}
          />
        ),
        cell: ({ row }) => (
          <Checkbox
            aria-label="Select row"
            checked={row.getIsSelected()}
            disabled={!row.getCanSelect()}
            onChange={row.getToggleSelectedHandler()}
          />
        ),
      },
      {
        id: "bookingRef",
        header: "Booking",
        meta: { headerClassName, cellClassName },
        cell: ({ row }) => <Text size="sm" fw={600}>{bookingRef(row.original)}</Text>,
      },
      {
        id: "customer",
        header: "Customer",
        meta: { headerClassName, cellClassName },
        cell: ({ row }) => customerName(row.original),
      },
      {
        id: "pickup",
        header: "Pickup",
        meta: { headerClassName, cellClassName },
        cell: ({ row }) => pickupLocation(row.original),
      },
      {
        id: "destination",
        header: "Destination",
        meta: { headerClassName, cellClassName },
        cell: ({ row }) => destinationYardName(row.original),
      },
      {
        id: "cargo",
        header: "Cargo",
        meta: { headerClassName, cellClassName },
        cell: ({ row }) => cargoDesc(row.original),
      },
      {
        id: "advancedPayment",
        header: "Advanced Payment",
        meta: { headerClassName, cellClassName },
        cell: ({ row }) => formatPrice(row.original.advancedPayment),
      },
      {
        id: "postPayment",
        header: "Post Payment",
        meta: { headerClassName, cellClassName },
        cell: ({ row }) => formatPrice(row.original.remainingPayment),
      },
      {
        id: "vehicle",
        header: "Vehicle",
        meta: { headerClassName, cellClassName },
        cell: ({ row }) => vehicleLabel(row.original) ?? <Text c="dimmed">—</Text>,
      },
      {
        id: "estimatedKm",
        header: "Est. Distance (KM)",
        meta: { headerClassName, cellClassName },
        cell: ({ row }) => row.original.estimatedKm != null ? row.original.estimatedKm : <Text c="dimmed">—</Text>,
      },
      {
        id: "exactKm",
        header: "Actual Distance (KM)",
        meta: { headerClassName, cellClassName },
        cell: ({ row }) => row.original.exactKm != null ? row.original.exactKm : <Text c="dimmed">—</Text>,
      },
      {
        id: "invoice",
        header: "Invoice",
        meta: { headerClassName, cellClassName },
        cell: ({ row }) => {
          const hasDistance = row.original.exactKm != null && row.original.exactKm > 0;
          const isPaid = (row.original as any).paid;
          if (!hasDistance) {
            return <Text c="dimmed">—</Text>;
          }
          if (isPaid) {
            return (
              <Group gap="xs" wrap="nowrap">
                <UnstyledButton
                  onClick={() => openInvoice(row.original)}
                  c="blue"
                  fw={500}
                  style={{ textDecoration: "underline", cursor: "pointer" }}
                >
                  #345
                </UnstyledButton>
                <Badge color="green" variant="light" size="sm">Paid</Badge>
              </Group>
            );
          }
          return (
            <UnstyledButton
              onClick={() => openInvoice(row.original)}
              c="blue"
              fw={500}
              style={{ textDecoration: "underline", cursor: "pointer" }}
            >
              #345
            </UnstyledButton>
          );
        },
      },
      {
        id: "status",
        header: "Status",
        meta: { headerClassName, cellClassName },
        cell: ({ row }) => {
          const meta = STATUS_META[row.original.status];
          return <Badge color={meta.color} variant="light" size="sm">{meta.label}</Badge>;
        },
      },
      {
        id: "assignment",
        header: "Assignment",
        meta: { headerClassName, cellClassName },
        cell: ({ row }) => (
          <Badge color={isAssigned(row.original) ? "green" : "orange"} variant="light" size="sm">
            {isAssigned(row.original) ? "Assigned" : "Unassigned"}
          </Badge>
        ),
      },
      {
        id: "actions",
        header: "Actions",
        meta: { headerClassName, cellClassName: `${cellClassName} whitespace-nowrap` },
        cell: ({ row }) => {
          const assigned = isAssigned(row.original);
          const nextStatus = NEXT_STATUS[row.original.status];
          const canPrint = row.original.status !== "PAYMENT_PENDING";
          const isPaid = (row.original as any).paid;
          const canReceiveToWarehouse = row.original.status === "RECEIVED_TO_PORT";
          return (
            <Group gap={4} justify="flex-end" wrap="nowrap">
              <Menu position="bottom-end" width={200} withinPortal>
                <Menu.Target>
                  <ActionIcon variant="subtle" color="gray" aria-label="Pickup actions">
                    <MoreHorizontal size={16} />
                  </ActionIcon>
                </Menu.Target>
                <Menu.Dropdown>
                  <Menu.Item
                    leftSection={<ArrowRight size={15} />}
                    disabled={!nextStatus}
                    onClick={() => handleAdvanceStatus(row.original)}
                  >
                    {nextStatus ? `Mark ${STATUS_META[nextStatus].label}` : STATUS_META[row.original.status].label}
                  </Menu.Item>
                  <Menu.Divider />
                  <Menu.Item
                    leftSection={<Truck size={15} />}
                    disabled={assigned}
                    onClick={() => openAssign(row.original.id)}
                  >
                    Assign
                  </Menu.Item>
                  <Menu.Item
                    leftSection={<RefreshCw size={15} />}
                    disabled={!assigned}
                    onClick={() => openAssign(row.original.id)}
                  >
                    Reassign
                  </Menu.Item>
                  <Menu.Divider />
                  <Menu.Item
                    leftSection={<Eye size={15} />}
                    onClick={() => { setActiveId(row.original.id); setDetailOpen(true); }}
                  >
                    View detail
                  </Menu.Item>
                  <Menu.Item
                    leftSection={<PackageCheck size={15} />}
                    disabled={!canReceiveToWarehouse}
                    onClick={() => openWarehouseReceive(row.original)}
                  >
                    Receive to warehouse
                  </Menu.Item>
                  <Menu.Item
                    leftSection={<Ruler size={15} />}
                    onClick={() => openDistance(row.original.id)}
                  >
                    Add distance
                  </Menu.Item>
                  {canPrint && (
                    <Menu.Item
                      leftSection={<Printer size={15} />}
                      onClick={() => handlePrintTripSlip(row.original)}
                    >
                      Print trip slip
                    </Menu.Item>
                  )}
                  {!isPaid && (
                    <>
                      <Menu.Divider />
                      <Menu.Item
                        leftSection={<Trash size={15} />}
                        color="red"
                        onClick={() => {
                          if (confirm(`Delete first-mile record ${bookingRef(row.original)}?`)) {
                            deleteMutation.mutate(row.original.id);
                          }
                        }}
                      >
                        Delete
                      </Menu.Item>
                    </>
                  )}
                </Menu.Dropdown>
              </Menu>
            </Group>
          );
        },
      },
    ];
  // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [vehicleOptions]);

  return (
    <Stack gap="md">
      <Card radius="lg" padding={0} withBorder style={{ borderColor: "var(--mantine-color-gray-2)" }}>
        <Stack gap={0}>
          <Box px="md" pt="md" pb="sm" w="100%">
            <Stack gap="sm">
              <Group justify="space-between" wrap="wrap">
                <TextInput
                  placeholder="Search pickups…"
                  value={search}
                  onChange={(e) => setSearch(e.currentTarget.value)}
                  w={260}
                />
                <Group gap="sm">
                  {selectedIds.length > 0 && (
                    <Button variant="light" leftSection={<Truck size={16} />} onClick={openBulkAssign} styles={{ label: { fontWeight: 500 } }}>
                      Assign vehicle ({selectedIds.length})
                    </Button>
                  )}
                  <Button leftSection={<Truck size={16} />} onClick={openAccept} styles={{ label: { fontWeight: 500 } }}>
                    Assign Mile
                  </Button>
                </Group>
              </Group>
              <Group gap="xs" wrap="wrap">
                {FILTER_OPTIONS.map((option) => {
                  const active = statusFilter === option.value;
                  return (
                    <Button
                      key={option.value}
                      size="xs"
                      variant={active ? "filled" : "default"}
                      styles={{ label: { fontWeight: 500 } }}
                      onClick={() => {
                        setStatusFilter(option.value);
                        setPagination((p) => ({ ...p, pageIndex: 0 }));
                      }}
                    >
                      {option.label} ({statusCounts[option.value] ?? 0})
                    </Button>
                  );
                })}
                <Button
                  size="xs"
                  variant={filterPostPaymentPending ? "filled" : "default"}
                  styles={{ label: { fontWeight: 500 } }}
                  onClick={() => {
                    setFilterPostPaymentPending(!filterPostPaymentPending);
                    setPagination((p) => ({ ...p, pageIndex: 0 }));
                  }}
                >
                  Post Payment Pending
                </Button>
              </Group>
            </Stack>
          </Box>

          <DataTable
            columns={columns}
            data={pagedRecords}
            status={isLoading ? "loading" : "success"}
            emptyMessage="No first-mile pickups found"
            pagination={{
              pageIndex: pagination.pageIndex,
              pageSize: pagination.pageSize,
              pageCount,
              totalCount: filteredRecords.length,
            }}
            tableOptions={{
              manualPagination: true,
              pageCount,
              enableRowSelection: true,
              getRowId: (row) => row.id,
              state: { pagination, rowSelection },
              onPaginationChange: setPagination,
              onRowSelectionChange: setRowSelection,
            }}
            containerClassName="border-0 shadow-none bg-transparent"
            footer={({ table, pagination: fp }) => (
              <DataTableFooter table={table} pagination={fp} options={{ labels: { items: "pickups" } }} />
            )}
          />
        </Stack>
      </Card>

      {/* Assign / Reassign modal */}
      <Modal
        opened={assignOpen}
        onClose={closeAssign}
        title={<Text fw={600}>Assign Vehicle</Text>}
        size="lg"
        radius="lg"
        centered
      >
        <Stack gap="md">
          {bulkMode ? (
            <Text size="sm">
              Assigning a vehicle to{" "}
              <Text span fw={600}>{selectedIds.length}</Text>{" "}
              selected {selectedIds.length === 1 ? "pickup" : "pickups"}.
            </Text>
          ) : activeRecord ? (
            <BookingInfo record={activeRecord} />
          ) : (
            <Text size="sm" c="dimmed">No unassigned pickups available.</Text>
          )}
          <Divider />
          <Select
            label="Vehicle"
            placeholder={vehicleOptions.length === 0 ? "No free vehicles" : "Select a vehicle"}
            description={
              vehicleOptions.length === 0
                ? "No free vehicles available — all vehicles are busy, in maintenance, or retired. Free up a vehicle in Fleet › Vehicles first."
                : undefined
            }
            data={vehicleOptions}
            value={vehicleValue}
            onChange={setVehicleValue}
            searchable
            disabled={vehicleOptions.length === 0}
          />
          <Group justify="flex-end" gap="sm">
            <Button variant="default" onClick={closeAssign}>Cancel</Button>
            <Button
              onClick={handleAssign}
              loading={updateMutation.isPending}
              disabled={bulkMode ? selectedIds.length === 0 : !activeRecord}
            >
              {!bulkMode && activeRecord && isAssigned(activeRecord) ? "Reassign" : "Assign"}
            </Button>
          </Group>
        </Stack>
      </Modal>

      {/* View detail modal */}
      <Modal
        opened={detailOpen}
        onClose={() => { setDetailOpen(false); setActiveId(null); }}
        title={<Text fw={600}>Pickup Detail</Text>}
        size="lg"
        radius="lg"
        centered
      >
        <Stack gap="md">
          {activeRecord && <BookingInfo record={activeRecord} />}
          <Group justify="flex-end">
            <Button variant="default" onClick={() => { setDetailOpen(false); setActiveId(null); }}>Close</Button>
          </Group>
        </Stack>
      </Modal>

      {/* Trip slip modal */}
      <Modal
        opened={tripSlipOpen}
        onClose={() => setTripSlipOpen(false)}
        title={<Text fw={600}>Trip Slip</Text>}
        size="lg"
        radius="lg"
        centered
      >
        <Stack gap="md">
          {tripSlipRecord && <TripSlipDocument record={tripSlipRecord} />}
          <Divider />
          <Group justify="flex-end" gap="sm">
            <Button variant="default" onClick={() => setTripSlipOpen(false)}>Close</Button>
            <Button leftSection={<Printer size={16} />} onClick={printTripSlip}>Print</Button>
          </Group>
        </Stack>
      </Modal>

      <ReceiveInventoryModal
        opened={warehouseReceiveOpen}
        onClose={closeWarehouseReceive}
        mode="bulk"
        direction="EXPORT"
        bookingId={warehouseReceiveRecord?.bookingId}
        bookingLabel={warehouseReceiveRecord ? bookingRef(warehouseReceiveRecord) : undefined}
        onReceived={() => {
          void qc.invalidateQueries({ queryKey: QUERY_KEYS.FIRST_MILE.list() });
          closeWarehouseReceive();
        }}
      />

      {/* Accept Booking modal — step 1: booking list, step 2: details + vehicle */}
      <Modal
        opened={acceptOpen}
        onClose={closeAccept}
        title={
          <Text fw={600}>
            {acceptStep === 1 ? "Select a Paid Booking" : "Accept Booking"}
          </Text>
        }
        size="xl"
        radius="lg"
        centered
      >
        {acceptStep === 1 ? (
          <Stack gap="md">
            <TextInput
              placeholder="Search by reference or company…"
              value={bookingSearch}
              onChange={(e) => setBookingSearch(e.currentTarget.value)}
            />
            <Stack gap="xs" style={{ maxHeight: 420, overflowY: "auto" }}>
              {bookingsLoading ? (
                <Text c="dimmed" size="sm" ta="center" py="md">Loading bookings…</Text>
              ) : filteredPaidBookings.length === 0 ? (
                <Text c="dimmed" size="sm" ta="center" py="md">No paid export bookings need first mile.</Text>
              ) : (
                filteredPaidBookings.map((b) => (
                  <UnstyledButton
                    key={b.id}
                    w="100%"
                    onClick={() => {
                      setSelectedBooking(b);
                      setAcceptStep(2);
                    }}
                    style={{
                      borderRadius: "var(--mantine-radius-md)",
                      border: "1px solid var(--mantine-color-gray-3)",
                      padding: "10px 12px",
                      backgroundColor: "var(--mantine-color-white)",
                      transition: "background-color 120ms ease, border-color 120ms ease",
                    }}
                    onMouseEnter={(e) => {
                      (e.currentTarget as HTMLButtonElement).style.backgroundColor =
                        "var(--mantine-color-blue-0)";
                      (e.currentTarget as HTMLButtonElement).style.borderColor =
                        "var(--mantine-color-blue-4)";
                    }}
                    onMouseLeave={(e) => {
                      (e.currentTarget as HTMLButtonElement).style.backgroundColor =
                        "var(--mantine-color-white)";
                      (e.currentTarget as HTMLButtonElement).style.borderColor =
                        "var(--mantine-color-gray-3)";
                    }}
                  >
                    <Group justify="space-between" wrap="nowrap" gap="sm">
                      <Stack gap={3} style={{ flex: 1, minWidth: 0 }}>
                        <Text fw={700} size="sm" c="dark">{b.reference}</Text>
                        <Text size="xs" c="dimmed" truncate>
                          {b.company?.name ?? b.company?.companyName ?? "—"}
                        </Text>
                      </Stack>
                      <Stack gap={3} align="flex-end" style={{ flexShrink: 0 }}>
                        <Text size="xs" c="dimmed">
                          {b.originYard?.label ?? "—"} → {b.destinationYard?.label ?? "—"}
                        </Text>
                        <Text size="sm" fw={600} c="blue">
                          {formatPrice(b.totalAmount)}
                        </Text>
                        <Text size="xs" c="dimmed">
                          {b.scheduledDate ? b.scheduledDate.slice(0, 10) : "—"}
                        </Text>
                      </Stack>
                      <ChevronRight size={16} color="var(--mantine-color-gray-5)" />
                    </Group>
                  </UnstyledButton>
                ))
              )}
            </Stack>
            <Group justify="flex-end">
              <Button variant="default" onClick={closeAccept}>Cancel</Button>
            </Group>
          </Stack>
        ) : (
          <Stack gap="md">
            {selectedBooking && (
              <Card withBorder padding="md" radius="md" bg="var(--mantine-color-gray-0)">
                <Stack gap="sm">
                  <Group justify="space-between">
                    <Text fw={600}>{selectedBooking.reference}</Text>
                    <Badge color="green" variant="light" size="sm">PAID</Badge>
                  </Group>
                  <SimpleGrid cols={2} spacing="sm">
                    <InfoRow label="Customer" value={selectedBooking.company?.name ?? selectedBooking.company?.companyName ?? "—"} />
                    <InfoRow label="Service type" value={selectedBooking.serviceType?.name ?? "—"} />
                    <InfoRow label="Pickup address" value={selectedBooking.firstMilePickupAddress ?? "—"} />
                    <InfoRow label="Destination (origin yard)" value={selectedBooking.originYard?.label ?? "—"} />
                    <InfoRow label="Train destination yard" value={selectedBooking.destinationYard?.label ?? "—"} />
                    <InfoRow label="Cargo type" value={selectedBooking.cargoType?.name ?? "—"} />
                    <InfoRow label="Weight (VGM)" value={`${selectedBooking.cargoTotalWeightVgm} t`} />
                    <InfoRow label="Total amount" value={formatPrice(selectedBooking.totalAmount)} />
                    <InfoRow label="Contact person" value={selectedBooking.company?.contactPersonName ?? "—"} />
                    <InfoRow label="Contact phone" value={selectedBooking.company?.contactPersonPhone ?? selectedBooking.company?.phone ?? "—"} />
                    <InfoRow label="Requested date" value={selectedBooking.scheduledDate ? selectedBooking.scheduledDate.slice(0, 10) : "—"} />
                  </SimpleGrid>
                </Stack>
              </Card>
            )}
            <Divider />
            <Select
              label="Assign Vehicle (optional)"
              placeholder={vehicleOptions.length === 0 ? "No free vehicles" : "Select a vehicle"}
              description={
                vehicleOptions.length === 0
                  ? "No free vehicles available — you can still accept and assign a vehicle later."
                  : undefined
              }
              data={vehicleOptions}
              value={acceptVehicleValue}
              onChange={setAcceptVehicleValue}
              searchable
              clearable
              disabled={vehicleOptions.length === 0}
            />
            <Group justify="space-between" gap="sm">
              <Button variant="subtle" onClick={() => setAcceptStep(1)}>← Back</Button>
              <Group gap="sm">
                <Button variant="default" onClick={closeAccept}>Cancel</Button>
                <Button
                  onClick={handleAcceptConfirm}
                  loading={acceptMutation.isPending}
                  disabled={!selectedBooking}
                >
                  Accept Booking
                </Button>
              </Group>
            </Group>
          </Stack>
        )}
      </Modal>

      {/* Add Actual Distance modal */}
      <Modal
        opened={distanceOpen}
        onClose={closeDistance}
        title={<Text fw={600}>Add Actual Distance</Text>}
        size="md"
        radius="lg"
        centered
      >
        <Stack gap="md">
          {activeRecord && (
            <Card withBorder padding="md" radius="md" bg="var(--mantine-color-gray-0)">
              <Stack gap="sm">
                <Text fw={600} size="sm">{bookingRef(activeRecord)}</Text>
                <Group justify="space-between">
                  <Text size="xs" c="dimmed">Customer</Text>
                  <Text size="sm">{customerName(activeRecord)}</Text>
                </Group>
                <Group justify="space-between">
                  <Text size="xs" c="dimmed">Est. Distance (KM)</Text>
                  <Text size="sm">{activeRecord.estimatedKm ?? "—"}</Text>
                </Group>
              </Stack>
            </Card>
          )}
          <NumberInput
            label="Actual Distance (KM)"
            placeholder="Enter distance"
            value={distanceValue}
            onChange={(v) => setDistanceValue(String(v ?? ""))}
            min={0}
            step={0.1}
            decimalScale={2}
          />
          <Group justify="flex-end" gap="sm">
            <Button variant="default" onClick={closeDistance}>Cancel</Button>
            <Button
              onClick={handleSaveDistance}
              loading={updateDistanceMutation.isPending}
              disabled={!distanceValue}
            >
              Save
            </Button>
          </Group>
        </Stack>
      </Modal>

      {/* Invoice modal */}
      <Modal
        opened={invoiceOpen}
        onClose={closeInvoice}
        title={<Text fw={600}>Invoice #345</Text>}
        size="lg"
        radius="lg"
        centered
      >
        <Stack gap="md">
          {invoiceRecord && (
            <>
              <Card withBorder padding="md" radius="md" bg="var(--mantine-color-gray-0)">
                <Stack gap="sm">
                  <Group justify="space-between">
                    <Text fw={700}>EDR Freight</Text>
                    <Text fw={600} size="sm">Invoice #345</Text>
                  </Group>
                  <Divider />
                  <SimpleGrid cols={2} spacing="sm">
                    <InfoRow label="Booking" value={bookingRef(invoiceRecord)} />
                    <InfoRow label="Customer" value={customerName(invoiceRecord)} />
                    <InfoRow label="Pickup" value={pickupLocation(invoiceRecord)} />
                    <InfoRow label="Destination" value={destinationYardName(invoiceRecord)} />
                    <InfoRow label="Est. Distance" value={invoiceRecord.estimatedKm ? `${invoiceRecord.estimatedKm} km` : "—"} />
                    <InfoRow label="Actual Distance" value={invoiceRecord.exactKm ? `${invoiceRecord.exactKm} km` : "—"} />
                    <InfoRow label="Advanced Payment" value={formatPrice(invoiceRecord.advancedPayment)} />
                    <InfoRow label="Post Payment" value={formatPrice(invoiceRecord.remainingPayment)} />
                  </SimpleGrid>
                  <Divider />
                  <Group justify="flex-end">
                    <Stack gap={0} align="flex-end" style={{ minWidth: 200 }}>
                      <Group justify="space-between" w="100%">
                        <Text size="sm" c="dimmed">Post Payment</Text>
                        <Text size="sm">{formatPrice(invoiceRecord.remainingPayment)}</Text>
                      </Group>
                      <Group justify="space-between" w="100%">
                        <Text size="sm" c="dimmed">Advanced Payment</Text>
                        <Text size="sm">{formatPrice(invoiceRecord.advancedPayment)}</Text>
                      </Group>
                      <Divider my="xs" />
                      {(() => {
                        const postPayment = parseFloat(String(invoiceRecord.remainingPayment));
                        const advancedPayment = parseFloat(String(invoiceRecord.advancedPayment));
                        const difference = postPayment - advancedPayment;

                        if (difference > 0) {
                          return (
                            <Group justify="space-between" w="100%">
                              <Text size="sm" fw={600}>Remaining to Pay</Text>
                              <Text fw={700} c="orange">{formatPrice(difference)}</Text>
                            </Group>
                          );
                        } else if (difference < 0) {
                          return (
                            <Group justify="space-between" w="100%">
                              <Text size="sm" fw={600}>Refund</Text>
                              <Text fw={700} c="green">{formatPrice(Math.abs(difference))}</Text>
                            </Group>
                          );
                        } else {
                          return (
                            <Group justify="space-between" w="100%">
                              <Text size="sm" fw={600}>Status</Text>
                              <Text fw={700} c="blue">Settled</Text>
                            </Group>
                          );
                        }
                      })()}
                    </Stack>
                  </Group>
                </Stack>
              </Card>
            </>
          )}
          <Group justify="flex-end" gap="sm">
            <Button variant="default" onClick={closeInvoice}>Close</Button>
          </Group>
        </Stack>
      </Modal>

      {/* Container Allocation modal */}
      <Modal
        opened={containerAllocationOpen}
        onClose={closeContainerAllocation}
        title={<Text fw={600}>Allocate Containers to Vehicles</Text>}
        size="xl"
        radius="lg"
        centered
      >
        <Stack gap="md">
          {activeRecord && (
            <>
              {/* Capacity guidance */}
              {activeRecord.booking?.cargoType?.label === "BULK" ? (
                <Alert color="blue" title="Bulk Cargo Allocation">
                  <Text size="sm">
                    Select multiple containers per vehicle based on capacity. Each vehicle can carry multiple containers if capacity allows.
                  </Text>
                  <Text size="xs" c="dimmed" mt="xs">
                    Capacity: TBD — TODO: add vehicle capacity_tons to vehicle API if missing
                  </Text>
                </Alert>
              ) : (
                <Alert color="blue">
                  <Text size="sm">
                    One vehicle per container. Each container will be assigned to a single vehicle.
                  </Text>
                </Alert>
              )}
              <Divider />

              {/* Container table */}
              <FirstMileContainerAllocationTable
                firstMileId={activeRecord.id}
                containers={[
                  // TODO: Get containers from booking/first-mile data
                  // For now placeholder with TODO comment
                ]}
                onSave={async (allocations) => {
                  await allocateMutation.mutateAsync(allocations);
                }}
              />
            </>
          )}
          <Group justify="flex-end" gap="sm">
            <Button variant="default" onClick={closeContainerAllocation}>Close</Button>
          </Group>
        </Stack>
      </Modal>
    </Stack>
  );
};

export default FirstMilePage;
