import { Box, Group, Stack, Text } from "@mantine/core";
import { useQuery } from "@tanstack/react-query";

import type { Freight } from "@edr/types";

import { bookingsService } from "@/services/bookings.service";
import type {
  MileLegSummary,
  MileVehicleSummary,
} from "@/services/bookings.service";

import { CardTitle, SectionCard } from "./layout";

function StatusPill({ status }: { status: string }) {
  const s = status.toUpperCase();
  const done = s.includes("DELIVER") || s.includes("COMPLET") || s.includes("PAID");
  const active = s.includes("TRANSIT") || s.includes("PROGRESS") || s.includes("ASSIGN");
  const dot = done ? "#0EA371" : active ? "#2563EB" : "#94A3B8";
  const color = done ? "#0A6F4D" : active ? "#1E40AF" : "#475569";
  const bg = done ? "#ECF6F1" : active ? "#EAF1FE" : "#F1F4F7";
  const border = done ? "#CDEBDD" : active ? "#CFDDFB" : "#E1E7EE";
  const label = status
    .replace(/_/g, " ")
    .toLowerCase()
    .replace(/\b\w/g, (m) => m.toUpperCase());

  return (
    <Group
      component="span"
      gap={6}
      align="center"
      wrap="nowrap"
      style={{
        display: "inline-flex",
        borderRadius: 999,
        backgroundColor: bg,
        border: `1px solid ${border}`,
        padding: "4px 10px",
        fontSize: 11.5,
        fontWeight: 700,
        color,
      }}
    >
      <Box
        component="span"
        style={{ width: 6, height: 6, borderRadius: 999, backgroundColor: dot }}
      />
      {label}
    </Group>
  );
}

function VehicleRow({ v }: { v: MileVehicleSummary }) {
  const parts: string[] = [];
  if (v.driverName) parts.push(v.driverName);
  if (v.containerNumber) parts.push(`Container ${v.containerNumber}`);
  if (v.distanceKm != null) parts.push(`${v.distanceKm} km`);

  return (
    <Group
      justify="space-between"
      align="flex-start"
      wrap="nowrap"
      py={8}
      style={{ borderTop: "1px solid #F2F5F8" }}
    >
      <Stack gap={2} style={{ minWidth: 0 }}>
        <Text fz="13px" fw={700} c="#10202F">
          {v.plate || v.code || "Vehicle"}
        </Text>
        {parts.length > 0 && (
          <Text fz="12px" c="#6B7C8E">
            {parts.join("  ·  ")}
          </Text>
        )}
      </Stack>
      {v.code && v.plate && (
        <Text fz="12px" c="#9AA8B5" style={{ whiteSpace: "nowrap" }}>
          {v.code}
        </Text>
      )}
    </Group>
  );
}

function LegBlock({
  title,
  leg,
  address,
}: {
  title: string;
  leg: MileLegSummary | null;
  address?: string | null;
}) {
  const fmtMoney = (n: number | null, currency: string) =>
    n == null
      ? null
      : `${currency} ${Number(n).toLocaleString(undefined, {
          minimumFractionDigits: 2,
          maximumFractionDigits: 2,
        })}`;

  return (
    <Box>
      <Group justify="space-between" align="center" pb={8}>
        <Text fz="13px" fw={700} c="#10202F">
          {title}
        </Text>
        {leg ? (
          <StatusPill status={leg.status} />
        ) : (
          <StatusPill status="AWAITING_ASSIGNMENT" />
        )}
      </Group>

      {address && (
        <Text fz="12px" c="#6B7C8E" pb={4}>
          {title.startsWith("First") ? "Pickup" : "Delivery"}:{" "}
          <b style={{ color: "#10202F" }}>{address}</b>
        </Text>
      )}

      {!leg ? (
        <Text fz="12px" c="#9AA8B5" fs="italic" py={6}>
          Requested — a vehicle and driver will be assigned soon.
        </Text>
      ) : leg.vehicles.length > 0 ? (
        <Box>
          {leg.vehicles.map((v, i) => (
            <VehicleRow key={`${v.plate ?? v.code ?? "v"}-${i}`} v={v} />
          ))}
        </Box>
      ) : (
        <Text fz="12px" c="#9AA8B5" fs="italic" py={6}>
          No vehicle assigned yet.
        </Text>
      )}

      {leg && (
        <Group
          justify="space-between"
          align="center"
          pt={8}
          mt={4}
          style={{ borderTop: "1px solid #F2F5F8" }}
        >
          <Group gap={16}>
            {leg.exactKm != null && (
              <Text fz="12px" c="#6B7C8E">
                Total distance{" "}
                <b style={{ color: "#10202F" }}>{leg.exactKm} km</b>
              </Text>
            )}
            {leg.remainingPayment != null && leg.remainingPayment > 0 && (
              <Text fz="12px" c="#6B7C8E">
                Balance{" "}
                <b style={{ color: "#10202F" }}>
                  {fmtMoney(leg.remainingPayment, leg.currency)}
                </b>
              </Text>
            )}
          </Group>
          {leg.invoiced && (
            <Text fz="11px" fw={700} c="#0A6F4D">
              Invoiced
            </Text>
          )}
        </Group>
      )}
    </Box>
  );
}

export function MileSummaryCard({ booking }: { booking: Freight.IBooking }) {
  const { data } = useQuery({
    queryKey: ["booking-mile-summary", booking.id],
    queryFn: () => bookingsService.mileSummary(booking.id),
  });

  const firstLeg = data?.firstMile ?? null;
  const lastLeg = data?.lastMile ?? null;

  // The backend doesn't persist an "enabled" flag — the presence of a
  // pickup/delivery address is the request signal. Also show a leg once its
  // record exists, regardless of address.
  const showFirst = !!booking.firstMilePickupAddress || !!firstLeg;
  const showLast = !!booking.lastMileDeliveryAddress || !!lastLeg;

  if (!showFirst && !showLast) return null;

  return (
    <SectionCard p={22}>
      <Box pb={12}>
        <CardTitle>First & Last Mile</CardTitle>
      </Box>
      <Stack gap={20}>
        {showFirst && (
          <LegBlock
            title="First mile"
            leg={firstLeg}
            address={booking.firstMilePickupAddress}
          />
        )}
        {showLast && (
          <LegBlock
            title="Last mile"
            leg={lastLeg}
            address={booking.lastMileDeliveryAddress}
          />
        )}
      </Stack>
    </SectionCard>
  );
}
