"use client";
import { Poster } from "./Poster";
import { sourceToFetcher } from "../libraries/Source";
import React, { useCallback, useEffect, useRef, useState } from "react";
import { Mutex } from "../libraries/Mutex";
import styles from "./Grid.module.css";
import { clsx } from "clsx";
function getDivPropsWithClassName(baseClassName, props) {
    const { className, ...rest } = props ?? {};
    return {
        className: clsx(baseClassName, className),
        ...rest
    };
}
/**
 * A grid of posters that fetches items from a source.
 * Provides infinite scrolling to fetch more items out of the box.
 *
 * You can set a height or append the Grid component to a parent with a height
 * to limit the height of the grid, as the grid will grow indefinitely (as long as the source has items)
 * and keep fetching more items.
 *
 * @category Components
 */
export function Grid(props) {
    const [items, setItems] = useState([]);
    const [fetching, setFetching] = useState(false);
    const [source, setSource] = useState(sourceToFetcher(props.source));
    const mutex = useRef(new Mutex());
    const parentRef = useRef(null);
    const childRef = useRef(undefined);
    const observer = useRef(null);
    const update = useCallback(() => {
        mutex.current.runExclusive(async () => {
            if (!source || fetching || !parentRef.current) {
                return;
            }
            if (!observer.current) {
                observer.current = new IntersectionObserver(update);
            }
            const childrenSize = parentRef.current.children.length;
            if (childrenSize !== 0) {
                const target = Math.max(Math.floor(childrenSize * 0.75), childrenSize - 100);
                const newElement = parentRef.current.children[target];
                if (childRef.current) {
                    if (childRef.current !== newElement) {
                        observer.current.unobserve(childRef.current);
                        childRef.current = newElement;
                        observer.current.observe(newElement);
                    }
                }
                else {
                    childRef.current = newElement;
                    observer.current.observe(newElement);
                }
                if (newElement.getBoundingClientRect().top > window.innerHeight) {
                    return;
                }
            }
            setFetching(true);
            const item = await source.fetch();
            if (item) {
                setItems((oldItems) => {
                    if (oldItems.map((oldItem) => oldItem.show.id).includes(item.show.id)) {
                        return oldItems;
                    }
                    return [...oldItems, item];
                });
            }
            else {
                setSource(() => undefined);
            }
            setFetching(false);
        });
    }, [fetching, source]);
    useEffect(() => {
        update();
    }, [update, items, fetching]);
    useEffect(() => {
        window.addEventListener('resize', update);
        return () => window.removeEventListener('resize', update);
    }, [update]);
    return (<div {...getDivPropsWithClassName(styles["root"], props.rootDivProps)} ref={parentRef}>
			{items.map((item, index) => {
            return (<Poster key={index} {...props} posterImageProps={{
                    ...props.posterImageProps,
                    onLoad: (e) => {
                        update();
                        if (props.posterImageProps?.onLoad) {
                            props.posterImageProps.onLoad(e);
                        }
                    },
                    className: clsx(styles["poster-image"], props.posterImageProps?.className),
                }} posterContainerAnchorProps={{
                    ...props.posterContainerAnchorProps,
                    className: clsx(styles["poster-root"], props.posterContainerAnchorProps?.className),
                }} highlightedChange={item.change} show={item.show} country={item.country} priorityCatalogs={[...item.priorityCatalogs ?? [], ...props.priorityCatalogs ?? []]} hidePosterIfNoStreamingOption={true}/>);
        })}
		</div>);
}
//# sourceMappingURL=Grid.jsx.map