import { memo, useMemo } from "react";
import { Box, Group, Paper, Progress, Stack, Text, Tooltip } from "@mantine/core";
import { useElementSize } from "@mantine/hooks";
import { Box as BoxIcon, Container as ContainerIcon, Fuel, Gauge, TrainFront } from "lucide-react";

import { freightBrand } from "@/theme/freight-brand";

/**
 * Visual train composition: a locomotive coupled to its wagons, drawn like a real
 * consist. Long trains wrap into a serpentine (zig-zag) so the whole train stays on
 * screen. Each wagon shows its load (container blocks or a bulk fill gauge), physical
 * wagon number and tonnage.
 */

type DiagramWagonInput = {
  sequenceNo: number;
  capacityTons: number;
  assignedWeightTons: number;
  tareWeightTons?: number | null;
  slotLoadType?: string | null;
  wagonType?: { code?: string | null } | null;
  wagonTypeCode?: string | null;
  /** Pinned physical wagon — slots sharing one (cross-leg TEU) draw as ONE car. */
  physicalWagonId?: string | null;
  physicalWagonNumber?: string | null;
  allocations?: Array<{
    bookingReference?: string | null;
    bookingId?: string;
    loadType?: string | null;
    containerItems?: Array<{ containerNumber?: string | null }> | null;
    bulkLoad?: { weightTons?: number | null; cargoDescription?: string | null } | null;
  }> | null;
};

type NormalizedWagon = {
  sequenceNo: number;
  capacityTons: number;
  assignedWeightTons: number;
  tareWeightTons: number;
  wagonTypeCode: string | null;
  physicalWagonNumber: string | null;
  isEmpty: boolean;
  isBulk: boolean;
  containerNumbers: string[];
  bookingRefs: string[];
  cargoDescription: string | null;
};

const CAR_WIDTH = 150; // car body + coupler footprint

const round1 = (n: number) => Math.round(n * 10) / 10;

function normalizeWagon(w: DiagramWagonInput, freightType?: string | null): NormalizedWagon {
  const allocations = w.allocations ?? [];
  const firstLoad = (
    w.slotLoadType ??
    allocations[0]?.loadType ??
    freightType ??
    ""
  )
    .toString()
    .toUpperCase();
  const isBulk = firstLoad.includes("BULK");
  const containerNumbers: string[] = [];
  const bookingRefs: string[] = [];
  let cargoDescription: string | null = null;
  for (const alloc of allocations) {
    if (alloc.bookingReference) bookingRefs.push(alloc.bookingReference);
    for (const item of alloc.containerItems ?? []) {
      containerNumbers.push(item.containerNumber?.trim() || "—");
    }
    if (alloc.bulkLoad?.cargoDescription) cargoDescription = alloc.bulkLoad.cargoDescription;
  }
  return {
    sequenceNo: w.sequenceNo,
    capacityTons: Number(w.capacityTons) || 0,
    assignedWeightTons: Number(w.assignedWeightTons) || 0,
    tareWeightTons: Number(w.tareWeightTons) || 0,
    wagonTypeCode: w.wagonType?.code ?? w.wagonTypeCode ?? null,
    physicalWagonNumber: w.physicalWagonNumber ?? null,
    isEmpty: allocations.length === 0,
    isBulk,
    containerNumbers,
    bookingRefs,
    cargoDescription,
  };
}

function chunk<T>(items: T[], size: number): T[][] {
  if (size <= 0) return [items];
  const rows: T[][] = [];
  for (let i = 0; i < items.length; i += size) rows.push(items.slice(i, i + size));
  return rows;
}

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: 13,
            height: 13,
            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: 16, height: 78, display: "flex", alignItems: "center", flexShrink: 0 }}>
      <Box
        style={{
          width: "100%",
          height: 6,
          borderRadius: 3,
          background:
            "linear-gradient(90deg, var(--mantine-color-gray-4), var(--mantine-color-gray-6), var(--mantine-color-gray-4))",
          boxShadow: "0 1px 1px rgba(0,0,0,0.15)",
        }}
      />
    </Box>
  );
}

