import { useMemo, useState } from "react";
import { PackageCheck } from "lucide-react";
import { Badge, Button, Checkbox, Group, Loader, Paper, Stack, Text } from "@mantine/core";
import { useMutation, useQueryClient } from "@tanstack/react-query";
import toast from "react-hot-toast";

import { api } from "@/services/api";
import type {
  ImportLoadingBooking,
  ImportLoadingBookingsResponse,
  LoadingStatus,
} from "@/types/trainScheduling";

function ImportLoadingBookingRow({
  booking,
  selected,
  onToggle,
}: {
  booking: ImportLoadingBooking;
  selected: boolean;
  onToggle: () => void;
}) {
  return (
    <Group
      align="flex-start"
      wrap="nowrap"
      p="sm"
      style={{
        border: `1px solid ${
          selected ? "var(--mantine-color-edr-green-3)" : "var(--mantine-color-gray-2)"
        }`,
        borderRadius: 12,
        background: selected ? "var(--mantine-color-edr-green-0)" : "white",
        transition: "border-color 120ms ease, background 120ms ease",
      }}
    >
      <Checkbox checked={selected} onChange={onToggle} mt={4} color="edr-green" />
      <Stack gap={4} style={{ flex: 1 }}>
        <Group gap="xs" wrap="wrap">
          <PackageCheck size={14} />
          <Text fw={600} size="sm">
            {booking.reference ?? booking.id}
          </Text>
          <Badge
            variant="light"
            size="xs"
            color={booking.loadingStatus === "LOADED" ? "edr-green" : "gray"}
          >
            {booking.loadingStatus}
          </Badge>
        </Group>
        <Text size="xs" c="dimmed">
          {booking.customer ?? "Unknown customer"}
        </Text>
        <Text size="xs" c="dimmed">
          {booking.weightTons}T
        </Text>
      </Stack>
    </Group>
  );
}

export function ImportLoadingConfirmationPanel({
  scheduleId,
  items,
  isLoading,
}: {
  scheduleId: string;
  items: ImportLoadingBooking[];
  isLoading?: boolean;
}) {
  const [selectedIds, setSelectedIds] = useState<string[]>([]);
  const queryClient = useQueryClient();

  const updateStatus = useMutation<
    ImportLoadingBookingsResponse,
    Error,
    { id: string; bookingIds: string[]; loadingStatus: LoadingStatus }
  >({
    ...api.trainScheduling.updateImportLoadingStatus.mutationOptions(),
    onSuccess: () => {
      setSelectedIds([]);
      queryClient.invalidateQueries({
        queryKey: api.trainScheduling.importLoadingBookings.queryKey({ id: scheduleId }),
      });
    },
    onError: (error) => {
      toast.error(error instanceof Error ? error.message : "Could not update loading status");
    },
  });

  const toggle = (id: string) => {
    setSelectedIds((prev) =>
      prev.includes(id) ? prev.filter((x) => x !== id) : [...prev, id],
    );
  };

  const allIds = useMemo(() => items.map((b) => b.id), [items]);

  if (isLoading) {
    return (
      <Group justify="center" py="md">
        <Loader size="sm" />
        <Text size="sm" c="dimmed">
          Loading import bookings…
        </Text>
      </Group>
    );
  }

  if (!items.length) {
    return (
      <Paper p="lg" radius="lg" withBorder bg="gray.0">
        <Text size="sm" c="dimmed" ta="center">
          No paid import bookings with wagons allocated on this schedule
        </Text>
      </Paper>
    );
  }

  return (
    <Stack gap="md">
      <Group justify="space-between" wrap="wrap">
        <Text size="sm" fw={500}>
          Import bookings ({items.length})
        </Text>
        <Group gap="sm">
          <Button variant="light" size="compact-sm" onClick={() => setSelectedIds(allIds)}>
            Select all
          </Button>
          <Button variant="subtle" size="compact-sm" onClick={() => setSelectedIds([])}>
            Clear
          </Button>
        </Group>
      </Group>

      <Stack gap="sm">
        {items.map((booking) => (
          <ImportLoadingBookingRow
            key={booking.id}
            booking={booking}
            selected={selectedIds.includes(booking.id)}
            onToggle={() => toggle(booking.id)}
          />
        ))}
      </Stack>

      <Group gap="sm">
        <Button
          color="edr-green"
          disabled={!selectedIds.length}
          loading={updateStatus.isPending}
          onClick={() =>
            updateStatus.mutate({ id: scheduleId, bookingIds: selectedIds, loadingStatus: "LOADED" })
          }
        >
          Mark loaded
        </Button>
        <Button
          variant="outline"
          disabled={!selectedIds.length}
          loading={updateStatus.isPending}
          onClick={() =>
            updateStatus.mutate({ id: scheduleId, bookingIds: selectedIds, loadingStatus: "UNLOADED" })
          }
        >
          Mark unloaded
        </Button>
      </Group>
    </Stack>
  );
}
