"use client";

import { ReactNode, useId, useState, useTransition } from "react";
import {
  DndContext,
  closestCenter,
  PointerSensor,
  useSensor,
  useSensors,
  type DragEndEvent,
} from "@dnd-kit/core";
import {
  SortableContext,
  verticalListSortingStrategy,
  useSortable,
  arrayMove,
} from "@dnd-kit/sortable";
import { CSS } from "@dnd-kit/utilities";

type Item = { id: string; content: ReactNode };

function SortableRow({ id, content }: Item) {
  const { attributes, listeners, setNodeRef, transform, transition, isDragging } = useSortable({ id });

  return (
    <div
      ref={setNodeRef}
      style={{ transform: CSS.Transform.toString(transform), transition, opacity: isDragging ? 0.5 : 1 }}
      className="flex items-center gap-2"
    >
      <button
        type="button"
        {...attributes}
        {...listeners}
        className="cursor-grab touch-none rounded-lg p-2 text-text-muted hover:bg-bg-alt active:cursor-grabbing"
        title="Sürükle"
      >
        <svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
          <circle cx="9" cy="6" r="1.5" />
          <circle cx="15" cy="6" r="1.5" />
          <circle cx="9" cy="12" r="1.5" />
          <circle cx="15" cy="12" r="1.5" />
          <circle cx="9" cy="18" r="1.5" />
          <circle cx="15" cy="18" r="1.5" />
        </svg>
      </button>
      <div className="flex-1">{content}</div>
    </div>
  );
}

/**
 * Sunucudan gelen `items` değiştiğinde (yeni öğe eklendi/silindi) bileşenin sıfırdan
 * mount olup güncel veriyle başlaması için çağıran taraf bir `key` (örn. id listesinin
 * birleşimi) geçmeli — React'ın önerdiği "prop değişince state'i sıfırla" deseni.
 */
export function SortableList({
  items,
  onReorder,
}: {
  items: Item[];
  onReorder: (orderedIds: string[]) => void | Promise<void>;
}) {
  const [ordered, setOrdered] = useState(items);
  const [, startTransition] = useTransition();
  const sensors = useSensors(useSensor(PointerSensor, { activationConstraint: { distance: 4 } }));
  // dnd-kit varsayılan olarak kendi iç sayacıyla erişilebilirlik id'si üretir — sayfada birden
  // fazla DndContext varsa (örn. her söz kategorisi için ayrı liste) bu sayaç sunucu/istemci
  // render'ları arasında farklı ilerleyip hydration uyuşmazlığına yol açar. React'ın kendi
  // useId()'si sunucu/istemci arasında garanti tutarlı olduğu için dnd-kit'in id prop'una veriyoruz.
  const dndId = useId();

  function handleDragEnd(event: DragEndEvent) {
    const { active, over } = event;
    if (!over || active.id === over.id) return;

    const oldIndex = ordered.findIndex((item) => item.id === active.id);
    const newIndex = ordered.findIndex((item) => item.id === over.id);
    const next = arrayMove(ordered, oldIndex, newIndex);
    setOrdered(next);

    startTransition(() => {
      onReorder(next.map((item) => item.id));
    });
  }

  return (
    <DndContext id={dndId} sensors={sensors} collisionDetection={closestCenter} onDragEnd={handleDragEnd}>
      <SortableContext items={ordered.map((i) => i.id)} strategy={verticalListSortingStrategy}>
        <div className="flex flex-col gap-1.5">
          {ordered.map((item) => (
            <SortableRow key={item.id} id={item.id} content={item.content} />
          ))}
        </div>
      </SortableContext>
    </DndContext>
  );
}
