import React from "react";

type Param = {
    elementRef?: React.MutableRefObject<Element | undefined>;
    className?: string;
    options?: IntersectionObserverInit;
    removeIntersected?: boolean;
};

export default function useIntersectionObserver({
    elementRef,
    className,
    options,
    removeIntersected,
}: Param) {
    const [isIntersecting, setIsIntersecting] = React.useState(false);
    const [refresh, setRefresh] = React.useState(0);

    const observerCallback: IntersectionObserverCallback = React.useCallback(
        (entries, observer) => {
            const entry = entries[0];

            if (entry.isIntersecting) {
                setIsIntersecting(true);

                if (removeIntersected) {
                    observer.unobserve(entry.target);
                }
            } else {
                setIsIntersecting(false);
            }
        },
        []
    );

    React.useEffect(() => {
        const element = elementRef?.current;
        const elements = className
            ? document.querySelectorAll(`.${className}`)
            : null;

        if (!element && !className && refresh < 5) {
            requestAnimationFrame(() => {
                setTimeout(() => {
                    setRefresh(refresh + 1);
                }, 2000);
            });
            return;
        }

        const observer = new IntersectionObserver(observerCallback, {
            rootMargin: "0px 0px 0px 0px",
            ...options,
        });

        if (elements) {
            elements.forEach((el) => {
                observer.observe(el);
            });
        } else if (element) {
            observer.observe(element);
        }
    }, [refresh]);

    return { isIntersecting };
}
