import { useEffect, useRef } from 'preact/hooks';

/**
 * useInfiniteScroll (core hook)
 * Calls onLoadMore when the user scrolls near the bottom of a scroll container.
 *
 * Keep the DOM listener stable: provider panels can re-render often while images load,
 * and re-attaching + immediately checking on every render can trigger request storms
 * and unnecessary work in image-heavy modules such as Pixabay.
 */
export function useInfiniteScroll(
  container: HTMLElement | null,
  onLoadMore: () => void,
  opts?: { thresholdPx?: number; enabled?: boolean; initialCheck?: boolean },
) {
  const thresholdPx = opts?.thresholdPx ?? 180;
  const enabled = opts?.enabled ?? true;
  const initialCheck = opts?.initialCheck ?? false;
  const callbackRef = useRef(onLoadMore);
  const rafRef = useRef<number | null>(null);

  useEffect(() => {
    callbackRef.current = onLoadMore;
  }, [onLoadMore]);

  useEffect(() => {
    if (!container || !enabled) return;

    const el = container;
    let disposed = false;

    const check = () => {
      rafRef.current = null;
      if (disposed) return;
      const nearBottom = el.scrollTop + el.clientHeight >= el.scrollHeight - thresholdPx;
      if (nearBottom) callbackRef.current?.();
    };

    const scheduleCheck = () => {
      if (rafRef.current != null) return;
      rafRef.current = window.requestAnimationFrame(check);
    };

    el.addEventListener('scroll', scheduleCheck, { passive: true });

    // Avoid auto-loading extra pages on mount by default. Panels can opt in with
    // initialCheck if they truly need it.
    if (initialCheck) scheduleCheck();

    return () => {
      disposed = true;
      el.removeEventListener('scroll', scheduleCheck);
      if (rafRef.current != null) {
        window.cancelAnimationFrame(rafRef.current);
        rafRef.current = null;
      }
    };
  }, [container, enabled, thresholdPx, initialCheck]);
}
