import { Badge, Box, Button, Card, Group, Stack, Text, ThemeIcon, Tooltip } from "@mantine/core";
import { AlertTriangle, Container as ContainerIcon, MapPin, Plus, TrainFront } from "lucide-react";
import { useMutation, useQuery } from "@tanstack/react-query";
import { api } from "@/services/api";
import { useToast } from "@/hooks/use-toast";
import type { FleetAvailabilityRow } from "@/types/trainScheduling";
import type { BookingDetailData } from "./BookingDetailModal";

interface UnassignedBookingsPanelProps {
  scheduleId: string;
  selectedBookingId?: string | null;
  onSelect: (booking: BookingDetailData) => void;
}

const parseError = (error: unknown): string | null => {
  if (error && typeof error === "object" && "response" in error) {
    const resp = (error as {
      response?: { data?: { message?: unknown; violations?: string[] } };
    }).response;
    const violations = resp?.data?.violations;
    if (Array.isArray(violations) && violations.length) return violations.join("; ");
    const msg = resp?.data?.message;
    if (Array.isArray(msg)) return msg.join(", ");
    if (typeof msg === "string") return msg;
  }
  return null;
};

const YardFleetBanner = ({ fleetAtOrigin }: { fleetAtOrigin: FleetAvailabilityRow[] }) => {
  if (!fleetAtOrigin.length) {
    return (
      <Group gap={5} wrap="nowrap" px="sm" py={6} style={{ borderRadius: 8, background: "var(--mantine-color-red-0)", border: "1px solid var(--mantine-color-red-2)" }}>
        <MapPin size={13} color="var(--mantine-color-red-6)" />
        <Text size="xs" fw={700} c="red.7">
          No wagons at origin yard
        </Text>
      </Group>
    );
  }

  return (
    <Group
      gap="xs"
      wrap="wrap"
      px="sm"
      py={6}
      style={{
        borderRadius: 8,
        background: "var(--mantine-color-edr-green-0)",
        border: "1px solid var(--mantine-color-edr-green-1)",
      }}
    >
      <Group gap={5} wrap="nowrap">
        <MapPin size={13} color="var(--mantine-color-edr-green-7)" />
        <Text size="xs" fw={700} c="edr-green.8">
          Origin yard
        </Text>
      </Group>
      {fleetAtOrigin.map((row) => (
        <Badge key={row.wagonTypeId} size="sm" variant="light" color="edr-green">
          {row.wagonTypeCode}: {row.available}
        </Badge>
      ))}
    </Group>
  );
};

export const UnassignedBookingsPanel = ({
  scheduleId,
  selectedBookingId,
  onSelect,
}: UnassignedBookingsPanelProps) => {
  const { toast } = useToast();
  const unassignedQuery = useQuery(
    api.trainScheduling.unassignedBookings.queryOptions({
      input: { scheduleId },
      enabled: Boolean(scheduleId),
    }),
  );
  const assignMutation = useMutation(
    api.trainScheduling.assignUnassignedBooking.mutationOptions(),
  );

  const handleAssign = async (bookingId: string, reference: string | null) => {
    try {
      await assignMutation.mutateAsync({
        id: scheduleId,
        bookingId,
      });
      toast({ title: `Assigned ${reference ?? "booking"} to the train` });
    } catch (err) {
      toast({
        title: "Could not assign booking",
        description: parseError(err) ?? "Assignment failed — check yard fleet and train limits.",
        variant: "destructive",
      });
    }
  };

  if (unassignedQuery.isLoading) {
    return (
      <Text size="sm" c="dimmed">
        Loading...
      </Text>
    );
  }

  const bookings = unassignedQuery.data?.bookings ?? [];
  const fleetAtOrigin = unassignedQuery.data?.fleetAtOrigin ?? [];

  if (bookings.length === 0) {
    return (
      <Stack align="center" gap="xs" py="xl">
        <ThemeIcon size={44} radius="xl" variant="light" color="gray">
          <ContainerIcon size={20} />
        </ThemeIcon>
        <Text size="sm" fw={600} c="gray.7">
          No unassigned bookings
        </Text>
        <Text size="xs" c="dimmed" ta="center" maw={220}>
          Paid bookings waiting for a wagon will appear here.
        </Text>
      </Stack>
    );
  }

  return (
    <Stack gap="xs">
      <YardFleetBanner fleetAtOrigin={fleetAtOrigin} />

      {bookings.map((booking) => {
        const isActive = selectedBookingId === booking.id;
        const weight = Number(booking.cargoTotalWeightVgm ?? 0);
        const fits = booking.canAssign;
        const blockReason = booking.blockReason;

        return (
          <Card
            key={booking.id}
            padding="xs"
            radius="md"
            withBorder
            onClick={() =>
              onSelect({
                bookingId: booking.id,
                reference: booking.reference,
                company: null,
                freightType: booking.freightType,
                weightTons: Number.isFinite(weight) ? weight : null,
                status: booking.status,
                priorityScore: booking.priorityScore,
              })
            }
            style={{
              cursor: "pointer",
              borderColor: isActive ? "var(--mantine-color-edr-green-5)" : undefined,
            }}
          >
            <Stack gap={6}>
              <Group gap={8} wrap="nowrap" align="flex-start">
                <ThemeIcon size={30} radius="md" variant="light" color="orange">
                  <ContainerIcon size={16} />
                </ThemeIcon>
                <Box style={{ flex: 1, minWidth: 0 }}>
                  <Group justify="space-between" wrap="nowrap" gap={4}>
                    <Text size="sm" fw={700} truncate>
                      {booking.reference}
                    </Text>
                    {booking.priorityScore ? (
                      <Badge size="xs" color="edr-green">
                        P{booking.priorityScore}
                      </Badge>
                    ) : null}
                  </Group>
                  <Group gap={6} wrap="nowrap" mt={2}>
                    <Badge size="xs" variant="light" color="gray">
                      {booking.freightType}
                    </Badge>
                    <Group gap={3} wrap="nowrap">
                      <TrainFront size={11} color="var(--mantine-color-gray-6)" />
                      <Text size="11px" c="dimmed">
                        {booking.wagonsRequired}× {booking.requiredWagonTypeCode}
                      </Text>
                    </Group>
                  </Group>
                </Box>
              </Group>

              {blockReason ? (
                <Group gap={5} wrap="nowrap">
                  <AlertTriangle size={12} color="var(--mantine-color-red-6)" />
                  <Text size="10px" c="red.7" fw={600}>
                    {blockReason}
                  </Text>
                </Group>
              ) : null}

              <Tooltip label={blockReason} disabled={fits} withArrow position="bottom">
                <Button
                  size="xs"
                  variant="light"
                  color="edr-green"
                  disabled={!fits}
                  onClick={(e) => {
                    e.stopPropagation();
                    void handleAssign(booking.id, booking.reference);
                  }}
                  loading={
                    assignMutation.isPending &&
                    assignMutation.variables?.bookingId === booking.id
                  }
                  leftSection={<Plus size={12} />}
                >
                  Assign to train
                </Button>
              </Tooltip>
            </Stack>
          </Card>
        );
      })}
    </Stack>
  );
};
