import { useEffect, RefObject, useRef } from 'react';

interface UseSwipeNavigationProps {
  containerRef: RefObject<HTMLElement>;
  onSwipeLeft: () => void;
  onSwipeRight: () => void;
  onSwipeUp?: () => void;
  onSwipeDown?: () => void;
  disabled?: boolean;
  threshold?: number;
  axis?: 'horizontal' | 'vertical';
}

/**
 * A hook that enables swipe-based navigation on a container element.
 * In horizontal mode: swipe left → next, swipe right → previous.
 * In vertical mode: swipe up → next, swipe down → previous.
 */
const useSwipeNavigation = ({
  containerRef,
  onSwipeLeft,
  onSwipeRight,
  onSwipeUp,
  onSwipeDown,
  disabled = false,
  threshold = 50,
  axis = 'horizontal',
}: UseSwipeNavigationProps) => {
  const onSwipeLeftRef  = useRef(onSwipeLeft);
  const onSwipeRightRef = useRef(onSwipeRight);
  const onSwipeUpRef    = useRef(onSwipeUp);
  const onSwipeDownRef  = useRef(onSwipeDown);

  useEffect(() => {
    onSwipeLeftRef.current  = onSwipeLeft;
    onSwipeRightRef.current = onSwipeRight;
    onSwipeUpRef.current    = onSwipeUp;
    onSwipeDownRef.current  = onSwipeDown;
  }, [onSwipeLeft, onSwipeRight, onSwipeUp, onSwipeDown]);

  useEffect(() => {
    const container = containerRef.current;
    if (!container || disabled) return;

    let startX: number | null = null;
    let startY: number | null = null;

    const handleTouchStart = (e: TouchEvent) => {
      startX = e.touches[0].clientX;
      startY = e.touches[0].clientY;
    };

    const handleTouchEnd = (e: TouchEvent) => {
      if (startX === null || startY === null) return;

      const endX = e.changedTouches[0].clientX;
      const endY = e.changedTouches[0].clientY;

      if (axis === 'vertical') {
        const diffY = startY - endY; // positive = swiped up
        if (Math.abs(diffY) > threshold) {
          if (diffY > 0) {
            // Swiped up → next
            (onSwipeUpRef.current ?? onSwipeLeftRef.current)();
          } else {
            // Swiped down → previous
            (onSwipeDownRef.current ?? onSwipeRightRef.current)();
          }
        }
      } else {
        const diffX = startX - endX; // positive = swiped left
        if (Math.abs(diffX) > threshold) {
          if (diffX > 0) {
            onSwipeLeftRef.current();
          } else {
            onSwipeRightRef.current();
          }
        }
      }

      startX = null;
      startY = null;
    };

    container.addEventListener('touchstart', handleTouchStart, { passive: true });
    container.addEventListener('touchend', handleTouchEnd);

    return () => {
      container.removeEventListener('touchstart', handleTouchStart);
      container.removeEventListener('touchend', handleTouchEnd);
    };
  }, [containerRef, disabled, threshold, axis]);
};

export default useSwipeNavigation;

