"use client";

import {
  DndContext,
  closestCenter,
  type DragEndEvent,
  KeyboardSensor,
  PointerSensor,
  useSensor,
  useSensors,
} from "@dnd-kit/core";
import {
  SortableContext,
  sortableKeyboardCoordinates,
  useSortable,
  verticalListSortingStrategy,
} from "@dnd-kit/sortable";
import { CSS } from "@dnd-kit/utilities";
import { Eye, EyeOff, GripVertical, Trash2 } from "lucide-react";
import { useTranslations } from "next-intl";

import type { ImageLayer } from "@/lib/image-editor-types";
import { useImageEditorStore } from "@/lib/image-editor-store";
import { cn } from "@/lib/utils";

function layerIcon(type: ImageLayer["type"]): string {
  switch (type) {
    case "image":
      return "🖼";
    case "text":
      return "T";
    case "shape":
      return "□";
    case "draw":
      return "✎";
    default:
      return "•";
  }
}

function SortableLayerRow({ layer }: { layer: ImageLayer }) {
  const t = useTranslations("auto.componentsImageEditorPanelsLayersPanel");
  const selectedLayerId = useImageEditorStore((s) => s.selectedLayerId);
  const setSelectedLayer = useImageEditorStore((s) => s.setSelectedLayer);
  const toggleLayerVisibility = useImageEditorStore((s) => s.toggleLayerVisibility);
  const deleteLayer = useImageEditorStore((s) => s.deleteLayer);

  const { attributes, listeners, setNodeRef, transform, transition } =
    useSortable({ id: layer.id });

  return (
    <div
      ref={setNodeRef}
      style={{
        transform: CSS.Transform.toString(transform),
        transition,
      }}
      className={cn(
        "flex items-center gap-1 rounded-lg border px-2 py-2",
        selectedLayerId === layer.id
          ? "border-primary-500 bg-primary-600/15"
          : "border-gray-700 bg-gray-800/80"
      )}
    >
      <button
        type="button"
        className="cursor-grab text-gray-500 hover:text-gray-300"
        aria-label={t("reorderLayer", { name: layer.name ?? "" })}
        {...attributes}
        {...listeners}
      >
        <GripVertical className="h-3.5 w-3.5" />
      </button>
      <button
        type="button"
        onClick={() => setSelectedLayer(layer.id)}
        className="flex min-w-0 flex-1 items-center gap-2 text-left text-xs text-gray-200"
      >
        <span className="w-4 text-center">{layerIcon(layer.type)}</span>
        <span className="truncate">{layer.name}</span>
      </button>
      <button
        type="button"
        onClick={() => toggleLayerVisibility(layer.id)}
        className="text-gray-400 hover:text-white"
        aria-label={layer.visible ? t("hideLayer") : t("showLayer")}
      >
        {layer.visible ? (
          <Eye className="h-3.5 w-3.5" />
        ) : (
          <EyeOff className="h-3.5 w-3.5" />
        )}
      </button>
      {layer.type !== "image" ? (
        <button
          type="button"
          onClick={() => deleteLayer(layer.id)}
          className="text-gray-400 hover:text-red-400"
          aria-label={t("deleteLayer", { name: layer.name ?? "" })}
        >
          <Trash2 className="h-3.5 w-3.5" />
        </button>
      ) : (
        <span className="w-3.5" />
      )}
    </div>
  );
}

export function LayersPanel() {
  const t = useTranslations("auto.componentsImageEditorPanelsLayersPanel");
  const layers = useImageEditorStore((s) => s.layers);
  const reorderLayers = useImageEditorStore((s) => s.reorderLayers);

  const reversed = [...layers].sort((a, b) => b.zIndex - a.zIndex);

  const sensors = useSensors(
    useSensor(PointerSensor, { activationConstraint: { distance: 4 } }),
    useSensor(KeyboardSensor, {
      coordinateGetter: sortableKeyboardCoordinates,
    })
  );

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

    const oldIndex = reversed.findIndex((l) => l.id === active.id);
    const newIndex = reversed.findIndex((l) => l.id === over.id);
    if (oldIndex === -1 || newIndex === -1) return;

    const next = [...reversed];
    const [moved] = next.splice(oldIndex, 1);
    next.splice(newIndex, 0, moved);
    reorderLayers([...next].reverse().map((l) => l.id));
  };

  if (layers.length === 0) {
    return <p className="text-xs text-gray-500">{t("emptyState")}</p>;
  }

  return (
    <DndContext
      sensors={sensors}
      collisionDetection={closestCenter}
      onDragEnd={handleDragEnd}
    >
      <SortableContext
        items={reversed.map((l) => l.id)}
        strategy={verticalListSortingStrategy}
      >
        <div className="space-y-1">
          {reversed.map((layer) => (
            <SortableLayerRow key={layer.id} layer={layer} />
          ))}
        </div>
      </SortableContext>
    </DndContext>
  );
}
