import { useState, useMemo } from "react";
import { useMutation, useQuery } from "@tanstack/react-query";
import {
  Box,
  Button,
  Group,
  Loader,
  Select,
  Stack,
  Table,
  Text,
  Alert,
} from "@mantine/core";
import { AlertCircle } from "lucide-react";
import toast from "react-hot-toast";

import { vehiclesService } from "@/services/vehicles.service";

export interface ContainerAllocationRow {
  id: string;
  type: string;
  qty: number;
}

export interface ContainerAllocationTableProps {
  bookingId: string;
  containers: ContainerAllocationRow[];
  onSave: (allocations: Array<{ containerId: string; vehicleId: string }>) => Promise<void>;
}

/**
 * Manual container-to-vehicle allocation table for freight bookings.
 * Displays containers with type/qty, vehicle dropdown per row, and save action.
 */
export function ContainerAllocationTable({
  containers,
  onSave,
}: ContainerAllocationTableProps) {
  const [allocations, setAllocations] = useState<Record<string, string | null>>(
    () => containers.reduce((acc, c) => ({ ...acc, [c.id]: null }), {}),
  );

  const { data: vehicles = [], isLoading: vehiclesLoading } = useQuery({
    queryKey: ["vehicles", "free"],
    queryFn: async () => {
      const res = await vehiclesService.getAll({ status: "ACTIVE", availability: "FREE" });
      return res.data ?? [];
    },
  });

  const vehicleOptions = useMemo(
    () =>
      vehicles.map((v) => ({
        value: v.id,
        label: `${v.plateNumber} (${v.vehicleType})`,
        description: `${v.model} · ${v.manufacturer}`,
      })),
    [vehicles],
  );

  const saveAllocation = useMutation({
    mutationFn: async () => {
      const mappings = containers
        .filter((c) => allocations[c.id])
        .map((c) => ({
          containerId: c.id,
          vehicleId: allocations[c.id]!,
        }));

      if (mappings.length === 0) {
        throw new Error("No containers allocated to vehicles");
      }

      await onSave(mappings);
    },
    onSuccess: () => {
      toast.success("Container allocations saved");
      setAllocations(
        containers.reduce((acc, c) => ({ ...acc, [c.id]: null }), {}),
      );
    },
    onError: (error) => {
      toast.error(
        error instanceof Error ? error.message : "Failed to save allocations",
      );
    },
  });

  const allocatedCount = Object.values(allocations).filter(Boolean).length;

  if (vehiclesLoading) {
    return (
      <Group justify="center" p="xl">
        <Loader size="sm" />
      </Group>
    );
  }

  return (
    <Stack gap="md">
      {vehicles.length === 0 && (
        <Alert icon={<AlertCircle size={16} />} color="yellow">
          No free vehicles available. Free up or add vehicles before allocating containers.
        </Alert>
      )}

      <Box style={{ overflowX: "auto" }}>
        <Table verticalSpacing="md" horizontalSpacing="md" highlightOnHover>
          <Table.Thead>
            <Table.Tr>
              <Table.Th>Container ID</Table.Th>
              <Table.Th>Type</Table.Th>
              <Table.Th>Qty</Table.Th>
              <Table.Th>Assigned Vehicle</Table.Th>
            </Table.Tr>
          </Table.Thead>
          <Table.Tbody>
            {containers.map((container) => (
              <Table.Tr key={container.id}>
                <Table.Td>
                  <Text fw={600} size="sm">
                    {container.id}
                  </Text>
                </Table.Td>
                <Table.Td>{container.type}</Table.Td>
                <Table.Td>{container.qty}</Table.Td>
                <Table.Td>
                  <Select
                    placeholder="Select vehicle"
                    data={vehicleOptions}
                    value={allocations[container.id] ?? null}
                    onChange={(value) =>
                      setAllocations((prev) => ({
                        ...prev,
                        [container.id]: value,
                      }))
                    }
                    searchable
                    clearable
                    disabled={vehicles.length === 0}
                    style={{ minWidth: 200 }}
                  />
                </Table.Td>
              </Table.Tr>
            ))}
          </Table.Tbody>
        </Table>
      </Box>

      <Group justify="space-between">
        <Text size="sm" c="dimmed">
          {allocatedCount} of {containers.length} containers allocated
        </Text>
        <Button
          color="edr-green"
          loading={saveAllocation.isPending}
          disabled={allocatedCount === 0 || vehicles.length === 0}
          onClick={() => saveAllocation.mutate()}
        >
          Save Allocations
        </Button>
      </Group>
    </Stack>
  );
}
