import { Freight } from "@edr/types";
import {
  Button,
  Checkbox,
  Group,
  ScrollArea,
  Select,
  Stack,
  Text,
  TextInput,
} from "@mantine/core";
import { useQuery } from "@tanstack/react-query";
import { Plus, Search } from "lucide-react";
import { useMemo, useState } from "react";

import { api } from "@/services/api";

/**
 * AVAILABLE wagons standing in the train's own yard — the only ones that can
 * be coupled. Pick any number and append them to the consist.
 */
export default function AvailableWagonsPanel({
  yardId,
  yardLabel,
  onAssign,
  assigning,
}: AvailableWagonsPanelProps) {
  const [search, setSearch] = useState("");
  const [typeFilter, setTypeFilter] = useState<string>("ALL");
  const [selected, setSelected] = useState<string[]>([]);

  const wagonsQuery = useQuery(
    api.wagons.list.queryOptions({
      input: {
        filters: { status: Freight.WagonStatus.Available, currentYardId: yardId },
      },
      enabled: Boolean(yardId),
    }),
  );

  const wagons = useMemo(() => {
    const q = search.trim().toLowerCase();
    return (wagonsQuery.data ?? []).filter((wagon) => {
      if (typeFilter !== "ALL" && wagon.wagonTypeId !== typeFilter) return false;
      if (q && !wagon.wagonNumber.toLowerCase().includes(q)) return false;
      return true;
    });
  }, [wagonsQuery.data, search, typeFilter]);

  const typeOptions = useMemo(() => {
    const byId = new Map<string, string>();
    for (const wagon of wagonsQuery.data ?? []) {
      if (wagon.wagonType) byId.set(wagon.wagonType.id, wagon.wagonType.name);
    }
    return [
      { value: "ALL", label: "All types" },
      ...[...byId.entries()].map(([value, label]) => ({ value, label })),
    ];
  }, [wagonsQuery.data]);

  const toggle = (wagonId: string, checked: boolean) => {
    setSelected((prev) =>
      checked ? [...prev, wagonId] : prev.filter((id) => id !== wagonId),
    );
  };

  const handleAssign = () => {
    if (!selected.length) return;
    onAssign(selected);
    setSelected([]);
  };

  return (
    <Stack gap="sm">
      <Group gap="xs" grow>
        <TextInput
          size="sm"
          placeholder="Search wagon number…"
          leftSection={<Search size={14} />}
          value={search}
          onChange={(e) => setSearch(e.currentTarget.value)}
        />
        <Select
          size="sm"
          data={typeOptions}
          value={typeFilter}
          onChange={(v) => setTypeFilter(v ?? "ALL")}
        />
      </Group>

      <ScrollArea.Autosize mah={380} type="auto">
        <Stack gap={6}>
          {wagonsQuery.isLoading ? (
            <Text py="md" ta="center" c="dimmed" size="sm">
              Loading wagons…
            </Text>
          ) : !wagons.length ? (
            <Text py="md" ta="center" c="dimmed" size="sm">
              No available wagons in {yardLabel ?? "this yard"}
            </Text>
          ) : (
            wagons.map((wagon) => (
              <Group
                key={wagon.id}
                gap="sm"
                wrap="nowrap"
                p="xs"
                style={{
                  border: "1px solid var(--mantine-color-gray-2)",
                  borderRadius: "var(--mantine-radius-md)",
                }}
              >
                <Checkbox
                  size="sm"
                  checked={selected.includes(wagon.id)}
                  onChange={(e) => toggle(wagon.id, e.currentTarget.checked)}
                  aria-label={`Select wagon ${wagon.wagonNumber}`}
                />
                <Stack gap={0} style={{ flex: 1, minWidth: 0 }}>
                  <Text size="sm" fw={600} ff="monospace" truncate>
                    {wagon.wagonNumber}
                  </Text>
                  <Text size="xs" c="dimmed" truncate>
                    {wagon.wagonType
                      ? `${wagon.wagonType.name} · ${wagon.wagonType.capacityTons ?? "—"}T cap`
                      : "Unknown type"}
                  </Text>
                </Stack>
              </Group>
            ))
          )}
        </Stack>
      </ScrollArea.Autosize>

      <Button
        leftSection={<Plus size={16} />}
        disabled={!selected.length}
        loading={assigning}
        onClick={handleAssign}
      >
        Add {selected.length ? `${selected.length} wagon${selected.length > 1 ? "s" : ""}` : "wagons"} to consist
      </Button>
    </Stack>
  );
}

export interface AvailableWagonsPanelProps {
  yardId: string;
  yardLabel?: string | null;
  onAssign: (wagonIds: string[]) => void;
  assigning: boolean;
}
