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

interface UsePullToRefreshOptions {
  onRefresh: () => void;
  threshold?: number;
  maxPull?: number;
  enabled?: boolean;
}

interface UsePullToRefreshResult {
  containerRef: React.RefObject<HTMLDivElement | null>;
  pullDistance: number;
  isRefreshing: boolean;
  setIsRefreshing: React.Dispatch<React.SetStateAction<boolean>>;
}

/**
 * Touch gesture hook for pull-to-refresh functionality.
 * Mirrors SwipeToArchive.tsx convention — native DOM events, not React synthetic.
 */
export function usePullToRefresh({
  onRefresh,
  threshold = 64,
  maxPull = 96,
  enabled = true,
}: UsePullToRefreshOptions): UsePullToRefreshResult {
  const containerRef = useRef<HTMLDivElement | null>(null);
  const startYRef = useRef<number>(0);
  const [pullDistance, setPullDistance] = useState(0);
  const [isRefreshing, setIsRefreshing] = useState(false);

  const handleTouchStart = useCallback(
    (e: TouchEvent) => {
      if (!enabled || isRefreshing) return;
      // Only capture touch if we're at the top of the scroll container
      if (containerRef.current?.scrollTop !== 0) return;
      startYRef.current = e.touches[0]!.clientY;
    },
    [enabled, isRefreshing],
  );

  const handleTouchMove = useCallback(
    (e: TouchEvent) => {
      if (!enabled || isRefreshing || startYRef.current === 0) return;
      const dy = e.touches[0]!.clientY - startYRef.current;
      if (dy > 0) {
        setPullDistance(Math.min(dy, maxPull));
      }
    },
    [enabled, isRefreshing, maxPull],
  );

  const handleTouchEnd = useCallback(() => {
    if (!enabled || isRefreshing) return;
    if (pullDistance >= threshold) {
      // Haptic feedback if available
      navigator.vibrate?.(10);
      setIsRefreshing(true);
      onRefresh();
      // Reset pull distance but keep isRefreshing until caller resolves
      setPullDistance(0);
    } else {
      setPullDistance(0);
    }
    startYRef.current = 0;
  }, [enabled, isRefreshing, pullDistance, threshold, onRefresh]);

  useEffect(() => {
    const el = containerRef.current;
    if (!el || !enabled) return;

    el.addEventListener("touchstart", handleTouchStart, { passive: true });
    el.addEventListener("touchmove", handleTouchMove, { passive: true });
    el.addEventListener("touchend", handleTouchEnd);
    el.addEventListener("touchcancel", handleTouchEnd);

    return () => {
      el.removeEventListener("touchstart", handleTouchStart);
      el.removeEventListener("touchmove", handleTouchMove);
      el.removeEventListener("touchend", handleTouchEnd);
      el.removeEventListener("touchcancel", handleTouchEnd);
    };
  }, [enabled, handleTouchStart, handleTouchMove, handleTouchEnd]);

  return { containerRef, pullDistance, isRefreshing, setIsRefreshing };
}
