import {
  DragDropContext,
  Draggable,
  Droppable,
  type DraggableProvided,
  type DraggableStateSnapshot,
  type DropResult,
} from "@hello-pangea/dnd";
import { ActionIcon, Badge, Box, Group, Stack, Text, Tooltip } from "@mantine/core";
import { GripVertical, Trash2, Wrench } from "lucide-react";
import { type ReactNode } from "react";
import { createPortal } from "react-dom";

import type { TrainCompositionWagon } from "@/services/trainBuilder.service";

/** Reparent dragged row to body — fixes position:fixed inside transformed parents. */
const PortalAwareRow = ({
  snapshot,
  children,
}: {
  snapshot: DraggableStateSnapshot;
  children: ReactNode;
}) => {
  if (snapshot.isDragging) {
    return createPortal(children, document.body);
  }
  return <>{children}</>;
};

/**
 * The train's ordered wagon consist. Drag to reorder (persisted on drop),
 * trash to detach a wagon back to the yard.
 */
export default function ConsistWagonList({
  wagons,
  editable,
  onReorder,
  onRemove,
  onMaintenance,
  busy = false,
}: ConsistWagonListProps) {
  const onDragEnd = (result: DropResult) => {
    if (!result.destination) return;
    const from = result.source.index;
    const to = result.destination.index;
    if (from === to) return;
    const next = [...wagons];
    const [moved] = next.splice(from, 1);
    next.splice(to, 0, moved!);
    onReorder(next.map((w) => w.id));
  };

  if (!wagons.length) {
    return (
      <Text py="lg" ta="center" c="dimmed" size="sm">
        No wagons in the consist yet.
      </Text>
    );
  }

  return (
    <DragDropContext onDragEnd={onDragEnd}>
      <Droppable droppableId="train-consist-wagons" isDropDisabled={!editable || busy}>
        {(dropProvided) => (
          <Stack gap="xs" ref={dropProvided.innerRef} {...dropProvided.droppableProps}>
            {wagons.map((wagon, index) => (
              <Draggable
                key={wagon.id}
                draggableId={wagon.id}
                index={index}
                isDragDisabled={!editable || busy}
              >
                {(dragProvided, snapshot) => (
                  <WagonRow
                    wagon={wagon}
                    index={index}
                    dragProvided={dragProvided}
                    snapshot={snapshot}
                    editable={editable}
                    busy={busy}
                    onRemove={onRemove}
                    onMaintenance={onMaintenance}
                  />
                )}
              </Draggable>
            ))}
            {dropProvided.placeholder}
          </Stack>
        )}
      </Droppable>
    </DragDropContext>
  );
}

export interface ConsistWagonListProps {
  wagons: TrainCompositionWagon[];
  editable: boolean;
  onReorder: (wagonIds: string[]) => void;
  onRemove: (wagonId: string) => void;
  /** Detach the wagon and move it to MAINTENANCE status. */
  onMaintenance: (wagonId: string) => void;
  busy?: boolean;
}

function WagonRow({
  wagon,
  index,
  dragProvided,
  snapshot,
  editable,
  busy,
  onRemove,
  onMaintenance,
}: {
  wagon: TrainCompositionWagon;
  index: number;
  dragProvided: DraggableProvided;
  snapshot: DraggableStateSnapshot;
  editable: boolean;
  busy: boolean;
  onRemove: (wagonId: string) => void;
  onMaintenance: (wagonId: string) => void;
}) {
  return (
    <PortalAwareRow snapshot={snapshot}>
      <Group
        ref={dragProvided.innerRef}
        {...dragProvided.draggableProps}
        {...dragProvided.dragHandleProps}
        gap="sm"
        wrap="nowrap"
        p="sm"
        style={{
          ...dragProvided.draggableProps.style,
          border: "1px solid var(--mantine-color-gray-3)",
          borderRadius: "var(--mantine-radius-md)",
          background: snapshot.isDragging ? "var(--mantine-color-gray-0)" : "white",
          boxShadow: snapshot.isDragging ? "0 8px 24px rgba(0, 0, 0, 0.12)" : undefined,
          cursor: editable ? (snapshot.isDragging ? "grabbing" : "grab") : "default",
          userSelect: "none",
        }}
      >
        {editable ? (
          <Box c="dimmed" style={{ display: "flex", alignItems: "center" }}>
            <GripVertical size={18} />
          </Box>
        ) : null}
        <Badge variant="light" color="gray" size="sm">
          {index + 1}
        </Badge>
        <Stack gap={2} 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 · ${wagon.wagonType.lengthMeters}m`
              : "Unknown type"}
          </Text>
        </Stack>
        {editable ? (
          <Group gap={4} wrap="nowrap">
            <Tooltip label="Send to maintenance (detaches)" withArrow>
              <ActionIcon
                variant="subtle"
                color="orange"
                disabled={busy}
                onClick={() => onMaintenance(wagon.id)}
                aria-label={`Send wagon ${wagon.wagonNumber} to maintenance`}
              >
                <Wrench size={16} />
              </ActionIcon>
            </Tooltip>
            <Tooltip label="Detach wagon" withArrow>
              <ActionIcon
                variant="subtle"
                color="red"
                disabled={busy}
                onClick={() => onRemove(wagon.id)}
                aria-label={`Detach wagon ${wagon.wagonNumber}`}
              >
                <Trash2 size={16} />
              </ActionIcon>
            </Tooltip>
          </Group>
        ) : null}
      </Group>
    </PortalAwareRow>
  );
}
