import { Badge, Box, Group, HoverCard, Stack, Text } from "@mantine/core";
import {
  Building2,
  Container as ContainerIcon,
  Fuel,
  Gauge,
  Package,
  TrainFront,
  Weight,
} from "lucide-react";
import type { TrainScheduleDetail } from "@/types/trainScheduling";
import { freightBrand } from "@/theme/freight-brand";

type Wagon = NonNullable<TrainScheduleDetail["trainSet"]>["wagons"][number];
type Locomotive = NonNullable<TrainScheduleDetail["trainSet"]>["locomotive"];

interface InteractiveTrainConsistProps {
  wagons: Wagon[];
  locomotive: Locomotive | null | undefined;
  /** Resolve the customer/company name for a booking id (joined from schedule bookings). */
  getCompany: (bookingId: string | undefined) => string | null;
  selectedWagonId: string | null;
  onSelectWagon: (wagon: Wagon) => void;
  /** Booking id to highlight across the train (e.g. selected in the side panel). */
  highlightBookingId?: string | null;
}

const CONTAINER_GRADIENTS = [
  "linear-gradient(180deg, var(--mantine-color-cyan-5), var(--mantine-color-cyan-7))",
  "linear-gradient(180deg, var(--mantine-color-blue-5), var(--mantine-color-blue-7))",
];
const CONTAINER_BORDERS = ["var(--mantine-color-cyan-8)", "var(--mantine-color-blue-8)"];

function Wheels({ count = 2, dark = false }: { count?: number; dark?: boolean }) {
  return (
    <Group gap={count > 2 ? 10 : 18} justify="center" wrap="nowrap" mt={2}>
      {Array.from({ length: count }).map((_, i) => (
        <Box
          key={i}
          style={{
            width: 12,
            height: 12,
            borderRadius: "50%",
            background: dark
              ? "radial-gradient(circle at 35% 35%, #2c4a3a, #0f291b)"
              : "radial-gradient(circle at 35% 35%, var(--mantine-color-gray-5), var(--mantine-color-gray-8))",
            border: "2px solid var(--mantine-color-gray-4)",
            boxShadow: "inset 0 0 0 2px rgba(255,255,255,0.3), 0 1px 2px rgba(0,0,0,0.2)",
          }}
        />
      ))}
    </Group>
  );
}

function Coupler() {
  return (
    <Box style={{ width: 12, height: 70, display: "flex", alignItems: "center", flexShrink: 0 }}>
      <Box
        style={{
          width: "100%",
          height: 5,
          borderRadius: 3,
          background:
            "linear-gradient(90deg, var(--mantine-color-gray-4), var(--mantine-color-gray-6), var(--mantine-color-gray-4))",
        }}
      />
    </Box>
  );
}

function LocomotiveCar({ locomotive }: { locomotive: Locomotive }) {
  const code = locomotive?.code ?? "LOCO";
  return (
    <Box style={{ width: 120, flexShrink: 0 }}>
      <Box
        style={{
          position: "relative",
          height: 70,
          borderRadius: "12px 22px 9px 9px",
          background: `linear-gradient(160deg, ${freightBrand.primaryLight} 0%, ${freightBrand.primary} 45%, ${freightBrand.primaryDark} 100%)`,
          boxShadow: `${freightBrand.shadowSm}, inset 0 1px 0 rgba(255,255,255,0.25)`,
          border: "1px solid rgba(0,0,0,0.1)",
          overflow: "hidden",
          padding: "8px 9px 7px",
          color: "white",
        }}
      >
        {/* cab windows */}
        <Box style={{ position: "absolute", top: 9, right: 9, display: "flex", gap: 4 }}>
          <Box
            style={{
              width: 13,
              height: 11,
              borderRadius: "3px 5px 3px 3px",
              background: "linear-gradient(135deg, #E8FBFF 0%, #9ED9E8 100%)",
            }}
          />
        </Box>
        {/* headlight */}
        <Box
          style={{
            position: "absolute",
            bottom: 12,
            right: 5,
            width: 7,
            height: 7,
            borderRadius: "50%",
            background: "#fde68a",
            boxShadow: "0 0 9px 3px rgba(253,230,138,0.9)",
          }}
        />
        {/* hazard stripe */}
        <Box
          style={{
            position: "absolute",
            bottom: 0,
            left: 0,
            right: 0,
            height: 5,
            background: "repeating-linear-gradient(45deg, #fbbf24 0 6px, #1f2937 6px 12px)",
            opacity: 0.9,
          }}
        />
        <Group gap={5} wrap="nowrap" align="center">
          <TrainFront size={16} />
          <Text size="sm" fw={800} style={{ letterSpacing: 0.4 }}>
            {code}
          </Text>
        </Group>
        {locomotive?.maxPullWeightTons ? (
          <Group gap={3} wrap="nowrap" mt={3} style={{ opacity: 0.95 }}>
            <Gauge size={10} />
            <Text size="9px" fw={700}>
              {locomotive.maxPullWeightTons}T pull
            </Text>
          </Group>
        ) : null}
      </Box>
      <Wheels count={3} dark />
      <Text size="9px" ta="center" c="dimmed" mt={2} fw={700} style={{ letterSpacing: 1 }}>
        HEAD
      </Text>
    </Box>
  );
}

