import { RefObject, useEffect, useRef, useState } from 'react';

// https://rasilbaidar.medium.com/trigger-event-when-element-enters-viewport-the-react-way-168509da2e23
export const useIntersection = (element: RefObject<HTMLElement>, rootMargin: string) => {
  const [isVisible, setIsVisible] = useState(false);
  const observerRef = useRef<IntersectionObserver | null>(null);

  // Runs after every render so it catches when element.current transitions from null
  // to a mounted DOM node (e.g. when a conditionally-rendered element first appears).
  // Bails immediately once the observer is attached, keeping per-render cost O(1).
  useEffect(() => {
    const current = element?.current;
    console.debug('[useIntersection] effect ran', {
      elementCurrent: current,
      rootMargin,
      alreadyObserving: !!observerRef.current,
    });

    if (!current) {
      console.debug('[useIntersection] element.current is null — observer NOT attached');
      return;
    }
    if (observerRef.current) return; // already observing

    const observer = new IntersectionObserver(
      ([entry]) => {
        console.debug('[useIntersection] IntersectionObserver fired', {
          isIntersecting: entry.isIntersecting,
          intersectionRatio: entry.intersectionRatio,
          boundingClientRect: entry.boundingClientRect,
          target: entry.target,
        });
        setIsVisible(entry.isIntersecting);
      },
      { rootMargin },
    );

    observer.observe(current);
    observerRef.current = observer;
    console.debug('[useIntersection] observer attached to element', current);
  });

  // Disconnect on unmount only — intentionally separate from the setup effect above.
  useEffect(() => {
    return () => {
      observerRef.current?.disconnect();
      observerRef.current = null;
    };
  }, []);

  return isVisible;
};
