import { useRef, type TouchEvent } from 'react';

interface UseSwipeNavOptions {
  onSwipeLeft?: () => void;
  onSwipeRight?: () => void;
  /** Minimum horizontal distance (px) to count as a swipe. Default 60. */
  threshold?: number;
  /** Maximum vertical drift (px) before the gesture is treated as a scroll. Default 40. */
  verticalTolerance?: number;
}

/**
 * Lightweight horizontal swipe handler. Pure DOM touch events, no deps.
 *
 * Usage:
 *   const swipe = useSwipeNav({ onSwipeLeft: next, onSwipeRight: prev });
 *   <div {...swipe}>...</div>
 *
 * Behavior:
 *   - Touches starting on form controls (input / textarea / select / button /
 *     anchor / contenteditable) are ignored so we don't fight cursor placement
 *     or button presses.
 *   - Gestures with vertical drift > verticalTolerance are treated as
 *     scrolls and ignored, so vertical scroll inside panels still works.
 *   - Horizontal distance must exceed threshold to trigger a callback.
 */
export function useSwipeNav({
  onSwipeLeft,
  onSwipeRight,
  threshold = 60,
  verticalTolerance = 40,
}: UseSwipeNavOptions) {
  const start = useRef<{ x: number; y: number; ignored: boolean } | null>(null);

  const onTouchStart = (e: TouchEvent<HTMLElement>) => {
    const touch = e.touches[0];
    if (!touch) return;
    const target = e.target as HTMLElement | null;
    const ignored = !!target?.closest(
      'input, textarea, select, button, a, [contenteditable="true"], [data-no-swipe]',
    );
    start.current = { x: touch.clientX, y: touch.clientY, ignored };
  };

  const onTouchEnd = (e: TouchEvent<HTMLElement>) => {
    const s = start.current;
    start.current = null;
    if (!s || s.ignored) return;
    const touch = e.changedTouches[0];
    if (!touch) return;
    const dx = touch.clientX - s.x;
    const dy = touch.clientY - s.y;
    if (Math.abs(dy) > verticalTolerance) return;
    if (Math.abs(dx) < threshold) return;
    if (dx < 0) onSwipeLeft?.();
    else onSwipeRight?.();
  };

  return { onTouchStart, onTouchEnd };
}
