import { useMemo, useState } from "react";
import { ArrowRight, Building2, Package } from "lucide-react";
import {
  Accordion,
  Badge,
  Button,
  Checkbox,
  Group,
  Paper,
  Stack,
  Text,
  Title,
} from "@mantine/core";

import { BookingPriorityBadge } from "@/components/bookings/BookingPriorityBadge";
import { canAllocateBooking } from "@/features/bookings/booking-actions.config";
import type { BookingListRow } from "@/types/booking";
import { groupBookingsForOperationsQueue } from "@/utils/groupBookingsForOperationsQueue";

function BookingQueueRow({
  booking,
  selected,
  disabled,
  onToggle,
}: {
  booking: BookingListRow;
  selected: boolean;
  disabled: boolean;
  onToggle: () => void;
}) {
  return (
    <Group
      align="flex-start"
      wrap="nowrap"
      p="sm"
      style={{
        border: "1px solid var(--mantine-color-gray-3)",
        borderRadius: 8,
      }}
    >
      <Checkbox checked={selected} disabled={disabled} onChange={onToggle} mt={4} />
      <Stack gap={4} style={{ flex: 1 }}>
        <Group gap="xs">
          <Package size={14} />
          <Text fw={600} size="sm">{booking.reference}</Text>
          {booking.isGovernment ? (
            <Badge color="violet" size="xs" leftSection={<Building2 size={10} />}>
              Government
            </Badge>
          ) : null}
          <Badge variant="outline" size="xs">{booking.freightType}</Badge>
          {booking.schedulingStatus ? (
            <Badge variant="light" size="xs">{booking.schedulingStatus}</Badge>
          ) : null}
        </Group>
        <Text size="xs" c="dimmed">{booking.customerLabel}</Text>
        <Group gap={6}>
          <Text size="xs">{booking.originLabel}</Text>
          <ArrowRight size={12} />
          <Text size="xs">{booking.destinationLabel}</Text>
        </Group>
        <Group gap="sm">
          <BookingPriorityBadge score={booking.priorityScore} />
          {booking.serviceTypeLabel ? (
            <Text size="xs" c="dimmed">
              {booking.serviceTypeLabel}
              {booking.serviceTypeBonus ? ` (+${booking.serviceTypeBonus} bonus)` : ""}
            </Text>
          ) : null}
        </Group>
      </Stack>
    </Group>
  );
}

export function OperationsBookingQueue({
  bookings,
  isLoading,
  onAllocate,
}: {
  bookings: BookingListRow[];
  isLoading?: boolean;
  onAllocate: (bookingIds: string[]) => void;
}) {
  const { government, commercial } = useMemo(
    () => groupBookingsForOperationsQueue(bookings),
    [bookings],
  );
  const [govSelected, setGovSelected] = useState<string[]>([]);
  const [selectedByBucket, setSelectedByBucket] = useState<Record<string, string[]>>({});

  const allocatable = (row: BookingListRow) =>
    row.status === "PAID" &&
    canAllocateBooking({ status: row.status, schedulingStatus: row.schedulingStatus });

  const govSelection = govSelected.length
    ? govSelected
    : government.filter(allocatable).map((b) => b.id);

  const bucketSelection = (bucketKey: string, bucketBookings: BookingListRow[]) => {
    const existing = selectedByBucket[bucketKey];
    if (existing) return existing;
    return bucketBookings.filter(allocatable).map((b) => b.id);
  };

  const toggleGov = (bookingId: string) => {
    setGovSelected((prev) => {
      const base = prev.length ? prev : government.filter(allocatable).map((b) => b.id);
      return base.includes(bookingId)
        ? base.filter((id) => id !== bookingId)
        : [...base, bookingId];
    });
  };

  const toggleBucket = (bucketKey: string, bookingId: string) => {
    setSelectedByBucket((prev) => {
      const current = prev[bucketKey] ?? [];
      const next = current.includes(bookingId)
        ? current.filter((id) => id !== bookingId)
        : [...current, bookingId];
      return { ...prev, [bucketKey]: next };
    });
  };

  if (isLoading) {
    return <Text size="sm" c="dimmed">Loading operations queue…</Text>;
  }

  if (!government.length && !commercial.length) {
    return (
      <Text size="sm" c="dimmed">
        No PAID bookings ready to allocate.
      </Text>
    );
  }

  return (
    <Stack gap="lg">
      {government.length > 0 ? (
        <Paper withBorder p="md" radius="md">
          <Group justify="space-between" mb="md">
            <Stack gap={2}>
              <Title order={5}>Government priority</Title>
              <Text size="xs" c="dimmed">
                Served first — not grouped by 3-hour window
              </Text>
            </Stack>
            <Group gap="xs">
              <Badge variant="light">{govSelection.length} selected</Badge>
              <Button
                size="compact-sm"
                color="violet"
                disabled={!govSelection.length}
                onClick={() => onAllocate(govSelection)}
              >
                Allocate
              </Button>
            </Group>
          </Group>
          <Stack gap="sm">
            {government.map((booking) => (
              <BookingQueueRow
                key={booking.id}
                booking={booking}
                selected={govSelection.includes(booking.id)}
                disabled={!allocatable(booking)}
                onToggle={() => toggleGov(booking.id)}
              />
            ))}
          </Stack>
        </Paper>
      ) : null}

      {commercial.length > 0 ? (
        <Accordion defaultValue={commercial[0]?.key} variant="separated" radius="md">
          {commercial.map((bucket) => {
            const selected = bucketSelection(bucket.key, bucket.bookings);
            return (
              <Accordion.Item key={bucket.key} value={bucket.key}>
                <Accordion.Control>
                  <Group justify="space-between" wrap="nowrap" pr="md">
                    <Stack gap={2}>
                      <Text fw={600} size="sm">{bucket.label}</Text>
                      <Text size="xs" c="dimmed">
                        {bucket.bookings.length} commercial booking
                        {bucket.bookings.length === 1 ? "" : "s"}
                      </Text>
                    </Stack>
                    <Group gap="xs">
                      <Badge variant="light">{selected.length} selected</Badge>
                      <Button
                        size="compact-sm"
                        color="edr-green"
                        disabled={!selected.length}
                        onClick={(e) => {
                          e.stopPropagation();
                          onAllocate(selected);
                        }}
                      >
                        Allocate
                      </Button>
                    </Group>
                  </Group>
                </Accordion.Control>
                <Accordion.Panel>
                  <Stack gap="sm">
                    {bucket.bookings.map((booking) => (
                      <BookingQueueRow
                        key={booking.id}
                        booking={booking}
                        selected={selected.includes(booking.id)}
                        disabled={!allocatable(booking)}
                        onToggle={() => toggleBucket(bucket.key, booking.id)}
                      />
                    ))}
                  </Stack>
                </Accordion.Panel>
              </Accordion.Item>
            );
          })}
        </Accordion>
      ) : null}
    </Stack>
  );
}
