"use client";

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

type LongPressOptions = {
  delay?: number;
  /** Cancel long-press only after pointer moves beyond this distance (px). */
  moveTolerance?: number;
};

export function useLongPress(
  onLongPress: () => void,
  { delay = 2000, moveTolerance = 14 }: LongPressOptions = {}
) {
  const timerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
  const blockClickRef = useRef(false);
  const startRef = useRef<{ x: number; y: number } | null>(null);
  const [pressing, setPressing] = useState(false);

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

  const cancelPress = useCallback(() => {
    clear();
    setPressing(false);
    startRef.current = null;
  }, [clear]);

  const onPointerDown = useCallback(
    (e: React.PointerEvent) => {
      if (e.button !== 0) return;
      blockClickRef.current = false;
      startRef.current = { x: e.clientX, y: e.clientY };
      setPressing(true);
      clear();
      timerRef.current = setTimeout(() => {
        blockClickRef.current = true;
        setPressing(false);
        startRef.current = null;
        if (typeof navigator !== "undefined" && navigator.vibrate) {
          navigator.vibrate(15);
        }
        onLongPress();
      }, delay);
    },
    [clear, delay, onLongPress]
  );

  const onPointerMove = useCallback(
    (e: React.PointerEvent) => {
      const start = startRef.current;
      if (!start || !timerRef.current) return;
      const dx = e.clientX - start.x;
      const dy = e.clientY - start.y;
      if (Math.hypot(dx, dy) > moveTolerance) {
        cancelPress();
      }
    },
    [cancelPress, moveTolerance]
  );

  const endPress = useCallback(() => {
    clear();
    setPressing(false);
    startRef.current = null;
  }, [clear]);

  const shouldBlockClick = useCallback(() => {
    if (blockClickRef.current) {
      blockClickRef.current = false;
      return true;
    }
    return false;
  }, []);

  return {
    pressing,
    shouldBlockClick,
    cancelPress,
    handlers: {
      onPointerDown,
      onPointerMove,
      onPointerUp: endPress,
      onPointerCancel: endPress,
      onContextMenu: (e: React.MouseEvent) => e.preventDefault(),
    },
  };
}