const LocomotiveCar = memo(function LocomotiveCar({
  code,
  name,
  maxPullWeightTons,
}: {
  code: string;
  name?: string | null;
  maxPullWeightTons?: number | null;
}) {
  return (
    <Tooltip
      label={`Locomotive ${code}${name ? ` · ${name}` : ""}${
        maxPullWeightTons ? ` · pulls up to ${maxPullWeightTons}T` : ""
      }`}
      withArrow
    >
      <Box style={{ width: 134, flexShrink: 0 }}>
        <Box
          style={{
            position: "relative",
            height: 78,
            borderRadius: "14px 26px 10px 10px",
            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: "10px 10px 8px",
            color: "white",
          }}
        >
          {/* roofline */}
          <Box
            style={{
              position: "absolute",
              top: 0,
              left: 0,
              right: 14,
              height: 5,
              background: "rgba(0,0,0,0.22)",
              borderRadius: "14px 0 0 0",
            }}
          />
          {/* roof vents */}
          <Box style={{ position: "absolute", top: 1, left: 16, display: "flex", gap: 5 }}>
            {[0, 1, 2].map((i) => (
              <Box
                key={i}
                style={{
                  width: 10,
                  height: 3,
                  borderRadius: 2,
                  background: "rgba(255,255,255,0.35)",
                }}
              />
            ))}
          </Box>
          {/* cab windows */}
          <Box style={{ position: "absolute", top: 10, right: 10, display: "flex", gap: 4 }}>
            <Box
              style={{
                width: 15,
                height: 13,
                borderRadius: "3px 6px 3px 3px",
                background: "linear-gradient(135deg, #E8FBFF 0%, #9ED9E8 100%)",
                border: "1px solid rgba(0,0,0,0.15)",
              }}
            />
            <Box
              style={{
                width: 12,
                height: 13,
                borderRadius: 3,
                background: "linear-gradient(135deg, rgba(232,251,255,0.8), rgba(158,217,232,0.6))",
                border: "1px solid rgba(0,0,0,0.12)",
              }}
            />
          </Box>
          {/* headlight */}
          <Box
            style={{
              position: "absolute",
              bottom: 14,
              right: 5,
              width: 8,
              height: 8,
              borderRadius: "50%",
              background: "#fde68a",
              boxShadow: "0 0 10px 3px rgba(253,230,138,0.9)",
            }}
          />
          {/* hazard stripe on the nose */}
          <Box
            style={{
              position: "absolute",
              bottom: 0,
              left: 0,
              right: 0,
              height: 6,
              background:
                "repeating-linear-gradient(45deg, #fbbf24 0 7px, #1f2937 7px 14px)",
              opacity: 0.9,
            }}
          />
          <Group gap={6} wrap="nowrap" align="center">
            <TrainFront size={18} />
            <Text size="sm" fw={800} style={{ letterSpacing: 0.4 }}>
              {code}
            </Text>
          </Group>
          <Text size="9px" mt={1} style={{ opacity: 0.85 }} lineClamp={1}>
            {name ?? "Locomotive"}
          </Text>
          {maxPullWeightTons ? (
            <Group gap={3} wrap="nowrap" mt={3} style={{ opacity: 0.95 }}>
              <Gauge size={10} />
              <Text size="9px" fw={700}>
                {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>
    </Tooltip>
  );
});

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)",
];

const WagonCar = memo(function WagonCar({ wagon }: { wagon: NormalizedWagon }) {
  // GROSS on both sides: cargo + tare vs rated payload + tare.
  const grossTons = round1(wagon.assignedWeightTons + wagon.tareWeightTons);
  const maxGrossTons = round1(wagon.capacityTons + wagon.tareWeightTons);
  const utilization =
    maxGrossTons > 0 ? Math.min(100, Math.round((grossTons / maxGrossTons) * 100)) : 0;
  const accent = wagon.isEmpty ? "gray" : wagon.isBulk ? "orange" : "cyan";
  const accentVar = `var(--mantine-color-${accent}-6)`;

  const tooltipLabel = wagon.isEmpty
    ? `Wagon #${wagon.sequenceNo} · empty / available`
    : `Wagon #${wagon.sequenceNo}${wagon.physicalWagonNumber ? ` · ${wagon.physicalWagonNumber}` : ""}\n${
        wagon.bookingRefs.length ? wagon.bookingRefs.join(", ") : ""
      }${
        wagon.containerNumbers.length ? `\nContainers: ${wagon.containerNumbers.join(", ")}` : ""
      }${wagon.cargoDescription ? `\n${wagon.cargoDescription}` : ""}\nGross: ${grossTons}/${maxGrossTons}T (${utilization}%)\nCargo: ${wagon.assignedWeightTons}T${
        wagon.tareWeightTons ? ` · Tare: ${wagon.tareWeightTons}T` : ""
      }`;

  // container blocks: one per container number, up to 4 — cross-leg TEU
  // sharing can put two 20ft pairs (riding different legs) on one wagon.
  // 1–2 sit side by side; 3–4 form a 2×2 grid (two rows, up/down).
  const blocks = wagon.containerNumbers.slice(0, 4);
  const twoRows = blocks.length > 2;

  return (
    <Tooltip label={tooltipLabel} withArrow multiline maw={240} style={{ whiteSpace: "pre-line" }}>
      <Box style={{ width: 134, flexShrink: 0 }}>
        <Box
          style={{
            position: "relative",
            height: 78,
            borderRadius: 12,
            background: wagon.isEmpty
              ? "var(--mantine-color-gray-0)"
              : "linear-gradient(180deg, white, var(--mantine-color-gray-0))",
            border: wagon.isEmpty
              ? "1.5px dashed var(--mantine-color-gray-4)"
              : "1px solid var(--mantine-color-gray-3)",
            boxShadow: wagon.isEmpty ? "none" : "0 3px 10px rgba(15,41,27,0.08)",
            overflow: "hidden",
            display: "flex",
            flexDirection: "column",
          }}
        >
          {/* top accent strip */}
          <Box
            style={{
              height: 4,
              background: wagon.isEmpty
                ? "var(--mantine-color-gray-3)"
                : `linear-gradient(90deg, ${accentVar}, var(--mantine-color-${accent}-4))`,
            }}
          />
          {/* header */}
          <Group justify="space-between" px={8} pt={4} wrap="nowrap">
            <Text size="10px" fw={800} c="gray.7">
              #{wagon.sequenceNo}
            </Text>
            {wagon.isEmpty ? (
              <Text size="9px" c="dimmed" fw={700} style={{ letterSpacing: 0.5 }}>
                EMPTY
              </Text>
            ) : (
              <Group gap={3} wrap="nowrap">
                {wagon.isBulk ? <Fuel size={11} color={accentVar} /> : <ContainerIcon size={11} color={accentVar} />}
                <Text size="9px" fw={700} c={`${accent}.7`} style={{ letterSpacing: 0.4 }}>
                  {wagon.isBulk ? "BULK" : "CONT"}
                </Text>
              </Group>
            )}
          </Group>

          {/* body */}
          <Box style={{ flex: 1, padding: "4px 8px 4px", display: "flex", alignItems: "center" }}>
            {wagon.isEmpty ? (
              <Group gap={4} justify="center" style={{ width: "100%" }}>
                <BoxIcon size={14} color="var(--mantine-color-gray-4)" />
                <Text size="9px" c="dimmed">
                  Available
                </Text>
              </Group>
            ) : wagon.isBulk ? (
              <Stack gap={3} style={{ width: "100%" }}>
                <Box
                  style={{
                    height: 18,
                    borderRadius: 6,
                    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))",
                      boxShadow: "inset 0 1px 0 rgba(255,255,255,0.35)",
                    }}
                  />
                </Box>
                <Text size="9px" c="dimmed" ta="center" fw={600}>
                  {grossTons}/{maxGrossTons}T
                </Text>
              </Stack>
            ) : (
              <Box
                style={{
                  width: "100%",
                  display: "grid",
                  gridTemplateColumns: blocks.length > 1 ? "1fr 1fr" : "1fr",
                  gap: 3,
                }}
              >
                {(blocks.length ? blocks : ["—"]).map((cn, i) => (
                  <Box
                    key={i}
                    style={{
                      minWidth: 0,
                      height: twoRows ? 14 : 28,
                      borderRadius: twoRows ? 4 : 5,
                      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), 0 1px 2px rgba(0,0,0,0.15)",
                      display: "flex",
                      flexDirection: "column",
                      alignItems: "center",
                      justifyContent: "center",
                      padding: "0 3px",
                    }}
                  >
                    {/* corrugation lines — dropped in two-row mode, no room */}
                    {!twoRows ? (
                      <Box
                        style={{
                          width: "80%",
                          height: 2,
                          marginBottom: 2,
                          background:
                            "repeating-linear-gradient(90deg, rgba(255,255,255,0.4) 0 3px, transparent 3px 6px)",
                          borderRadius: 1,
                        }}
                      />
                    ) : null}
                    <Text size={twoRows ? "7px" : "8px"} fw={700} c="white" truncate style={{ maxWidth: "100%" }}>
                      {cn}
                    </Text>
                  </Box>
                ))}
              </Box>
            )}
          </Box>

          {/* utilization hairline */}
          {!wagon.isEmpty && !wagon.isBulk ? (
            <Box style={{ height: 3, background: "var(--mantine-color-gray-1)" }}>
              <Box
                style={{
                  width: `${utilization}%`,
                  height: "100%",
                  background:
                    utilization >= 100
                      ? "var(--mantine-color-red-5)"
                      : `var(--mantine-color-${accent}-5)`,
                }}
              />
            </Box>
          ) : null}

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

/** Railway track: two rails over evenly-spaced sleepers. */
function TrackBed() {
  return (
    <Box
      style={{
        position: "absolute",
        left: 4,
        right: 4,
        bottom: 4,
        height: 10,
      }}
    >
      {/* sleepers */}
      <Box
        style={{
          position: "absolute",
          inset: 0,
          background:
            "repeating-linear-gradient(90deg, var(--mantine-color-gray-4) 0 5px, transparent 5px 20px)",
          opacity: 0.6,
          borderRadius: 2,
        }}
      />
      {/* rails */}
      <Box
        style={{
          position: "absolute",
          left: 0,
          right: 0,
          top: 1,
          height: 2,
          borderRadius: 1,
          background: "var(--mantine-color-gray-6)",
        }}
      />
      <Box
        style={{
          position: "absolute",
          left: 0,
          right: 0,
          bottom: 1,
          height: 2,
          borderRadius: 1,
          background: "var(--mantine-color-gray-6)",
        }}
      />
    </Box>
  );
}

export const TrainCompositionDiagram = memo(function TrainCompositionDiagram({
  locomotive,
  locomotives,
  wagons,
  freightType,
  trainNumber,
  totalLengthMeters,
}: {
  locomotive?: { code?: string | null; name?: string | null; maxPullWeightTons?: number | null } | null;
  /** Full locomotive set (built trains, ≥2). Takes precedence over `locomotive`. */
  locomotives?: Array<{
    code?: string | null;
    name?: string | null;
    maxPullWeightTons?: number | null;
  }> | null;
  wagons: DiagramWagonInput[];
  freightType?: string | null;
  trainNumber?: string | null;
  totalLengthMeters?: number | null;
}) {
  const { ref, width } = useElementSize();

  const locos = useMemo(
    () => (locomotives?.length ? locomotives : locomotive ? [locomotive] : []),
    [locomotives, locomotive],
  );

  // One car per PHYSICAL wagon: cross-leg TEU sharing pins two plan slots
  // (e.g. intercity + export on disjoint legs) onto the same wagon — merge
  // their cargo into one drawn car. Tare counts once; cargo and containers
  // combine. Slots without a pinned wagon stay their own car.
  const merged = useMemo(() => {
    const groups: DiagramWagonInput[][] = [];
    const byPhysical = new Map<string, DiagramWagonInput[]>();
    for (const w of wagons) {
      const existing = w.physicalWagonId ? byPhysical.get(w.physicalWagonId) : undefined;
      if (existing) {
        existing.push(w);
        continue;
      }
      const group = [w];
      groups.push(group);
      if (w.physicalWagonId) byPhysical.set(w.physicalWagonId, group);
    }
    return groups.map((group) =>
      group.length === 1
        ? group[0]!
        : {
            ...group[0]!,
            assignedWeightTons: group.reduce(
              (s, w) => s + (Number(w.assignedWeightTons) || 0),
              0,
            ),
            allocations: group.flatMap((w) => w.allocations ?? []),
          },
    );
  }, [wagons]);

  const normalized = useMemo(
    () => merged.map((w) => normalizeWagon(w, freightType)),
    [merged, freightType],
  );

  const stats = useMemo(() => {
    const assigned = normalized.filter((w) => !w.isEmpty).length;
    const totalWeight = normalized.reduce((s, w) => s + w.assignedWeightTons, 0);
    const totalCapacity = normalized.reduce((s, w) => s + w.capacityTons, 0);
    // Every coupled wagon's tare is hauled — empty ones included — so the
    // locomotive pull limit is measured against gross (tare + cargo), the same
    // ceiling the allocation engine spends from.
    const totalTare = normalized.reduce((s, w) => s + w.tareWeightTons, 0);
    const grossWeight = totalWeight + totalTare;
    // Engine rule (combinedLocomotiveLimits): coupled locomotives pull
    // TOGETHER, so their pull limits SUM.
    const pullLimits = locos
      .map((l) => Number(l.maxPullWeightTons))
      .filter((v) => Number.isFinite(v) && v > 0);
    const pullLimit = pullLimits.length
      ? pullLimits.reduce((sum, v) => sum + v, 0)
      : null;
    return {
      total: normalized.length,
      assigned,
      empty: normalized.length - assigned,
      totalWeight: Math.round(totalWeight * 100) / 100,
      totalTare: Math.round(totalTare * 100) / 100,
      grossWeight: Math.round(grossWeight * 100) / 100,
      totalCapacity,
      pullLimit,
      pullUtil: pullLimit
        ? Math.min(100, Math.round((grossWeight / pullLimit) * 100))
        : null,
    };
  }, [normalized, locos]);

  // cars-per-row from measured width; each locomotive counts as one car
  const perRow = Math.max(1, Math.floor((width || CAR_WIDTH) / CAR_WIDTH));
  const cars = useMemo(
    () => [
      ...locos.map((l) => ({ kind: "loco" as const, l })),
      ...normalized.map((w) => ({ kind: "wagon" as const, w })),
    ],
    [locos, normalized],
  );
  const rows = useMemo(() => chunk(cars, perRow), [cars, perRow]);

  if (!locos.length && !wagons.length) return null;

  return (
    <Paper
      radius="lg"
      p="lg"
      withBorder
      style={{
        borderColor: "var(--mantine-color-gray-2)",
        background: "white",
      }}
    >
      <Stack gap="md">
        {/* Header */}
        <Group justify="space-between" align="flex-start" wrap="wrap" gap="sm">
          <Group gap="sm" wrap="nowrap">
            <Box
              style={{
                display: "flex",
                alignItems: "center",
                justifyContent: "center",
                width: 40,
                height: 40,
                borderRadius: 11,
                background: freightBrand.gradient,
                boxShadow: freightBrand.shadowSm,
                color: "white",
              }}
            >
              <TrainFront size={21} />
            </Box>
            <Stack gap={0}>
              <Text fw={800} style={{ letterSpacing: 0.2 }}>
                Train composition
              </Text>
              <Text size="xs" c="dimmed">
                {trainNumber ? `${trainNumber} · ` : ""}
                {stats.total} wagons · {stats.assigned} loaded · {stats.empty} empty
                {totalLengthMeters ? ` · ${totalLengthMeters}m` : ""}
              </Text>
            </Stack>
          </Group>

          <Group gap="md">
            <Group
              gap={6}
              style={{
                padding: "4px 12px",
                borderRadius: 999,
                background: "var(--mantine-color-gray-0)",
                border: "1px solid var(--mantine-color-gray-2)",
              }}
            >
              <Text size="xs" fw={700} c="dark.4">
                {stats.totalWeight}T cargo
              </Text>
              <Text size="xs" c="dimmed">
                of {stats.totalCapacity}T capacity
              </Text>
            </Group>
            {stats.totalTare > 0 ? (
              <Group
                gap={6}
                style={{
                  padding: "4px 12px",
                  borderRadius: 999,
                  background: "var(--mantine-color-gray-0)",
                  border: "1px solid var(--mantine-color-gray-2)",
                }}
              >
                <Text size="xs" fw={700} c="dark.4">
                  {stats.grossWeight}T gross
                </Text>
                <Text size="xs" c="dimmed">
                  incl. {stats.totalTare}T tare
                </Text>
              </Group>
            ) : null}
            <Group gap="xs">
              <LegendDot color="cyan" label="Container" />
              <LegendDot color="orange" label="Bulk" />
              <LegendDot color="gray" label="Empty" />
            </Group>
          </Group>
        </Group>

        {/* Locomotive pull gauge */}
        {stats.pullUtil != null ? (
          <Box
            p="sm"
            style={{
              borderRadius: 12,
              background: "linear-gradient(135deg, var(--mantine-color-edr-green-0), #F2FBF7)",
              border: "1px solid var(--mantine-color-edr-green-1)",
            }}
          >
            <Group justify="space-between" mb={6}>
              <Group gap={6} wrap="nowrap">
                <Gauge size={14} color={freightBrand.primary} />
                <Text size="xs" fw={700} c="edr-green.8">
                  Locomotive load ·{" "}
                  {stats.totalTare > 0
                    ? `${stats.grossWeight}T of ${stats.pullLimit}T (${stats.totalWeight}T cargo + ${stats.totalTare}T tare)`
                    : `${stats.totalWeight}T of ${stats.pullLimit}T`}
                </Text>
              </Group>
              <Text size="sm" fw={800} c={stats.pullUtil > 95 ? "red.7" : "edr-green.7"}>
                {stats.pullUtil}%
              </Text>
            </Group>
            <Progress
              value={stats.pullUtil}
              size="md"
              radius="xl"
              striped={stats.pullUtil > 95}
              animated={stats.pullUtil > 95}
              color={stats.pullUtil > 95 ? "red" : stats.pullUtil > 80 ? "yellow" : "edr-green"}
            />
          </Box>
        ) : null}

        {/* The train */}
        <Box ref={ref} style={{ width: "100%" }}>
          <Stack gap={0}>
            {rows.map((row, rowIndex) => {
              const reversed = rowIndex % 2 === 1;
              const isLast = rowIndex === rows.length - 1;
              // side where this row's track ends / turns down to the next row
              const turnSide: "left" | "right" = rowIndex % 2 === 0 ? "right" : "left";
              return (
                <Box key={rowIndex}>
                  <Box style={{ position: "relative", paddingBottom: 10 }}>
                    <TrackBed />
                    <Group
                      gap={0}
                      wrap="nowrap"
                      justify="flex-start"
                      style={{
                        flexDirection: reversed ? "row-reverse" : "row",
                        position: "relative",
                      }}
                    >
                      {row.map((car, carIndex) => (
                        <Group key={carIndex} gap={0} wrap="nowrap" style={{ flexDirection: reversed ? "row-reverse" : "row" }}>
                          {carIndex > 0 ? <Coupler /> : null}
                          {car.kind === "loco" ? (
                            <LocomotiveCar
                              code={car.l.code ?? "LOCO"}
                              name={car.l.name}
                              maxPullWeightTons={car.l.maxPullWeightTons}
                            />
                          ) : (
                            <WagonCar wagon={car.w} />
                          )}
                        </Group>
                      ))}
                    </Group>
                  </Box>

                  {/* serpentine turn connector to the next row */}
                  {!isLast ? (
                    <Box style={{ position: "relative", height: 16 }}>
                      <Box
                        style={{
                          position: "absolute",
                          top: -10,
                          height: 26,
                          width: 22,
                          borderBottom: "4px solid var(--mantine-color-gray-4)",
                          ...(turnSide === "right"
                            ? {
                                right: 4,
                                borderRight: "4px solid var(--mantine-color-gray-4)",
                                borderBottomRightRadius: 16,
                              }
                            : {
                                left: 4,
                                borderLeft: "4px solid var(--mantine-color-gray-4)",
                                borderBottomLeftRadius: 16,
                              }),
                        }}
                      />
                    </Box>
                  ) : null}
                </Box>
              );
            })}
          </Stack>
        </Box>
      </Stack>
    </Paper>
  );
});

function LegendDot({ color, label }: { color: string; label: string }) {
  return (
    <Group gap={5} wrap="nowrap">
      <Box
        style={{
          width: 10,
          height: 10,
          borderRadius: 3,
          background:
            color === "gray"
              ? "var(--mantine-color-gray-2)"
              : `var(--mantine-color-${color}-5)`,
          border: color === "gray" ? "1.5px dashed var(--mantine-color-gray-4)" : "none",
        }}
      />
      <Text size="xs" c="dimmed">
        {label}
      </Text>
    </Group>
  );
}
