import { Badge, Card, Group, Progress, SimpleGrid, Stack, Text, ThemeIcon } from "@mantine/core";
import { Box, Package } from "lucide-react";
import { EntityLink } from "@/components/detail";
import type { TrainScheduleWagonAllocation, WagonPlanRow } from "@/types/trainScheduling";

type WagonSlot = (WagonPlanRow & {
  physicalWagonNumber?: string | null;
  tareWeightTons?: number | null;
}) | {
  sequenceNo: number;
  capacityTons: number;
  assignedWeightTons: number;
  tareWeightTons?: number | null;
  slotLoadType?: string;
  wagonType?: { code: string } | null;
  wagonTypeCode?: string;
  physicalWagonNumber?: string | null;
  allocations?: TrainScheduleWagonAllocation[] | Array<{
    id?: string;
    bookingId: string;
    bookingReference?: string | null;
    allocatedWeightTons: number;
    loadType?: string | null;
    containerItems?: Array<{ containerNumber: string | null; grossWeightTons?: number | null }>;
    bulkLoad?: { weightTons: number; cargoDescription: string | null } | null;
  }>;
};

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

function loadTypeColor(loadType: string | undefined, freightType?: string | null) {
  const normalized = loadType?.toUpperCase() ?? "";
  if (normalized.includes("BULK")) return "orange";
  if (normalized.includes("CONTAINER")) return "cyan";
  return freightType === "BULK" ? "orange" : "cyan";
}

function slotLabel(slot: WagonSlot, freightType?: string | null) {
  if ("slotLoadType" in slot && slot.slotLoadType) return slot.slotLoadType;
  const fromAlloc = slot.allocations?.[0]?.loadType?.toString().toUpperCase();
  if (fromAlloc) return fromAlloc;
  if (freightType === "MIXED") return "MIXED";
  return freightType ?? "SLOT";
}

function wagonTypeLabel(slot: WagonSlot) {
  if ("wagonType" in slot && slot.wagonType?.code) return slot.wagonType.code;
  if ("wagonTypeCode" in slot && slot.wagonTypeCode) return slot.wagonTypeCode;
  return null;
}

