import {
  Badge,
  Button,
  Checkbox,
  Group,
  Pagination,
  Paper,
  Stack,
  Table,
  Text,
  ThemeIcon,
  Tooltip,
} from "@mantine/core";
import { useQuery } from "@tanstack/react-query";
import { Link2, MapPin, PackageOpen, User } from "lucide-react";
import { useState } from "react";

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

interface Props {
  trainId: string;
  /** Staff may attach and the train is editable (not out on a run). */
  canAttach: boolean;
  attachPending: boolean;
  onAttach: (wagonIds: string[]) => void;
}

/**
 * "Detached wagons" tab: wagons last detached from THIS train that are still
 * loose — with when, where and by whom they were detached — so staff can pick
 * them straight back onto the consist without hunting through the global pool.
 */
export default function DetachedWagonsPanel({
  trainId,
  canAttach,
  attachPending,
  onAttach,
}: Props) {
  const [page, setPage] = useState(1);
  const query = useQuery(
    api.trainBuilder.detachedWagons.queryOptions({
      input: { id: trainId, page, pageSize: 20 },
      enabled: Boolean(trainId),
      // Keep the previous page on screen while the next one loads.
      placeholderData: (prev) => prev,
    }),
  );
  const rows = query.data?.items ?? [];
  const totalPages = Math.max(1, query.data?.meta.totalPages ?? 1);
  // Selection is page-scoped in the header checkbox but survives paging, so
  // staff can gather wagons across pages into one attach.
  const [selected, setSelected] = useState<ReadonlySet<string>>(new Set());
  const allSelected = rows.length > 0 && rows.every((r) => selected.has(r.wagonId));

  const toggle = (wagonId: string, checked: boolean) =>
    setSelected((prev) => {
      const next = new Set(prev);
      if (checked) next.add(wagonId);
      else next.delete(wagonId);
      return next;
    });

  return (
    <Paper radius="xl" p="lg" withBorder>
      <Stack gap="lg">
        <Group justify="space-between" align="flex-start" wrap="wrap" gap="md">
          <Group gap="md" align="center" wrap="nowrap">
            <ThemeIcon size={44} radius="md" variant="light" color="orange">
              <PackageOpen size={22} />
            </ThemeIcon>
            <Stack gap={2}>
              <Text fw={700} fz="lg">
                Detached wagons
              </Text>
              <Text size="sm" c="dimmed">
                Wagons that left this train and are still loose — select and
                attach them back in one click.
              </Text>
            </Stack>
          </Group>
          {canAttach ? (
            <Button
              leftSection={<Link2 size={16} />}
              disabled={selected.size === 0}
              loading={attachPending}
              onClick={() => {
                onAttach([...selected]);
                setSelected(new Set());
              }}
            >
              Attach {selected.size || ""} wagon{selected.size === 1 ? "" : "s"}
            </Button>
          ) : null}
        </Group>

        {query.isLoading ? (
          <Text size="sm" c="dimmed" ta="center" py="md">
            Loading detached wagons…
          </Text>
        ) : rows.length === 0 ? (
          <Text size="sm" c="dimmed" ta="center" py="md">
            No loose wagons were detached from this train — detach history starts
            being recorded from now on.
          </Text>
        ) : (
          <Table striped highlightOnHover withTableBorder>
            <Table.Thead>
              <Table.Tr>
                {canAttach ? (
                  <Table.Th w={36}>
                    <Checkbox
                      checked={allSelected}
                      indeterminate={selected.size > 0 && !allSelected}
                      onChange={(e) =>
                        setSelected(
                          e.currentTarget.checked
                            ? new Set(rows.map((r) => r.wagonId))
                            : new Set(),
                        )
                      }
                    />
                  </Table.Th>
                ) : null}
                <Table.Th>Wagon</Table.Th>
                <Table.Th>Type</Table.Th>
                <Table.Th>Now standing at</Table.Th>
                <Table.Th>Last detached</Table.Th>
              </Table.Tr>
            </Table.Thead>
            <Table.Tbody>
              {rows.map((r) => (
                <Table.Tr key={r.wagonId}>
                  {canAttach ? (
                    <Table.Td>
                      <Checkbox
                        checked={selected.has(r.wagonId)}
                        onChange={(e) => toggle(r.wagonId, e.currentTarget.checked)}
                      />
                    </Table.Td>
                  ) : null}
                  <Table.Td>
                    <Text fw={600} size="sm" ff="monospace">
                      {r.wagonNumber}
                    </Text>
                  </Table.Td>
                  <Table.Td>
                    <Badge size="sm" variant="light" color="gray">
                      {r.wagonTypeCode ?? "—"}
                    </Badge>
                  </Table.Td>
                  <Table.Td>
                    <Text size="sm">{r.currentYardLabel ?? "No yard"}</Text>
                  </Table.Td>
                  <Table.Td>
                    <Group gap="md" wrap="wrap">
                      <Tooltip label={new Date(r.detachedAt).toLocaleString()}>
                        <Text size="sm">{new Date(r.detachedAt).toLocaleDateString()}</Text>
                      </Tooltip>
                      {r.detachedYardLabel ? (
                        <Group gap={4} wrap="nowrap">
                          <MapPin size={12} />
                          <Text size="xs" c="dimmed">
                            at {r.detachedYardLabel}
                          </Text>
                        </Group>
                      ) : null}
                      {r.detachedBy ? (
                        <Group gap={4} wrap="nowrap">
                          <User size={12} />
                          <Text size="xs" c="dimmed">
                            by {r.detachedBy}
                          </Text>
                        </Group>
                      ) : null}
                    </Group>
                  </Table.Td>
                </Table.Tr>
              ))}
            </Table.Tbody>
          </Table>
        )}

        {totalPages > 1 ? (
          <Group justify="space-between">
            <Text size="xs" c="dimmed">
              {query.data?.meta.total ?? 0} wagon(s) · selection carries across pages
            </Text>
            <Pagination size="sm" value={page} onChange={setPage} total={totalPages} />
          </Group>
        ) : null}
      </Stack>
    </Paper>
  );
}
