import type { RefObject } from "preact";
import { useEffect, useRef } from "preact/hooks";

const EDGE_THRESHOLD = 30; // px from screen edge to start a swipe
const MIN_SWIPE = 50;      // minimum horizontal distance to trigger

export function useSwipeNavigation(
    elementRef: RefObject<HTMLElement>,
    onSwipeLeft: () => void,
    onSwipeRight: () => void,
) {
    // Keep callbacks in a ref so the effect doesn't re-run when they change
    const callbacksRef = useRef({ onSwipeLeft, onSwipeRight });
    callbacksRef.current = { onSwipeLeft, onSwipeRight };

    useEffect(() => {
        const el = elementRef.current;
        if (!el) return;

        let start: { x: number; y: number } | null = null;

        const onTouchStart = (e: TouchEvent) => {
            const t = e.touches[0];
            const fromEdge = t.clientX < EDGE_THRESHOLD
                || t.clientX > window.innerWidth - EDGE_THRESHOLD;
            start = fromEdge ? { x: t.clientX, y: t.clientY } : null;
        };

        const onTouchMove = (e: TouchEvent) => {
            if (!start) return;
            const t = e.touches[0];
            const dx = Math.abs(t.clientX - start.x);
            const dy = Math.abs(t.clientY - start.y);
            // Prevent Chrome's back/forward navigation once we're sure it's horizontal
            if (dx > dy && dx > 10) e.preventDefault();
        };

        const onTouchEnd = (e: TouchEvent) => {
            if (!start) return;
            const t = e.changedTouches[0];
            const dx = t.clientX - start.x;
            const dy = t.clientY - start.y;
            start = null;

            if (Math.abs(dx) < MIN_SWIPE || Math.abs(dx) < Math.abs(dy)) return;

            e.preventDefault(); // prevent Chrome's back/forward navigation
            if (dx > 0) callbacksRef.current.onSwipeRight();
            else callbacksRef.current.onSwipeLeft();
        };

        el.addEventListener('touchstart', onTouchStart, { passive: false });
        el.addEventListener('touchmove', onTouchMove, { passive: false });
        el.addEventListener('touchend', onTouchEnd, { passive: false });

        return () => {
            el.removeEventListener('touchstart', onTouchStart);
            el.removeEventListener('touchmove', onTouchMove);
            el.removeEventListener('touchend', onTouchEnd);
        };
    }, [elementRef]);
}
