import { useCallback, useRef, useState } from "react"

const DEFAULT_DELAY_MS = 500
const ACK_MS = 280

/** Applied briefly when a long-press action fires (touch feedback). */
export const LONG_PRESS_ACK_CLASS = "long-press-ack"

export function useLongPress(
  onLongPress: () => void,
  options?: { delay?: number; disabled?: boolean; ack?: boolean }
) {
  const timerRef = useRef<ReturnType<typeof setTimeout> | null>(null)
  const ackTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null)
  const firedRef = useRef(false)
  const delay = options?.delay ?? DEFAULT_DELAY_MS
  const disabled = options?.disabled ?? false
  const withAck = options?.ack ?? true
  const [ack, setAck] = useState(false)

  const clearAck = useCallback(() => {
    if (ackTimerRef.current) {
      clearTimeout(ackTimerRef.current)
      ackTimerRef.current = null
    }
    setAck(false)
  }, [])

  const clear = useCallback(() => {
    if (timerRef.current) {
      clearTimeout(timerRef.current)
      timerRef.current = null
    }
  }, [])

  const pulseAck = useCallback(() => {
    if (!withAck) return
    clearAck()
    setAck(true)
    ackTimerRef.current = setTimeout(() => {
      setAck(false)
      ackTimerRef.current = null
    }, ACK_MS)
  }, [clearAck, withAck])

  const onPointerDown = useCallback(
    (e: React.PointerEvent) => {
      if (disabled) return
      if (e.pointerType === "mouse" && e.button !== 0) return
      firedRef.current = false
      clear()
      timerRef.current = setTimeout(() => {
        firedRef.current = true
        pulseAck()
        onLongPress()
      }, delay)
    },
    [clear, delay, disabled, onLongPress, pulseAck]
  )

  const onClickCapture = useCallback(
    (e: React.MouseEvent) => {
      if (!firedRef.current) return
      e.preventDefault()
      e.stopPropagation()
      firedRef.current = false
    },
    []
  )

  return {
    onPointerDown,
    onPointerUp: clear,
    onPointerLeave: clear,
    onPointerCancel: clear,
    onClickCapture,
    ackActive: ack,
    ackClassName: ack ? LONG_PRESS_ACK_CLASS : undefined,
  }
}
