"use client"

import { useCallback, useRef, type Dispatch, type SetStateAction } from "react"
import type { SidebarNavDragPayload, SidebarNavDropPlacement } from "@/lib/sidebar-nav-dnd"
import {
  markNavDragSource,
  setNavDropIndicator,
  unmarkNavDragSource,
} from "@/components/gmail/sidebar/sidebar-nav-primitives"

export function useSidebarNavDrag(opts: {
  reorderLabelRows: (
    sourceId: string,
    targetId: string,
    placement: "before" | "after"
  ) => void
  moveFolderRelative: (
    sourceId: string,
    targetId: string,
    placement: SidebarNavDropPlacement
  ) => void
  setExpandedFolderIds: Dispatch<SetStateAction<Set<string>>>
}) {
  const { reorderLabelRows, moveFolderRelative, setExpandedFolderIds } = opts
  const navDragRef = useRef<SidebarNavDragPayload | null>(null)
  const navDragSourceElRef = useRef<HTMLElement | null>(null)
  const navDropTargetElRef = useRef<HTMLElement | null>(null)
  const navDropPlacementRef = useRef<SidebarNavDropPlacement | null>(null)

  const beginNavDrag = useCallback(
    (payload: SidebarNavDragPayload, sourceEl: HTMLElement | null) => {
      navDragRef.current = payload
      navDragSourceElRef.current = sourceEl
      markNavDragSource(sourceEl)
    },
    []
  )

  const clearNavDrag = useCallback(() => {
    unmarkNavDragSource(navDragSourceElRef.current)
    setNavDropIndicator(navDropTargetElRef.current, null)
    navDragRef.current = null
    navDragSourceElRef.current = null
    navDropTargetElRef.current = null
    navDropPlacementRef.current = null
  }, [])

  const updateNavDropTarget = useCallback(
    (el: HTMLElement, placement: SidebarNavDropPlacement) => {
      if (navDropTargetElRef.current !== el) {
        setNavDropIndicator(navDropTargetElRef.current, null)
      }
      navDropTargetElRef.current = el
      navDropPlacementRef.current = placement
      setNavDropIndicator(el, placement)
    },
    []
  )

  const clearNavDropTarget = useCallback((el: HTMLElement) => {
    if (navDropTargetElRef.current === el) {
      setNavDropIndicator(el, null)
      navDropTargetElRef.current = null
      navDropPlacementRef.current = null
    }
  }, [])

  const commitNavDrop = useCallback(
    (
      payload: SidebarNavDragPayload,
      targetId: string,
      placement: SidebarNavDropPlacement,
      targetKind: "label" | "folder"
    ) => {
      clearNavDrag()
      if (payload.id === targetId && placement !== "inside") return
      if (targetKind === "label" && payload.kind === "label") {
        if (placement === "inside") return
        reorderLabelRows(payload.id, targetId, placement)
      } else if (targetKind === "folder" && payload.kind === "folder") {
        moveFolderRelative(payload.id, targetId, placement)
        if (placement === "inside") {
          setExpandedFolderIds((prev) => {
            const next = new Set(prev)
            next.add(targetId)
            return next
          })
        }
      }
    },
    [clearNavDrag, moveFolderRelative, reorderLabelRows, setExpandedFolderIds]
  )

  return {
    navDragRef,
    navDropPlacementRef,
    beginNavDrag,
    clearNavDrag,
    updateNavDropTarget,
    clearNavDropTarget,
    commitNavDrop,
  }
}
