import { useEffect, useMemo, useState } from "react";
import { useNavigate } from "react-router-dom";
import { isAxiosError } from "axios";
import {
  Badge,
  Box,
  Button,
  Checkbox,
  Group,
  Modal,
  Paper,
  Radio,
  RingProgress,
  Select,
  SimpleGrid,
  Stack,
  Text,
  ThemeIcon,
  Title,
} from "@mantine/core";
import {
  CheckCircle2,
  Container as ContainerIcon,
  Eye,
  Flame,
  LayoutGrid,
  Package,
  Route as RouteIcon,
  Train,
  Wallet,
  Weight,
} from "lucide-react";

import { useMutation, useQuery } from "@tanstack/react-query";
import { api } from "@/services/api";
import { useToast } from "@/hooks/use-toast";
import { trainSchedulingService } from "@/services/trainScheduling.service";
import type { BookingDetail } from "@/types/booking";
import type {
  ContainerPlacement,
  FreightType,
  ReschedulePlan,
  TrainScheduleDetail,
  TrainScheduleListItem,
  TrainSchedulePreviewResponse,
} from "@/types/trainScheduling";

import { ContainerPlacementGrid } from "./ContainerPlacementGrid";
import {
  autoFillPlacements,
  mergePlacementsWithSaved,
  placementsFromScheduleWagons,
  validateLocalPlacements,
} from "./containerPlacement.util";
import { shouldShowContainerPlacementStep } from "./schedulingContainerStep.util";
import { FleetAvailabilitySummary } from "./FleetAvailabilitySummary";
import { ScheduleBookingsStep } from "./ScheduleBookingsStep";
import { PreviewSummary, ScheduleWarningsAlert } from "./ScheduleWarningsAlert";
import { FreightTypeBadge, SchedulingStatusBadge } from "./ScheduleStatusBadge";
import {
  RouteCorridor,
  StatTile,
  StatusPill,
  scheduleBrand,
} from "./scheduleVisuals";
import { TrainCompositionDiagram } from "./TrainCompositionDiagram";
import { WagonPlanGrid } from "./WagonPlanGrid";
import { WorkflowRail, WorkflowStep } from "./WorkflowStep";

const parseError = (error: unknown, fallback: string) => {
  if (isAxiosError(error)) {
    const data = error.response?.data as Record<string, unknown> | undefined;
    const message = data?.message;
    if (Array.isArray(message)) return message.join(", ");
    if (typeof message === "string") return message;
    const violations = data?.violations;
    if (Array.isArray(violations)) return violations.join(", ");
  }
  return fallback;
};

const formatCountdown = (expiresAt?: string | null) => {
  if (!expiresAt) return null;
  const diff = new Date(expiresAt).getTime() - Date.now();
  if (diff <= 0) return "Hold expired";
  const hours = Math.floor(diff / 3600000);
  const mins = Math.floor((diff % 3600000) / 60000);
  return `${hours}h ${mins}m remaining`;
};