function WagonCar({
  wagon,
  company,
  selected,
  highlighted,
  onSelect,
}: {
  wagon: Wagon;
  company: string | null;
  selected: boolean;
  highlighted: boolean;
  onSelect: () => void;
}) {
  const allocation = wagon.allocations?.[0];
  const isEmpty = !allocation;
  const isBulk = (allocation?.loadType ?? "").toUpperCase().includes("BULK");
  const assigned = allocation?.allocatedWeightTons ?? wagon.assignedWeightTons ?? 0;
  const capacity = wagon.capacityTons ?? 0;
  const utilization = capacity > 0 ? Math.min(100, Math.round((assigned / capacity) * 100)) : 0;
  const accent = isEmpty ? "gray" : isBulk ? "orange" : "cyan";
  const accentVar = `var(--mantine-color-${accent}-6)`;

  const containerNumbers = (allocation?.containerItems ?? []).map(
    (c) => c.containerNumber?.trim() || "—",
  );
  const blocks = containerNumbers.slice(0, 2);

  const ringColor = selected
    ? freightBrand.primary
    : highlighted
      ? "var(--mantine-color-yellow-5)"
      : "transparent";

  return (
    <HoverCard width={280} shadow="lg" radius="md" position="top" withArrow openDelay={120}>
      <HoverCard.Target>
        <Box
          onClick={onSelect}
          style={{ width: 120, flexShrink: 0, cursor: "pointer" }}
        >
          <Box
            style={{
              position: "relative",
              height: 70,
              borderRadius: 11,
              background: isEmpty
                ? "var(--mantine-color-gray-0)"
                : "linear-gradient(180deg, white, var(--mantine-color-gray-0))",
              border: isEmpty
                ? "1.5px dashed var(--mantine-color-gray-4)"
                : "1px solid var(--mantine-color-gray-3)",
              boxShadow:
                ringColor !== "transparent"
                  ? `0 0 0 3px ${ringColor}, 0 4px 12px rgba(15,41,27,0.12)`
                  : isEmpty
                    ? "none"
                    : "0 3px 10px rgba(15,41,27,0.08)",
              overflow: "hidden",
              display: "flex",
              flexDirection: "column",
              transition: "box-shadow 120ms ease",
            }}
          >
            {/* top accent strip */}
            <Box
              style={{
                height: 4,
                background: isEmpty
                  ? "var(--mantine-color-gray-3)"
                  : `linear-gradient(90deg, ${accentVar}, var(--mantine-color-${accent}-4))`,
              }}
            />
            {/* header */}
            <Group justify="space-between" px={7} pt={3} wrap="nowrap">
              <Text size="10px" fw={800} c="gray.7">
                #{wagon.sequenceNo}
              </Text>
              {isEmpty ? (
                <Text size="8px" c="dimmed" fw={700} style={{ letterSpacing: 0.5 }}>
                  EMPTY
                </Text>
              ) : (
                <Group gap={2} wrap="nowrap">
                  {isBulk ? (
                    <Fuel size={10} color={accentVar} />
                  ) : (
                    <ContainerIcon size={10} color={accentVar} />
                  )}
                  <Text size="8px" fw={700} c={`${accent}.7`} style={{ letterSpacing: 0.3 }}>
                    {isBulk ? "BULK" : "CONT"}
                  </Text>
                </Group>
              )}
            </Group>

            {/* body */}
            <Box style={{ flex: 1, padding: "3px 7px", display: "flex", alignItems: "center" }}>
              {isEmpty ? (
                <Text size="9px" c="dimmed" ta="center" style={{ width: "100%" }}>
                  Available
                </Text>
              ) : isBulk ? (
                <Stack gap={2} style={{ width: "100%" }}>
                  <Box
                    style={{
                      height: 16,
                      borderRadius: 5,
                      background: "var(--mantine-color-orange-0)",
                      border: "1px solid var(--mantine-color-orange-2)",
                      overflow: "hidden",
                      position: "relative",
                    }}
                  >
                    <Box
                      style={{
                        position: "absolute",
                        inset: 0,
                        width: `${utilization}%`,
                        background:
                          "linear-gradient(90deg, var(--mantine-color-orange-6), var(--mantine-color-orange-4))",
                      }}
                    />
                  </Box>
                </Stack>
              ) : (
                <Group gap={3} justify="center" wrap="nowrap" style={{ width: "100%" }}>
                  {(blocks.length ? blocks : ["—"]).map((cn, i) => (
                    <Box
                      key={i}
                      style={{
                        flex: 1,
                        minWidth: 0,
                        height: 26,
                        borderRadius: 4,
                        background: CONTAINER_GRADIENTS[i % CONTAINER_GRADIENTS.length],
                        border: `1px solid ${CONTAINER_BORDERS[i % CONTAINER_BORDERS.length]}`,
                        boxShadow: "inset 0 1px 0 rgba(255,255,255,0.3)",
                        display: "flex",
                        alignItems: "center",
                        justifyContent: "center",
                        padding: "0 2px",
                      }}
                    >
                      <Text size="8px" fw={700} c="white" truncate style={{ maxWidth: "100%" }}>
                        {cn}
                      </Text>
                    </Box>
                  ))}
                </Group>
              )}
            </Box>

            {/* footer */}
            <Box
              style={{
                borderTop: "1px solid var(--mantine-color-gray-1)",
                padding: "2px 7px",
                background: isEmpty ? "transparent" : "var(--mantine-color-gray-0)",
              }}
            >
              <Group justify="space-between" wrap="nowrap" gap={3}>
                <Text size="8px" c="dimmed" fw={600} truncate>
                  {wagon.physicalWagonNumber ?? wagon.wagonType?.code ?? "Wagon"}
                </Text>
                {!isEmpty ? (
                  <Text size="8px" c="gray.6" fw={700} style={{ whiteSpace: "nowrap" }}>
                    {assigned}T
                  </Text>
                ) : null}
              </Group>
            </Box>
          </Box>
          <Wheels count={2} />
        </Box>
      </HoverCard.Target>

      <HoverCard.Dropdown p="sm">
        <Stack gap={8}>
          <Group justify="space-between" wrap="nowrap">
            <Group gap={6} wrap="nowrap">
              <Box
                style={{
                  width: 26,
                  height: 26,
                  borderRadius: 7,
                  display: "flex",
                  alignItems: "center",
                  justifyContent: "center",
                  background: isEmpty
                    ? "var(--mantine-color-gray-1)"
                    : freightBrand.gradient,
                  color: isEmpty ? "var(--mantine-color-gray-6)" : "white",
                }}
              >
                <TrainFront size={15} />
              </Box>
              <div>
                <Text size="sm" fw={800}>
                  Wagon #{wagon.sequenceNo}
                </Text>
                <Text size="10px" c="dimmed">
                  {wagon.physicalWagonNumber ?? wagon.wagonType?.code ?? "Unassigned"}
                </Text>
              </div>
            </Group>
            {!isEmpty ? (
              <Badge size="xs" variant="light" color={isBulk ? "orange" : "cyan"}>
                {isBulk ? "Bulk" : "Container"}
              </Badge>
            ) : null}
          </Group>

          {isEmpty ? (
            <Text size="xs" c="dimmed">
              Empty slot — available for allocation.
            </Text>
          ) : (
            <Stack gap={6}>
              {company ? (
                <Group gap={6} wrap="nowrap">
                  <Building2 size={13} color={freightBrand.primary} />
                  <Text size="xs" fw={700} truncate>
                    {company}
                  </Text>
                </Group>
              ) : null}
              <Group gap={6} wrap="nowrap">
                <Package size={13} color="var(--mantine-color-gray-6)" />
                <Text size="xs" c="dimmed">
                  {allocation?.bookingReference ?? "Unknown booking"}
                </Text>
              </Group>

              {containerNumbers.length ? (
                <div>
                  <Text size="10px" c="dimmed" fw={700} mb={3} tt="uppercase">
                    Containers
                  </Text>
                  <Group gap={4}>
                    {containerNumbers.map((cn, i) => (
                      <Badge key={i} size="xs" variant="outline" color="cyan" radius="sm">
                        {cn}
                      </Badge>
                    ))}
                  </Group>
                </div>
              ) : null}

              {isBulk && allocation?.bulkLoad?.cargoDescription ? (
                <Text size="xs" c="dimmed">
                  {allocation.bulkLoad.cargoDescription}
                </Text>
              ) : null}

              <Group gap={6} wrap="nowrap">
                <Weight size={13} color="var(--mantine-color-gray-6)" />
                <Text size="xs" c="dimmed">
                  {assigned}T / {capacity}T ({utilization}%)
                </Text>
              </Group>
              <Box
                style={{
                  height: 5,
                  borderRadius: 3,
                  background: "var(--mantine-color-gray-1)",
                  overflow: "hidden",
                }}
              >
                <Box
                  style={{
                    width: `${utilization}%`,
                    height: "100%",
                    background:
                      utilization >= 100
                        ? "var(--mantine-color-red-5)"
                        : `var(--mantine-color-${accent}-5)`,
                  }}
                />
              </Box>
              <Text size="10px" c="dimmed" ta="center">
                Click the wagon to edit or remove
              </Text>
            </Stack>
          )}
        </Stack>
      </HoverCard.Dropdown>
    </HoverCard>
  );
}

