"use client"

import { useState, useEffect } from "react"
import Image from "next/image"
import {
  DndContext,
  closestCenter,
  PointerSensor,
  KeyboardSensor,
  useSensor,
  useSensors,
  type DragEndEvent,
} from "@dnd-kit/core"
import {
  arrayMove,
  SortableContext,
  sortableKeyboardCoordinates,
  useSortable,
  horizontalListSortingStrategy,
} from "@dnd-kit/sortable"
import { CSS } from "@dnd-kit/utilities"
import { useMutation } from "convex/react"
import { api } from "../../../../../convex/_generated/api"
import type { Id } from "../../../../../convex/_generated/dataModel"
import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
} from "@/components/ui/alert-dialog"
import { Button } from "@/components/ui/button"
import { HugeiconsIcon } from "@hugeicons/react"
import { Delete02Icon, ImageAdd01Icon, DragDropVerticalIcon } from "@hugeicons/core-free-icons"

export interface ProductImage {
  _id: Id<"productImages">
  url: string
  alt?: string
  position: number
}

// ─── Drag handle ──────────────────────────────────────────────────────────────
// Separate component following the user's pattern: calls useSortable with the
// same id to get attributes + listeners for the drag trigger element only.

function DragHandle({ id }: { id: string }) {
  const { attributes, listeners } = useSortable({ id })
  return (
    <Button
      {...attributes}
      {...listeners}
      variant="ghost"
      size="icon"
      className="size-7 cursor-grab text-muted-foreground hover:bg-transparent active:cursor-grabbing"
    >
      <HugeiconsIcon icon={DragDropVerticalIcon} strokeWidth={2} className="size-3.5" />
      <span className="sr-only">Drag to reorder</span>
    </Button>
  )
}

// ─── Sortable image card ───────────────────────────────────────────────────────
// Each card is a single-column "table" with 3 rows, physically rotated 180°.
// The DOM order is [delete, image, drag handle]; after rotation the visual
// order becomes [drag handle, image, delete] — drag handle on top, delete on
// bottom — matching the desired layout.

function SortableImageCard({
  image,
  onDelete,
}: {
  image: ProductImage
  onDelete: (id: Id<"productImages">) => void
}) {
  const { setNodeRef, transform, transition, isDragging } = useSortable({
    id: image._id,
  })

  const style = {
    transform: CSS.Transform.toString(transform),
    transition,
    opacity: isDragging ? 0.4 : 1,
    zIndex: isDragging ? 10 : undefined,
  }

  return (
    // Outer div: dnd-kit positioning (no rotation here to keep transforms clean)
    <div ref={setNodeRef} style={style} className="shrink-0">
      {/* Inner column: rotated 180° — children appear in reverse visual order */}
      <div className="flex rotate-180 flex-col items-center gap-1">
        {/* Row 3 in DOM → Row 1 visually (bottom in DOM = top after rotation) */}
        {/* Delete button — appears at BOTTOM after rotation */}
        <Button
          variant="ghost"
          size="icon"
          aria-label="Delete image"
          className="size-7 rotate-180 text-muted-foreground hover:text-destructive"
          onClick={() => onDelete(image._id)}
        >
          <HugeiconsIcon icon={Delete02Icon} strokeWidth={2} className="size-3.5" />
        </Button>

        {/* Row 2 in DOM → Row 2 visually (middle stays middle) */}
        {/* Image — appears in CENTER */}
        <div className="relative w-28 aspect-square rotate-180 overflow-hidden rounded-md border bg-muted">
          <Image
            src={image.url}
            alt={image.alt ?? "Product image"}
            fill
            className="object-contain"
          />
        </div>

        {/* Row 1 in DOM → Row 3 visually (top in DOM = bottom after rotation) */}
        {/* Drag handle — appears at TOP after rotation */}
        <div className="rotate-180">
          <DragHandle id={image._id} />
        </div>
      </div>
    </div>
  )
}

// ─── Gallery ──────────────────────────────────────────────────────────────────

interface ProductImageCarouselProps {
  images: ProductImage[]
  onAddMore: () => void
}

export function ProductImageCarousel({ images, onAddMore }: ProductImageCarouselProps) {
  const [sortedImages, setSortedImages] = useState<ProductImage[]>(() =>
    [...images].sort((a, b) => a.position - b.position),
  )
  const [pendingDeleteId, setPendingDeleteId] = useState<Id<"productImages"> | null>(null)
  const [isDeleting, setIsDeleting] = useState(false)

  const deleteImage = useMutation(api.products.deleteImage)
  const reorderImages = useMutation(api.products.reorderImages)

  // Sync with server whenever images prop changes (after add/delete)
  useEffect(() => {
    setSortedImages([...images].sort((a, b) => a.position - b.position))
  }, [images])

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

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

    setSortedImages((prev) => {
      const oldIndex = prev.findIndex((img) => img._id === active.id)
      const newIndex = prev.findIndex((img) => img._id === over.id)
      const reordered = arrayMove(prev, oldIndex, newIndex)
      reorderImages({
        updates: reordered.map((img, i) => ({ id: img._id, position: i })),
      })
      return reordered
    })
  }

  async function handleConfirmDelete() {
    if (!pendingDeleteId) return
    setIsDeleting(true)
    try {
      await deleteImage({ id: pendingDeleteId })
      setPendingDeleteId(null)
    } catch (err) {
      console.error("Failed to delete image:", err)
    } finally {
      setIsDeleting(false)
    }
  }

  return (
    <>
      <div className="flex items-start gap-3 overflow-x-auto pb-2">
        <DndContext
          sensors={sensors}
          collisionDetection={closestCenter}
          onDragEnd={handleDragEnd}
        >
          <SortableContext
            items={sortedImages.map((img) => img._id)}
            strategy={horizontalListSortingStrategy}
          >
            {sortedImages.map((image) => (
              <SortableImageCard
                key={image._id}
                image={image}
                onDelete={setPendingDeleteId}
              />
            ))}
          </SortableContext>
        </DndContext>

        {/* Add more — outside sortable context, always at the end */}
        <button
          type="button"
          onClick={onAddMore}
          className="flex w-28 shrink-0 flex-col items-center justify-center gap-2 self-center rounded-md border border-dashed p-6 text-sm text-muted-foreground transition-colors hover:border-foreground/40 hover:bg-muted/50 hover:text-foreground"
          style={{ aspectRatio: "1" }}
        >
          <HugeiconsIcon icon={ImageAdd01Icon} strokeWidth={2} className="size-5" />
          Add image
        </button>
      </div>

      <AlertDialog
        open={pendingDeleteId !== null}
        onOpenChange={(open) => {
          if (!open) setPendingDeleteId(null)
        }}
      >
        <AlertDialogContent>
          <AlertDialogHeader>
            <AlertDialogTitle>Delete this image?</AlertDialogTitle>
            <AlertDialogDescription>
              This cannot be undone. The image will be permanently removed from this product.
            </AlertDialogDescription>
          </AlertDialogHeader>
          <AlertDialogFooter>
            <AlertDialogCancel>Cancel</AlertDialogCancel>
            <AlertDialogAction
              variant="destructive"
              onClick={handleConfirmDelete}
              disabled={isDeleting}
            >
              {isDeleting ? "Deleting…" : "Delete"}
            </AlertDialogAction>
          </AlertDialogFooter>
        </AlertDialogContent>
      </AlertDialog>
    </>
  )
}
