/**
 * useLazySection — Intersection Observer hook for rendering sections
 * only when they are near the viewport.
 *
 * Usage:
 *   const { ref, isVisible } = useLazySection({ rootMargin: "200px" });
 *   return (
 *     <div ref={ref}>
 *       {isVisible ? <ExpensiveSection /> : <Skeleton />}
 *     </div>
 *   );
 *
 * Options:
 *   rootMargin   — distance from viewport edge to trigger load (default "300px")
 *   threshold    — intersection threshold 0–1 (default 0)
 *   once         — once visible, stay visible forever (default true)
 *   fallback     — value to return while SSR/no-observer (default false)
 */

"use client";

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

interface Options {
  rootMargin?: string;
  threshold?:  number;
  once?:       boolean;
  fallback?:   boolean;
}

export function useLazySection({
  rootMargin = "300px",
  threshold  = 0,
  once       = true,
  fallback   = false,
}: Options = {}) {
  const ref            = useRef<HTMLDivElement | null>(null);
  const [isVisible, setIsVisible] = useState(fallback);
  const observerRef    = useRef<IntersectionObserver | null>(null);

  useEffect(() => {
    // SSR guard — IntersectionObserver doesn't exist server-side
    if (typeof IntersectionObserver === "undefined") {
      setIsVisible(true);
      return;
    }

    const el = ref.current;
    if (!el) return;

    // Already visible and `once` mode — no need to observe further
    if (isVisible && once) return;

    observerRef.current = new IntersectionObserver(
      ([entry]) => {
        if (entry.isIntersecting) {
          setIsVisible(true);
          if (once && observerRef.current) {
            observerRef.current.disconnect();
          }
        } else if (!once) {
          setIsVisible(false);
        }
      },
      { rootMargin, threshold },
    );

    observerRef.current.observe(el);

    return () => {
      observerRef.current?.disconnect();
    };
  // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [rootMargin, threshold, once]);

  return { ref, isVisible };
}
/**
 * useIntersection — raw IntersectionObserver hook.
 * Returns the IntersectionObserverEntry for fine-grained control.
 */
export function useIntersection(
  ref: React.RefObject<Element | null>,
  options?: IntersectionObserverInit,
) {
  const [entry, setEntry] = useState<IntersectionObserverEntry | null>(null);

  useEffect(() => {
    if (typeof IntersectionObserver === "undefined") return;
    const el = ref.current;
    if (!el) return;

    const observer = new IntersectionObserver(([e]) => setEntry(e), options);
    observer.observe(el);
    return () => observer.disconnect();
  }, [ref, options?.rootMargin, options?.threshold]); // eslint-disable-line

  return entry;
}

