import { useRef, useState } from "react";
import {
  DndContext, DragOverlay, closestCenter, PointerSensor, KeyboardSensor,
  useSensor, useSensors,
} from "@dnd-kit/core";
import {
  SortableContext, sortableKeyboardCoordinates, useSortable, rectSortingStrategy,
  arrayMove,
} from "@dnd-kit/sortable";
import { CSS } from "@dnd-kit/utilities";
import { Image, Plus, Trash2 } from "lucide-react";

import ConfirmDialog from "@/components/pc/admin/common/ConfirmDialog";

/**
 * 카드 컨텐츠 (Sortable wrapper와 DragOverlay에서 공통 사용)
 */
function MerchandiseCardContent({ item, index, onRemove, dragging = false }) {
  return (
    <div
      className={`relative group aspect-[3/4] rounded-xl overflow-hidden bg-white border transition-shadow ${
        dragging ? "border-primary shadow-xl" : "border-gray-100"
      }`}
    >
      <img
        src={item.preview}
        alt={`굿즈 ${index + 1}`}
        className="w-full h-full object-contain bg-gray-50 pointer-events-none"
        draggable={false}
      />
      <span className="absolute top-2 left-2 min-w-[24px] h-6 px-2 rounded-full bg-black/60 text-white text-xs font-medium flex items-center justify-center pointer-events-none">
        {index + 1}
      </span>
      {onRemove && (
        <button
          type="button"
          onClick={(e) => {
            e.stopPropagation();
            onRemove(item.id);
          }}
          onPointerDown={(e) => e.stopPropagation()}
          className="absolute top-2 right-2 w-7 h-7 rounded-full bg-black/60 hover:bg-red-500 text-white flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity z-10"
        >
          <Trash2 size={13} />
        </button>
      )}
    </div>
  );
}

/**
 * 정렬 가능한 굿즈 카드
 */
function SortableMerchandiseCard({ item, index, onRemove }) {
  const {
    attributes, listeners, setNodeRef, transform, transition, isDragging,
  } = useSortable({
    id: item.id,
    transition: { duration: 200, easing: "cubic-bezier(0.25, 0.1, 0.25, 1)" },
  });

  const style = {
    transform: CSS.Transform.toString(transform),
    transition,
  };

  return (
    <div
      ref={setNodeRef}
      style={style}
      {...attributes}
      {...listeners}
      className={`touch-none cursor-grab active:cursor-grabbing ${isDragging ? "opacity-30" : ""}`}
    >
      <MerchandiseCardContent item={item} index={index} onRemove={onRemove} />
    </div>
  );
}

function MerchandiseSection({ items, setItems }) {
  const fileInputRef = useRef(null);
  const [deleteConfirm, setDeleteConfirm] = useState({
    isOpen: false,
    itemId: null,
    itemName: null,
  });
  const [activeId, setActiveId] = useState(null);

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

  // 이미지 추가
  const handleFileChange = (e) => {
    const files = Array.from(e.target.files);
    if (files.length === 0) return;

    const newItems = files.map((file, i) => {
      const url = URL.createObjectURL(file);
      return {
        id: `md-${Date.now()}-${i}`,
        file,
        preview: url,
      };
    });

    setItems((prev) => [...prev, ...newItems]);
    e.target.value = "";
  };

  // 이미지 삭제
  const handleRemoveItem = (id) => {
    const item = items.find((it) => it.id === id);
    setDeleteConfirm({
      isOpen: true,
      itemId: id,
      itemName: item?.file?.name || "이미지",
    });
  };

  const confirmRemoveItem = () => {
    if (deleteConfirm.itemId !== null) {
      setItems((prev) => {
        const item = prev.find((it) => it.id === deleteConfirm.itemId);
        if (item?.preview) {
          URL.revokeObjectURL(item.preview);
        }
        return prev.filter((it) => it.id !== deleteConfirm.itemId);
      });
    }
    setDeleteConfirm({ isOpen: false, itemId: null, itemName: null });
  };

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

    const oldIdx = items.findIndex((it) => it.id === active.id);
    const newIdx = items.findIndex((it) => it.id === over.id);
    setItems(arrayMove(items, oldIdx, newIdx));
  };

  const activeItem = items.find((it) => it.id === activeId);
  const activeIndex = items.findIndex((it) => it.id === activeId);

  return (
    <>
      <ConfirmDialog
        isOpen={deleteConfirm.isOpen}
        onClose={() =>
          setDeleteConfirm({ isOpen: false, itemId: null, itemName: null })
        }
        onConfirm={confirmRemoveItem}
        title="이미지 삭제"
        message={
          <p>
            <span className="font-medium">{deleteConfirm.itemName}</span>
            을(를) 삭제하시겠습니까?
          </p>
        }
        confirmText="삭제"
        cancelText="취소"
      />

      <div className="bg-white rounded-2xl border border-gray-100 shadow-sm p-6">
        <h2 className="text-lg font-bold text-gray-900 mb-6">굿즈</h2>

        <input
          ref={fileInputRef}
          type="file"
          accept="image/*"
          multiple
          onChange={handleFileChange}
          className="hidden"
        />

        {items.length === 0 ? (
          <div
            onClick={() => fileInputRef.current?.click()}
            className="flex flex-col items-center justify-center py-12 border-2 border-dashed border-gray-200 rounded-xl cursor-pointer hover:border-primary hover:bg-primary/5 transition-colors"
          >
            <Image size={36} className="text-gray-300 mb-3" />
            <p className="text-sm text-gray-400">
              클릭하여 굿즈 이미지를 추가하세요
            </p>
            <p className="text-xs text-gray-300 mt-1">여러 장 선택 가능</p>
          </div>
        ) : (
          <>
            <DndContext
              sensors={sensors}
              collisionDetection={closestCenter}
              onDragStart={(e) => setActiveId(e.active.id)}
              onDragCancel={() => setActiveId(null)}
              onDragEnd={handleDragEnd}
            >
              <SortableContext items={items.map((it) => it.id)} strategy={rectSortingStrategy}>
                <div className="grid grid-cols-4 gap-3">
                  {items.map((item, index) => (
                    <SortableMerchandiseCard
                      key={item.id}
                      item={item}
                      index={index}
                      onRemove={handleRemoveItem}
                    />
                  ))}
                  <button
                    type="button"
                    onClick={() => fileInputRef.current?.click()}
                    className="aspect-[3/4] rounded-xl border-2 border-dashed border-gray-200 hover:border-primary hover:bg-primary/5 text-gray-400 hover:text-primary transition-colors flex flex-col items-center justify-center"
                  >
                    <Plus size={24} />
                    <span className="text-xs mt-1">추가</span>
                  </button>
                </div>
              </SortableContext>
              <DragOverlay
                dropAnimation={{
                  duration: 200,
                  easing: "cubic-bezier(0.25, 0.1, 0.25, 1)",
                }}
              >
                {activeItem ? (
                  <MerchandiseCardContent item={activeItem} index={activeIndex} dragging />
                ) : null}
              </DragOverlay>
            </DndContext>
            <p className="text-xs text-gray-400 mt-3">
              드래그하여 순서를 변경할 수 있습니다. 순서대로 표시됩니다.
            </p>
          </>
        )}
      </div>
    </>
  );
}

export default MerchandiseSection;