export function AllocateBookingWizard({
  booking,
  opened,
  onClose,
  initialBookingIds,
}: {
  booking: BookingDetail;
  opened: boolean;
  onClose: () => void;
  initialBookingIds?: string[];
}) {
  const navigate = useNavigate();
  const { toast } = useToast();
  const bookingFreightType = booking.freightType as FreightType;
  const [activeStep, setActiveStep] = useState(0);
  const [scheduleMode, setScheduleMode] = useState<"existing" | "new">("existing");
  const [selectedScheduleId, setSelectedScheduleId] = useState<string | null>(null);
  const [routeId, setRouteId] = useState("");
  const scheduleDate = booking.scheduledDate;
  const [locomotiveId, setLocomotiveId] = useState("");
  const [extraBookingIds, setExtraBookingIds] = useState<string[]>([]);
  const [forceAssign, setForceAssign] = useState(false);
  const [previewResult, setPreviewResult] = useState<TrainSchedulePreviewResponse | null>(null);
  const [containerPlacements, setContainerPlacements] = useState<ContainerPlacement[]>([]);
  const [assignedSchedule, setAssignedSchedule] = useState<TrainScheduleDetail | null>(null);
  const [reschedulePlan, setReschedulePlan] = useState<ReschedulePlan | null>(null);
  const [confirmPreempt, setConfirmPreempt] = useState(false);
  const [allocationComplete, setAllocationComplete] = useState(false);

  const originId = booking.originYard?.id;
  const destinationId = booking.destinationYard?.id;

  const eligibleFilters = useMemo(
    () => ({
      originStationId: originId,
      destinationStationId: destinationId,
    }),
    [originId, destinationId],
  );

  const eligibleQuery = useQuery(
    api.trainScheduling.eligibleBookings.queryOptions({
      input: { filters: eligibleFilters },
      enabled: opened,
    }),
  );
  const schedulesQuery = useQuery(
    api.trainScheduling.scheduleList.queryOptions({ input: {} }),
  );
  const routesQuery = useQuery(api.routes.list.queryOptions());
  const locomotivesQuery = useQuery(
    api.trainScheduling.availableLocomotives.queryOptions({
      input: {
        routeId: scheduleMode === "new" && routeId ? routeId : undefined,
      },
    }),
  );
  const create = useMutation(api.trainScheduling.createSchedule.mutationOptions());
  const preview = useMutation(api.trainScheduling.preview.mutationOptions());
  const assign = useMutation(api.trainScheduling.assignBookings.mutationOptions());
  const finalize = useMutation(api.trainScheduling.finalizeSchedule.mutationOptions());

  useEffect(() => {
    if (scheduleMode === "new") {
      setLocomotiveId("");
    }
  }, [routeId, scheduleMode]);

  const matchingSchedules = useMemo(
    () =>
      (schedulesQuery.data ?? []).filter(
        (s: TrainScheduleListItem) =>
          s.status === "DRAFT" &&
          (!s.freightType || s.freightType === "MIXED" || s.freightType === bookingFreightType),
      ),
    [schedulesQuery.data, bookingFreightType],
  );

  const allBookingIds = useMemo(
    () => [booking.id, ...extraBookingIds.filter((id) => id !== booking.id)],
    [booking.id, extraBookingIds],
  );

  const containerUnits = previewResult?.containerUnits ?? [];
  const containerSlots = previewResult?.containerSlotSequenceNos ?? [];
  const hasContainerStep = useMemo(
    () =>
      shouldShowContainerPlacementStep({
        containerUnitCount: containerUnits.length,
        scheduleFreightType: booking.freightType,
        bookingFreightTypes: [
          booking.freightType,
          ...(eligibleQuery.data?.items ?? [])
            .filter((item) => allBookingIds.includes(item.id))
            .map((item) => item.freightType),
        ],
      }),
    [
      allBookingIds,
      booking.freightType,
      containerUnits.length,
      eligibleQuery.data?.items,
    ],
  );
  const previewFreightType = previewResult?.summary?.freightMode as FreightType | undefined;
  const finalizeStep = hasContainerStep ? 3 : 2;

  useEffect(() => {
    if (!opened) {
      setActiveStep(0);
      setPreviewResult(null);
      setAssignedSchedule(null);
      setExtraBookingIds([]);
      setContainerPlacements([]);
      setReschedulePlan(null);
      setConfirmPreempt(false);
      setAllocationComplete(false);
      return;
    }
    if (initialBookingIds?.length) {
      setExtraBookingIds(initialBookingIds.filter((id) => id !== booking.id));
    }
  }, [opened, booking.id, initialBookingIds]);

  useEffect(() => {
    if (matchingSchedules.length && !selectedScheduleId) {
      setSelectedScheduleId(matchingSchedules[0].id);
    }
  }, [matchingSchedules, selectedScheduleId]);

  const savedPlacementsFromSchedule = useMemo(
    () =>
      assignedSchedule?.trainSet?.wagons
        ? placementsFromScheduleWagons(assignedSchedule.trainSet.wagons)
        : [],
    [assignedSchedule?.trainSet?.wagons],
  );

  useEffect(() => {
    if (!containerUnits.length || !containerSlots.length) return;

    setContainerPlacements((current) => {
      if (current.length && current.some((p) => p.containerNumber?.trim())) {
        return current;
      }
      const autoFilled = autoFillPlacements(containerUnits, containerSlots);
      if (savedPlacementsFromSchedule.length) {
        return mergePlacementsWithSaved(autoFilled, savedPlacementsFromSchedule);
      }
      if (current.length) return current;
      return autoFilled;
    });
  }, [containerUnits, containerSlots, savedPlacementsFromSchedule]);

  const activeRoutes = useMemo(
    () => (routesQuery.data ?? []).filter((r) => r.isActive),
    [routesQuery.data],
  );

  const displayWagonPlan = useMemo(() => {
    const savedWagons = assignedSchedule?.trainSet?.wagons ?? [];
    const physicalBySeq = new Map(
      savedWagons.map((w) => [w.sequenceNo, w.physicalWagonNumber ?? null]),
    );
    if (previewResult?.wagonPlan?.length) {
      return previewResult.wagonPlan.map((slot) => ({
        ...slot,
        physicalWagonNumber: physicalBySeq.get(slot.sequenceNo) ?? null,
      }));
    }
    if (savedWagons.length) return savedWagons;
    return [];
  }, [previewResult?.wagonPlan, assignedSchedule?.trainSet?.wagons]);

  const ensureSchedule = async (): Promise<string> => {
    if (scheduleMode === "existing" && selectedScheduleId) return selectedScheduleId;
    if (!routeId || !scheduleDate || !locomotiveId) {
      throw new Error("Select route, date, and locomotive");
    }
    const created = await create.mutateAsync({
      payload: { routeId, scheduleDate, locomotiveId },
    });
    setSelectedScheduleId(created.id);
    return created.id;
  };

  const handlePreview = async () => {
    if (!originId || !destinationId) {
      toast({ title: "Booking missing origin or destination", variant: "destructive" });
      return;
    }
    try {
      const targetScheduleId =
        scheduleMode === "existing" ? (selectedScheduleId ?? undefined) : undefined;
      const result = await preview.mutateAsync({
        payload: {
          bookingIds: allBookingIds,
          scheduleDate,
          originStationId: originId,
          destinationStationId: destinationId,
          targetScheduleId,
        },
      });
      setPreviewResult(result);
      if (booking.isGovernment && targetScheduleId) {
        const plan = (await trainSchedulingService.previewReschedule(targetScheduleId, {
          incomingBookingIds: allBookingIds,
          trigger: "GOVERNMENT_PREEMPT",
        })) as ReschedulePlan;
        setReschedulePlan(plan);
      } else {
        setReschedulePlan(null);
      }
      if (result.containerUnits?.length && result.containerSlotSequenceNos?.length) {
        const autoFilled = autoFillPlacements(
          result.containerUnits,
          result.containerSlotSequenceNos,
        );
        setContainerPlacements(autoFilled);
      }
      setActiveStep(1);
    } catch (err) {
      toast({
        title: "Preview failed",
        description: parseError(err, "Could not preview"),
        variant: "destructive",
      });
    }
  };

  const handleAssign = async () => {
    if (hasContainerStep) {
      const issues = validateLocalPlacements(containerUnits, containerPlacements);
      if (issues.length) {
        toast({
          title: "Complete container assignments",
          description: issues.join(", "),
          variant: "destructive",
        });
        return;
      }
    }

    if (reschedulePlan?.displaced.length && !confirmPreempt) {
      toast({
        title: "Confirm displacement",
        description: "Acknowledge displaced bookings before assigning",
        variant: "destructive",
      });
      return;
    }

    try {
      const scheduleId = await ensureSchedule();
      let result: TrainScheduleDetail;
      if (reschedulePlan?.displaced.length) {
        const executed = await trainSchedulingService.executeReschedule(scheduleId, {
          incomingBookingIds: allBookingIds,
          trigger: "GOVERNMENT_PREEMPT",
          finalBookingIds: reschedulePlan.finalBookingIds,
          displacedBookingIds: reschedulePlan.displaced.map((b) => b.id),
        });
        result = (executed as { schedule: TrainScheduleDetail }).schedule;
      } else {
        result = await assign.mutateAsync({
          id: scheduleId,
          freightType: previewFreightType,
          payload: {
            bookingIds: allBookingIds,
            forceAssign,
            containerPlacements: hasContainerStep ? containerPlacements : undefined,
          },
        });
      }
      setAssignedSchedule(result);
      const saved = result.trainSet?.wagons
        ? placementsFromScheduleWagons(result.trainSet.wagons)
        : [];
      if (saved.length) {
        setContainerPlacements(saved);
      }
      setActiveStep(finalizeStep);
      toast({ title: "Bookings assigned — wagons auto-pinned" });
      if (result.deferredBookings?.length) {
        toast({
          title: "Partial assignment",
          description: `${result.deferredBookings.length} booking(s) deferred to next train`,
        });
      }
    } catch (err) {
      toast({
        title: "Assign failed",
        description: parseError(err, "Could not assign"),
        variant: "destructive",
      });
    }
  };

  const handleFinalize = async () => {
    const scheduleId = assignedSchedule?.id ?? selectedScheduleId;
    if (!scheduleId) return;
    try {
      const finalized = await finalize.mutateAsync(scheduleId);
      setAssignedSchedule(finalized);
      setAllocationComplete(true);
      toast({ title: "Schedule finalized — booking allocated" });
    } catch (err) {
      toast({
        title: "Finalize failed",
        description: parseError(err, "Could not finalize schedule"),
        variant: "destructive",
      });
    }
  };

  const amount = Number(booking.totalAmount);
  const containers = booking.bookingContainers ?? [];
  const containerCount = containers.reduce((sum, c) => sum + Number(c.quantity ?? 0), 0);
  const weight = Number(booking.cargoTotalWeightVgm ?? 0);
  const holdCountdown = formatCountdown(booking.holdExpiresAt);

  const containerComplete =
    hasContainerStep &&
    containerUnits.length > 0 &&
    validateLocalPlacements(containerUnits, containerPlacements).length === 0;

  const stepsMeta = [
    {
      key: "bookings",
      icon: Package,
      title: "Bookings",
      subtitle: "Select cargo & preview the plan",
      complete: Boolean(previewResult) || Boolean(assignedSchedule),
    },
    {
      key: "wagon",
      icon: LayoutGrid,
      title: "Wagon plan",
      subtitle: "Review generated allocations",
      complete: displayWagonPlan.length > 0,
    },
    ...(hasContainerStep
      ? [
          {
            key: "container",
            icon: ContainerIcon,
            title: "Containers",
            subtitle: "Map units to wagon slots",
            complete: containerComplete,
          },
        ]
      : []),
    {
      key: "finalize",
      icon: CheckCircle2,
      title: "Finalize",
      subtitle: "Lock the plan & dispatch",
      complete: allocationComplete,
    },
  ];
  const completedCount = stepsMeta.filter((s) => s.complete).length;
  const progressPct = Math.round((completedCount / stepsMeta.length) * 100);
  const toggleStep = (i: number) => setActiveStep((cur) => (cur === i ? -1 : i));

  const renderStepRightSlot = (key: string) => {
    if (key === "bookings") {
      if (previewResult) {
        return (
          <Badge variant="light" color={previewResult.valid ? "edr-green" : "red"} radius="sm">
            {previewResult.valid ? "Plan valid" : "Has issues"}
          </Badge>
        );
      }
      return allBookingIds.length ? (
        <Badge variant="light" color="edr-green" radius="sm">
          {allBookingIds.length} selected
        </Badge>
      ) : null;
    }
    if (key === "wagon" && displayWagonPlan.length) {
      return (
        <Badge variant="light" color="edr-green" radius="sm">
          {displayWagonPlan.length} wagons
        </Badge>
      );
    }
    if (key === "container" && containerUnits.length) {
      return (
        <Badge variant="light" color={containerComplete ? "edr-green" : "yellow"} radius="sm">
          {containerUnits.length} units
        </Badge>
      );
    }
    if (key === "finalize" && allocationComplete) {
      return <StatusPill status="SCHEDULED" />;
    }
    return null;
  };

  const renderStepBody = (key: string) => {
    if (key === "bookings") {
      return (
        <Stack gap="md">
          <Paper p="md" radius="lg" withBorder style={{ borderColor: "var(--mantine-color-gray-2)" }}>
            <Stack gap="sm">
              <Text fw={600} size="sm">
                Train schedule
              </Text>
              <Radio.Group
                value={scheduleMode}
                onChange={(v) => setScheduleMode(v as "existing" | "new")}
              >
                <Group gap="lg">
                  <Radio value="existing" label="Use existing draft schedule" />
                  <Radio value="new" label="Create new schedule" />
                </Group>
              </Radio.Group>

              {scheduleMode === "existing" ? (
                <Select
                  label="Draft schedule"
                  data={matchingSchedules.map((s) => ({
                    value: s.id,
                    label: `${s.routeName ?? "Schedule"} · ${new Date(s.scheduleDate).toLocaleDateString()} · ${s.freightType ?? "MIXED"}`,
                  }))}
                  value={selectedScheduleId}
                  onChange={setSelectedScheduleId}
                  searchable
                />
              ) : (
                <SimpleGrid cols={{ base: 1, sm: 2 }} spacing="sm">
                  <Select
                    label="Route"
                    data={activeRoutes.map((r) => ({ value: r.id, label: r.name }))}
                    value={routeId || null}
                    onChange={(v) => setRouteId(v ?? "")}
                    searchable
                  />
                  <Select
                    label="Locomotive"
                    placeholder={routeId ? "Select locomotive" : "Select a route first"}
                    data={(locomotivesQuery.data ?? []).map((l) => ({
                      value: l.id,
                      label: `${l.code}${l.name ? ` · ${l.name}` : ""}`,
                    }))}
                    value={locomotiveId || null}
                    onChange={(v) => setLocomotiveId(v ?? "")}
                    searchable
                    disabled={!routeId}
                    nothingFoundMessage={
                      routeId ? "No available locomotives for this corridor" : "Select a route first"
                    }
                  />
                </SimpleGrid>
              )}

              {holdCountdown ? (
                <Text size="xs" c={holdCountdown.includes("expired") ? "red" : "yellow.8"}>
                  Hold window: {holdCountdown}
                </Text>
              ) : null}
            </Stack>
          </Paper>

          <ScheduleBookingsStep
            assignedBookings={(assignedSchedule?.bookings ?? []).map((b) => ({
              id: b.id,
              reference: b.reference ?? b.id.slice(0, 8),
              weightTons: b.weightTons,
            }))}
            eligibleItems={eligibleQuery.data?.items ?? []}
            eligibleLoading={eligibleQuery.isLoading}
            selectedIds={allBookingIds}
            onSelectionChange={(ids) => {
              setExtraBookingIds(ids.filter((id) => id !== booking.id));
            }}
            freightType={bookingFreightType}
          />

          <Group
            align="center"
            justify="space-between"
            wrap="wrap"
            gap="md"
            p="sm"
            style={{
              borderRadius: 12,
              background: "var(--mantine-color-gray-0)",
              border: "1px solid var(--mantine-color-gray-2)",
            }}
          >
            <Checkbox
              label="Force assign (bypass hold / overweight warnings)"
              checked={forceAssign}
              onChange={(e) => setForceAssign(e.currentTarget.checked)}
              size="sm"
            />
            <Button
              color="edr-green"
              radius="md"
              leftSection={<Eye size={16} />}
              loading={preview.isPending}
              onClick={handlePreview}
            >
              Preview plan
            </Button>
          </Group>

          {previewResult ? (
            <Stack gap="sm">
              <ScheduleWarningsAlert
                violations={previewResult.violations}
                warnings={previewResult.warnings}
              />
              <FleetAvailabilitySummary
                fleetAvailability={previewResult.fleetAvailability}
                deferredBookings={previewResult.deferredBookings}
              />
              <PreviewSummary summary={previewResult.summary} />
            </Stack>
          ) : null}
        </Stack>
      );
    }

    if (key === "wagon") {
      return (
        <Stack gap="md">
          {!displayWagonPlan.length && !previewResult ? (
            <Paper p="md" radius="lg" withBorder bg="gray.0">
              <Text size="sm" c="dimmed">
                Run a preview from the Bookings step to generate the wagon plan.
              </Text>
            </Paper>
          ) : null}
          {reschedulePlan?.displaced.length ? (
            <Paper p="md" radius="lg" withBorder style={{ borderColor: "var(--mantine-color-orange-2)", background: "var(--mantine-color-orange-0)" }}>
              <Stack gap="sm">
                <Text fw={600} size="sm" c="orange.8">
                  Government preempt — bookings to displace
                </Text>
                {reschedulePlan.displaced.map((b) => (
                  <Text key={b.id} size="sm">
                    {b.reference} (priority {b.priorityScore})
                  </Text>
                ))}
                <Checkbox
                  label="I confirm displacing the bookings listed above"
                  checked={confirmPreempt}
                  onChange={(e) => setConfirmPreempt(e.currentTarget.checked)}
                />
              </Stack>
            </Paper>
          ) : null}
          <ScheduleWarningsAlert
            violations={previewResult?.violations}
            warnings={previewResult?.warnings}
          />
          <FleetAvailabilitySummary
            fleetAvailability={previewResult?.fleetAvailability}
            deferredBookings={previewResult?.deferredBookings}
          />
          <WagonPlanGrid
            wagonPlan={displayWagonPlan}
            freightType={previewFreightType ?? bookingFreightType}
          />
          <Group>
            {!hasContainerStep ? (
              <Button
                color="edr-green"
                radius="md"
                loading={assign.isPending || create.isPending}
                onClick={handleAssign}
              >
                Assign bookings
              </Button>
            ) : (
              <Button
                color="edr-green"
                radius="md"
                rightSection={<ContainerIcon size={16} />}
                onClick={() => setActiveStep(2)}
              >
                Continue to containers
              </Button>
            )}
            <Button variant="default" radius="md" onClick={handlePreview}>
              Refresh preview
            </Button>
          </Group>
        </Stack>
      );
    }

    if (key === "container") {
      return (
        <Stack gap="md">
          {!containerUnits.length ? (
            <Paper p="md" radius="lg" withBorder bg="gray.0">
              <Text size="sm" c="dimmed">
                Run preview from the Bookings step to load container units for numbering.
              </Text>
            </Paper>
          ) : (
            <ContainerPlacementGrid
              units={containerUnits}
              containerSlots={containerSlots}
              placements={containerPlacements}
              onChange={setContainerPlacements}
            />
          )}
          <Group>
            <Button
              color="edr-green"
              radius="md"
              loading={assign.isPending || create.isPending}
              onClick={handleAssign}
            >
              Assign bookings
            </Button>
            <Button variant="default" radius="md" onClick={() => setActiveStep(finalizeStep)}>
              Skip to finalize
            </Button>
          </Group>
        </Stack>
      );
    }

    // finalize
    return (
      <Stack gap="md">
        {displayWagonPlan.length || assignedSchedule?.trainSet?.wagons?.length ? (
          <TrainCompositionDiagram
            locomotive={assignedSchedule?.trainSet?.locomotive}
            wagons={
              assignedSchedule?.trainSet?.wagons?.length
                ? assignedSchedule.trainSet.wagons
                : displayWagonPlan
            }
            freightType={previewFreightType ?? bookingFreightType}
            trainNumber={assignedSchedule?.trainNumber}
            totalLengthMeters={assignedSchedule?.trainSet?.totalLengthMeters}
          />
        ) : null}

        {allocationComplete ? (
          <Paper
            p="lg"
            radius="lg"
            withBorder
            style={{ background: scheduleBrand.softSurface, borderColor: scheduleBrand.mutedBorder }}
          >
            <Group gap="md" align="flex-start" wrap="nowrap">
              <ThemeIcon size={44} radius="md" variant="light" color="edr-green">
                <CheckCircle2 size={22} />
              </ThemeIcon>
              <Stack gap={2} style={{ flex: 1 }}>
                <Text fw={700} size="lg">
                  Allocation complete
                </Text>
                <Text size="sm" c="dimmed">
                  Booking {booking.reference} is scheduled on train{" "}
                  <Text span fw={600} c="edr-green.7">
                    {assignedSchedule?.trainSet?.locomotive?.code ?? "—"}
                  </Text>
                  .
                </Text>
                <Group mt="sm">
                  <Button
                    color="edr-green"
                    radius="md"
                    onClick={() => {
                      onClose();
                      if (assignedSchedule?.id) {
                        navigate(
                          `/dashboard/operations/train-scheduling-v2/${assignedSchedule.id}`,
                        );
                      }
                    }}
                  >
                    View schedule
                  </Button>
                  <Button variant="default" radius="md" onClick={onClose}>
                    Close
                  </Button>
                </Group>
              </Stack>
            </Group>
          </Paper>
        ) : (
          <>
            <Paper
              p="lg"
              radius="lg"
              withBorder
              style={{ background: scheduleBrand.softSurface, borderColor: scheduleBrand.mutedBorder }}
            >
              <Group gap="md" align="flex-start" wrap="nowrap">
                <ThemeIcon size={44} radius="md" variant="light" color="edr-green">
                  <CheckCircle2 size={22} />
                </ThemeIcon>
                <Stack gap={2}>
                  <Text fw={600}>Ready to finalize</Text>
                  <Text size="sm" c="dimmed">
                    Finalizing locks the plan, moves the schedule to{" "}
                    <Text span fw={600} c="edr-green.7">
                      SCHEDULED
                    </Text>
                    , and completes the booking allocation.
                  </Text>
                </Stack>
              </Group>
            </Paper>
            <Group>
              <Button
                color="edr-green"
                size="md"
                radius="md"
                leftSection={<CheckCircle2 size={18} />}
                loading={finalize.isPending}
                onClick={handleFinalize}
              >
                Finalize schedule
              </Button>
            </Group>
          </>
        )}
      </Stack>
    );
  };

  return (
    <Modal
      opened={opened}
      onClose={onClose}
      withCloseButton
      size="90%"
      radius="lg"
      centered
      padding="lg"
      styles={{ content: { maxWidth: 1200 }, body: { paddingTop: 8 } }}
    >
      <Stack gap="lg">
        {/* Hero */}
        <Paper
          radius="xl"
          p="xl"
          style={{
            position: "relative",
            overflow: "hidden",
            background: scheduleBrand.heroGradient,
            boxShadow: scheduleBrand.shadow,
          }}
        >
          <Box
            style={{
              position: "absolute",
              top: -90,
              right: -50,
              width: 280,
              height: 280,
              borderRadius: "50%",
              background: "rgba(255,255,255,0.10)",
              pointerEvents: "none",
            }}
          />
          <Stack gap="lg" style={{ position: "relative" }}>
            <Group justify="space-between" align="flex-start" wrap="wrap">
              <Group gap="md" align="flex-start" wrap="nowrap">
                <ThemeIcon
                  size={56}
                  radius="lg"
                  variant="white"
                  style={{ color: "var(--mantine-color-edr-green-7)" }}
                >
                  <Train size={28} />
                </ThemeIcon>
                <Stack gap={6}>
                  <Group gap="sm" align="center" wrap="wrap">
                    <Title order={2} c="white" fw={700}>
                      Allocate {booking.reference}
                    </Title>
                  </Group>
                  <Box maw={360}>
                    <RouteCorridor
                      onDark
                      origin={booking.originYard?.name ?? booking.originYard?.label}
                      destination={
                        booking.destinationYard?.name ?? booking.destinationYard?.label
                      }
                    />
                  </Box>
                  <Group gap="sm" align="center">
                    <FreightTypeBadge freightType={booking.freightType} />
                    {booking.schedulingStatus ? (
                      <SchedulingStatusBadge status={booking.schedulingStatus} />
                    ) : null}
                  </Group>
                </Stack>
              </Group>
              {previewResult ? (
                <Badge
                  size="lg"
                  radius="sm"
                  variant="white"
                  c={previewResult.valid ? "edr-green.8" : "red.7"}
                  leftSection={
                    <Box
                      w={8}
                      h={8}
                      style={{
                        borderRadius: 999,
                        background: previewResult.valid
                          ? "var(--mantine-color-edr-green-6)"
                          : "var(--mantine-color-red-6)",
                      }}
                    />
                  }
                >
                  Preview {previewResult.valid ? "valid" : "has issues"}
                </Badge>
              ) : null}
            </Group>

            <SimpleGrid cols={{ base: 2, sm: 4 }} spacing="md">
              <StatTile
                onDark
                icon={Wallet}
                label="Total value"
                value={`${booking.paymentCurrency} ${amount.toLocaleString(undefined, {
                  minimumFractionDigits: 2,
                })}`}
                hint={booking.paymentStatus}
              />
              <StatTile onDark icon={Weight} label="Cargo weight" value={`${weight} T`} hint="VGM total" />
              <StatTile
                onDark
                icon={ContainerIcon}
                label="Containers"
                value={containerCount || "—"}
                hint={`${containers.length} line${containers.length === 1 ? "" : "s"}`}
              />
              <StatTile
                onDark
                icon={Flame}
                label="Priority"
                value={booking.priorityScore ?? 0}
                hint={booking.tradeDirection}
              />
            </SimpleGrid>
          </Stack>
        </Paper>

        {/* Workflow */}
        <Paper radius="xl" p="lg" withBorder style={{ borderColor: "var(--mantine-color-gray-2)" }}>
          <Stack gap="lg">
            <Group justify="space-between" align="center" wrap="nowrap">
              <Group gap="md" align="center" wrap="nowrap">
                <ThemeIcon
                  size={44}
                  radius="md"
                  variant="gradient"
                  gradient={{ from: "edr-green", to: "teal", deg: 135 }}
                >
                  <RouteIcon size={22} />
                </ThemeIcon>
                <Stack gap={2}>
                  <Title order={4} fw={700}>
                    Allocation workflow
                  </Title>
                  <Text size="sm" c="dimmed">
                    {completedCount} of {stepsMeta.length} steps complete · expand any step
                    to edit
                  </Text>
                </Stack>
              </Group>
              <RingProgress
                size={64}
                thickness={6}
                roundCaps
                sections={[{ value: progressPct, color: "edr-green" }]}
                label={
                  <Text ta="center" size="xs" fw={700} c="edr-green.7">
                    {progressPct}%
                  </Text>
                }
              />
            </Group>

            <WorkflowRail>
              {stepsMeta.map((step, index) => (
                <WorkflowStep
                  key={step.key}
                  index={index}
                  icon={step.icon}
                  title={step.title}
                  subtitle={step.subtitle}
                  state={
                    activeStep === index
                      ? "active"
                      : step.complete
                        ? "complete"
                        : "upcoming"
                  }
                  open={activeStep === index}
                  onToggle={() => toggleStep(index)}
                  rightSlot={renderStepRightSlot(step.key)}
                >
                  {renderStepBody(step.key)}
                </WorkflowStep>
              ))}
            </WorkflowRail>
          </Stack>
        </Paper>
      </Stack>
    </Modal>
  );
}
