import { memo, useCallback, useMemo } from "react";
import { GripVertical } from "lucide-react";
import { Button } from "~/components/ui/button";
import { Badge } from "~/components/ui/badge";
import {
  DndContext,
  closestCenter,
  KeyboardSensor,
  PointerSensor,
  useSensor,
  useSensors,
} from "@dnd-kit/core";
import type { DragEndEvent } from "@dnd-kit/core";
import {
  arrayMove,
  SortableContext,
  sortableKeyboardCoordinates,
  useSortable,
  verticalListSortingStrategy,
} from "@dnd-kit/sortable";
import { CSS } from "@dnd-kit/utilities";

interface QueueSectionProps {
  queue: Array<{
    id: string;
    participantId: string;
  }>;
  availableParticipants: Array<{
    id: string;
    name: string;
    sport: { name: string };
  }>;
  isMyTurn: boolean;
  canPick: boolean;
  onRemoveFromQueue: (queueId: string) => void;
  onReorder: (participantIds: string[]) => void;
  onMakePick?: (participantId: string) => void;
}

// Sortable queue item component
const SortableQueueItem = memo(function SortableQueueItem({
  item,
  index,
  participantName,
  sportName,
  canPick,
  onRemove,
  onDraft,
}: {
  item: { id: string; participantId: string };
  index: number;
  participantName: string;
  sportName?: string;
  canPick: boolean;
  onRemove: (queueId: string) => void;
  onDraft?: (participantId: string) => void;
}) {
  const {
    attributes,
    listeners,
    setNodeRef,
    setActivatorNodeRef,
    transform,
    transition,
    isDragging,
  } = useSortable({ id: item.id });

  const style = {
    transform: CSS.Transform.toString(transform),
    transition,
    opacity: isDragging ? 0.5 : 1,
  };

  return (
    <div
      ref={setNodeRef}
      style={style}
      {...attributes}
      className={`flex items-center justify-between p-2 rounded-lg ${
        canPick ? "bg-electric/10 border border-electric/40" : "bg-muted"
      }`}
    >
      <div className="flex items-center gap-2 flex-1 min-w-0">
        <div
          ref={setActivatorNodeRef}
          {...listeners}
          className="flex items-center gap-2 flex-shrink-0 cursor-grab active:cursor-grabbing touch-none"
        >
          <GripVertical className="w-4 h-4 text-muted-foreground" />
          <Badge variant="default" className="text-xs">{index + 1}</Badge>
        </div>
        <div className="min-w-0">
          <p className="font-semibold text-sm truncate">{participantName}</p>
          {sportName && <p className="text-xs text-muted-foreground">{sportName}</p>}
        </div>
      </div>
      <div className="flex items-center gap-1 flex-shrink-0 ml-2">
        {canPick && onDraft && (
          <Button
            variant="default"
            size="sm"
            className="h-7 text-xs bg-electric text-background hover:bg-electric/90"
            onClick={() => onDraft(item.participantId)}
          >
            Draft
          </Button>
        )}
        <Button
          variant="ghost"
          size="icon"
          className="h-7 w-7 text-destructive hover:text-destructive hover:bg-destructive/10"
          onClick={() => onRemove(item.id)}
          title="Remove from queue"
        >
          <span className="text-lg">×</span>
        </Button>
      </div>
    </div>
  );
});

export const QueueSection = memo(function QueueSection({
  queue,
  availableParticipants,
  isMyTurn,
  canPick,
  onRemoveFromQueue,
  onReorder,
  onMakePick,
}: QueueSectionProps) {
  const sensors = useSensors(
    useSensor(PointerSensor, {
      activationConstraint: { distance: 8 },
    }),
    useSensor(KeyboardSensor, {
      coordinateGetter: sortableKeyboardCoordinates,
    })
  );

  const participantMap = useMemo(
    () => new Map(availableParticipants.map((p) => [p.id, p])),
    [availableParticipants]
  );

  const queueIds = useMemo(() => queue.map((item) => item.id), [queue]);

  const handleDragEnd = useCallback(
    (event: DragEndEvent) => {
      const { active, over } = event;
      if (over && active.id !== over.id) {
        const oldIndex = queue.findIndex((item) => item.id === active.id);
        const newIndex = queue.findIndex((item) => item.id === over.id);
        const reorderedQueue = arrayMove(queue, oldIndex, newIndex);
        onReorder(reorderedQueue.map((item) => item.participantId));
      }
    },
    [queue, onReorder]
  );

  return (
    <div className="p-4">
      {/* Queue List */}
      {queue.length === 0 ? (
        <p className="text-muted-foreground text-sm text-center py-8">
          Click participants in Available to add to your queue
        </p>
      ) : (
        <DndContext
          sensors={sensors}
          collisionDetection={closestCenter}
          onDragEnd={handleDragEnd}
        >
          <SortableContext
            items={queueIds}
            strategy={verticalListSortingStrategy}
          >
            <div className="space-y-1.5">
              {queue.map((item, index) => {
                const participant = participantMap.get(item.participantId);
                return (
                  <SortableQueueItem
                    key={item.id}
                    item={item}
                    index={index}
                    participantName={participant?.name ?? "Unknown"}
                    sportName={participant?.sport.name}
                    canPick={canPick}
                    onRemove={onRemoveFromQueue}
                    onDraft={onMakePick}
                  />
                );
              })}
            </div>
          </SortableContext>
        </DndContext>
      )}
    </div>
  );
});
