"use client";

import React, { useEffect, useRef } from "react";

interface Options {
  /** Whether more pages exist */
  hasMore: boolean;
  /** Whether a page fetch is in progress */
  isLoading: boolean;
  /** Callback fired when the sentinel enters the viewport */
  onLoadMore: () => void;
  /** Optional scrolling container (defaults to viewport) */
  rootRef?: React.RefObject<Element>;
  /** IntersectionObserver root margin (default "0px") */
  rootMargin?: string;
  /** IntersectionObserver threshold (default 0.1) */
  threshold?: number;
}

/**
 * Attaches an IntersectionObserver to a sentinel element.
 * Calls `onLoadMore` when the sentinel is visible and more data exists.
 * Returns a `ref` to attach to the sentinel div.
 *
 * Replaces 12+ identical IntersectionObserver blocks across the codebase.
 */
export function useInfiniteScroll({
  hasMore,
  isLoading,
  onLoadMore,
  rootRef,
  rootMargin = "0px",
  threshold = 0.1,
}: Options) {
  const sentinelRef = useRef<HTMLDivElement>(null);

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

    const obs = new IntersectionObserver(
      ([entry]) => {
        if (entry.isIntersecting && hasMore && !isLoading) {
          onLoadMore();
        }
      },
      { root: rootRef?.current ?? null, rootMargin, threshold },
    );

    obs.observe(el);
    return () => obs.disconnect();
  }, [hasMore, isLoading, onLoadMore, rootRef, rootMargin, threshold]);

  return sentinelRef;
}
