import { jsx as _jsx } from "react/jsx-runtime";
import throttle from "lodash/throttle";
import { useEffect, useState } from "react";
import Fade from "../../components/FadeIn";
import { useOneUIConfig } from "../../context/OneUIProvider";
import Styles from "./usePaginationControls.module.scss";
import { isSameTarget } from "../../utils/html.utils";
/**
 * This hook handles the display of pagination controls for the user to move to another page
 */
export default function usePaginationControls(containerRef, { snapToPage, baseWidth, snapToCutElement: _snapToCutElement, ...props } = {}) {
    const [controlsState, setControls] = useState([false, false]);
    const [leftControl, rightControl] = controlsState;
    const LeftControl = useOneUIConfig("hook.ui.usePaginationControls.LeftControl");
    const RightControl = useOneUIConfig("hook.ui.usePaginationControls.RightControl");
    const className = useOneUIConfig("hook.ui.usePaginationControls.className", "");
    function move(direction, snapToCutElement = _snapToCutElement) {
        return () => {
            if (snapToCutElement ?? false) {
                const childBaseWidth = baseWidth || containerRef.current.firstElementChild.clientWidth;
                const howMuchDoesTheScrollAddsUpTo = containerRef.current.scrollLeft / childBaseWidth -
                    Math.floor((containerRef.current.scrollLeft + (direction === "l" ? -1 : 0)) /
                        childBaseWidth);
                const howMuchElementsFitOnAPage = containerRef.current.clientWidth / childBaseWidth;
                const howMuchElementsFullyFitOnAPage = Math.floor(howMuchElementsFitOnAPage) || 1;
                const directionScale = direction === "l"
                    ? 1 - howMuchDoesTheScrollAddsUpTo
                    : howMuchDoesTheScrollAddsUpTo;
                const howMuchOfTheRemainingElementIsShown = howMuchElementsFitOnAPage +
                    directionScale -
                    howMuchElementsFullyFitOnAPage;
                const howMuchToScroll = (containerRef.current.clientWidth -
                    childBaseWidth * howMuchOfTheRemainingElementIsShown) *
                    (direction === "l" ? -1 : 1);
                containerRef.current.scrollBy({
                    left: howMuchToScroll,
                    behavior: "smooth",
                });
            }
            else {
                const rest = Math.round(containerRef.current.scrollLeft) %
                    containerRef.current.clientWidth;
                const snapOffset = snapToPage
                    ? direction === "l"
                        ? rest
                            ? containerRef.current.clientWidth - rest
                            : 0
                        : rest
                    : 0;
                containerRef.current.scrollBy({
                    left: (containerRef.current.clientWidth - snapOffset) *
                        (direction === "l" ? -1 : 1),
                    behavior: "smooth",
                });
            }
        };
    }
    function checkControlsRequirement() {
        const updateFunc = (next) => (prev) => {
            if (prev[0] !== next[0] || prev[1] !== next[1])
                return next;
            return prev;
        };
        const el = containerRef.current;
        if (!el)
            return;
        const shouldHaveAnyControl = el.scrollWidth > el.clientWidth;
        if (!shouldHaveAnyControl)
            setControls(updateFunc([false, false]));
        else {
            const shouldHaveRightControl = el.scrollLeft < el.scrollWidth - el.clientWidth;
            const shouldHaveLeftControl = el.scrollLeft > 0;
            setControls(updateFunc([shouldHaveLeftControl, shouldHaveRightControl]));
        }
    }
    useEffect(() => {
        const el = containerRef.current;
        const throttledCheck = throttle(checkControlsRequirement, 1000 / 4);
        checkControlsRequirement();
        let startingX;
        let lastX;
        const onTouchStart = ({ touches, ...e }) => {
            if (!isSameTarget(e))
                return;
            const { pageX } = touches.item(0);
            startingX = pageX;
        };
        const onTouchMove = ({ touches, ...e }) => {
            if (!isSameTarget(e))
                return;
            const touch = touches.item(0);
            lastX = touch.pageX;
        };
        const onTouchEnd = (e) => {
            if (!lastX)
                return;
            const dir = lastX > startingX ? "l" : "r";
            move(dir, true)();
            startingX = undefined;
        };
        el.addEventListener("scroll", throttledCheck, {
            passive: true,
        });
        el.addEventListener("touchstart", onTouchStart);
        el.addEventListener("touchend", onTouchEnd);
        el.addEventListener("touchmove", onTouchMove);
        return () => {
            el.removeEventListener("scroll", throttledCheck);
            el.removeEventListener("touchstart", onTouchStart);
            el.removeEventListener("touchend", onTouchEnd);
            el.removeEventListener("touchend", onTouchEnd);
        };
    }, []);
    return {
        controls: [
            _jsx(Fade, { active: leftControl, className: `${Styles.left} ${Styles.control} ${className}`, "data-testid": props["data-testid"]?.[0], onClick: move("l"), children: leftControl && _jsx(LeftControl, {}) }, "l"),
            _jsx(Fade, { active: rightControl, className: `${Styles.right} ${Styles.control} ${className}`, "data-testid": props["data-testid"]?.[1], onClick: move("r"), children: rightControl && _jsx(RightControl, {}) }, "r"),
        ],
        checkControlsRequirement,
    };
}
//# sourceMappingURL=usePaginationControls.js.map