export function WagonPlanGrid({
  wagonPlan,
  freightType,
}: {
  wagonPlan: WagonSlot[];
  freightType?: string | null;
}) {
  if (!wagonPlan?.length) {
    return (
      <Card radius="lg" padding="xl" withBorder bg="gray.0">
        <Stack align="center" gap="sm">
          <ThemeIcon size="lg" radius="xl" variant="light" color="gray">
            <Package size={20} />
          </ThemeIcon>
          <Text size="sm" fw={500}>
            No wagon plan yet
          </Text>
          <Text size="xs" c="dimmed" ta="center" maw={360}>
            Select bookings and run <strong>Preview plan</strong> to generate wagon slots and
            allocations.
          </Text>
        </Stack>
      </Card>
    );
  }

  // GROSS on both sides: cargo + tare vs rated payload + tare.
  const totalTare = round1(
    wagonPlan.reduce((sum, w) => sum + (Number(w.tareWeightTons) || 0), 0),
  );
  const totalCapacity = round1(
    wagonPlan.reduce((sum, w) => sum + w.capacityTons, 0) + totalTare,
  );
  const totalAssigned = round1(
    wagonPlan.reduce((sum, w) => sum + w.assignedWeightTons, 0) + totalTare,
  );
  const usedSlots = wagonPlan.filter((w) => (w.allocations?.length ?? 0) > 0).length;

  const isBulk = freightType === "BULK" || wagonPlan.every((w) => w.slotLoadType === "BULK" || (!w.slotLoadType && w.allocations?.[0]?.loadType === "Bulk"));

  return (
    <Stack gap="md">
      <Group gap="lg">
        <Text size="sm" c="dimmed">
          <strong>{wagonPlan.length}</strong> wagons · <strong>{usedSlots}</strong> in use
        </Text>
        {isBulk ? (
          <Text size="sm" c="dimmed">
            Gross: <strong>{totalAssigned}</strong> / {totalCapacity}T
          </Text>
        ) : null}
      </Group>

      <SimpleGrid cols={{ base: 1, sm: 2, xl: 3 }} spacing="md">
        {wagonPlan.map((wagon) => {
          const seq = wagon.sequenceNo;
          const tare = Number(wagon.tareWeightTons) || 0;
          const capacity = round1(wagon.capacityTons + tare);
          const assigned = round1(wagon.assignedWeightTons + tare);
          const allocations = wagon.allocations ?? [];
          const utilization = capacity > 0 ? Math.min(100, Math.round((assigned / capacity) * 100)) : 0;
          const label = slotLabel(wagon, freightType);
          const typeCode = wagonTypeLabel(wagon);

          return (
            <Card key={seq} radius="lg" padding="md" withBorder>
              <Stack gap="sm">
                <Group justify="space-between" align="flex-start" wrap="nowrap">
                  <Group gap="xs" wrap="nowrap">
                    <ThemeIcon size="md" radius="md" variant="light" color={loadTypeColor(label, freightType)}>
                      <Box size={16} />
                    </ThemeIcon>
                    <Stack gap={0}>
                      <Text fw={600} size="sm">
                        {wagon.physicalWagonNumber ?? `Wagon #${seq}`}
                      </Text>
                      <Text size="xs" c="dimmed">
                        {[typeCode, `Pos ${seq}`].filter(Boolean).join(" · ")}
                      </Text>
                    </Stack>
                  </Group>
                  <Badge variant="light" size="sm" color={loadTypeColor(label, freightType)}>
                    {label}
                  </Badge>
                </Group>

                {label === "BULK" ? (
                  <Stack gap={4}>
                    <Group justify="space-between">
                      <Text size="xs" c="dimmed">
                        Capacity
                      </Text>
                      <Text size="xs" fw={500}>
                        {assigned} / {capacity}T
                      </Text>
                    </Group>
                    <Progress
                      value={utilization}
                      size="sm"
                      radius="xl"
                      color={utilization > 95 ? "red" : utilization > 80 ? "yellow" : "edr-green"}
                    />
                  </Stack>
                ) : null}

                <Stack gap={6}>
                  {allocations.length ? (
                    allocations.map((alloc, index) => (
                      <Card key={`${alloc.bookingId}-${index}`} padding="xs" radius="md" bg="gray.0">
                        <Stack gap={2}>
                          <Group justify="space-between" gap="xs">
                            <EntityLink
                              to={`/dashboard/booking-requests/${alloc.bookingId}`}
                              label={alloc.bookingReference ?? alloc.bookingId}
                              size="xs"
                              fw={500}
                            />
                            {label === "BULK" ? (
                              <Text size="xs" c="dimmed">
                                {alloc.allocatedWeightTons}T cargo
                              </Text>
                            ) : null}
                          </Group>
                          {"containerItems" in alloc && alloc.containerItems?.length ? (
                            <Text size="xs" c="dimmed">
                              {alloc.containerItems.length} container{alloc.containerItems.length > 1 ? "s" : ""}
                            </Text>
                          ) : null}
                          {"bulkLoad" in alloc && alloc.bulkLoad ? (
                            <Text size="xs" c="dimmed" lineClamp={2}>
                              Bulk · {alloc.bulkLoad.weightTons}T
                              {alloc.bulkLoad.cargoDescription
                                ? ` — ${alloc.bulkLoad.cargoDescription}`
                                : ""}
                            </Text>
                          ) : null}
                        </Stack>
                      </Card>
                    ))
                  ) : (
                    <Text size="xs" c="dimmed" fs="italic">
                      Empty slot
                    </Text>
                  )}
                </Stack>
              </Stack>
            </Card>
          );
        })}
      </SimpleGrid>
    </Stack>
  );
}