export const InteractiveTrainConsist = ({
  wagons,
  locomotive,
  getCompany,
  selectedWagonId,
  onSelectWagon,
  highlightBookingId,
}: InteractiveTrainConsistProps) => {
  return (
    <Box
      style={{
        position: "relative",
        padding: "8px 12px 18px",
        borderRadius: 14,
        background: "linear-gradient(180deg, var(--mantine-color-gray-0), white)",
        border: "1px solid var(--mantine-color-gray-2)",
        overflowX: "auto",
      }}
    >
      <Group gap={0} wrap="nowrap" align="flex-start" style={{ minWidth: "min-content" }}>
        {locomotive ? <LocomotiveCar locomotive={locomotive} /> : null}
        {wagons.length === 0 ? (
          <Text size="sm" c="dimmed" pl="md" pt="lg">
            No wagons assigned
          </Text>
        ) : (
          wagons.map((wagon, i) => {
            const bookingId = wagon.allocations?.[0]?.bookingId;
            return (
              <Group key={wagon.id} gap={0} wrap="nowrap" align="flex-start">
                {i > 0 || locomotive ? <Coupler /> : null}
                <WagonCar
                  wagon={wagon}
                  company={getCompany(bookingId)}
                  selected={selectedWagonId === wagon.id}
                  highlighted={Boolean(highlightBookingId && bookingId === highlightBookingId)}
                  onSelect={() => onSelectWagon(wagon)}
                />
              </Group>
            );
          })
        )}
      </Group>

      {/* track bed under the whole consist */}
      <Box
        style={{
          position: "absolute",
          left: 12,
          right: 12,
          bottom: 8,
          height: 8,
        }}
      >
        <Box
          style={{
            position: "absolute",
            inset: 0,
            background:
              "repeating-linear-gradient(90deg, var(--mantine-color-gray-4) 0 5px, transparent 5px 20px)",
            opacity: 0.5,
            borderRadius: 2,
          }}
        />
        <Box
          style={{
            position: "absolute",
            left: 0,
            right: 0,
            top: 1,
            height: 2,
            borderRadius: 1,
            background: "var(--mantine-color-gray-5)",
          }}
        />
        <Box
          style={{
            position: "absolute",
            left: 0,
            right: 0,
            bottom: 1,
            height: 2,
            borderRadius: 1,
            background: "var(--mantine-color-gray-5)",
          }}
        />
      </Box>
    </Box>
  );
};
