import { useEffect, useRef, useCallback } from 'react';
import { useDragLayer } from 'react-dnd';
const SCROLL_ZONE_SIZE = 20;
const SCROLL_SPEED = 10;
const useDragLayerAutoScroll = (containerRef) => {
    const { isDragging, currentOffset } = useDragLayer(monitor => ({
        isDragging: monitor.isDragging(),
        currentOffset: monitor.getClientOffset(),
    }));
    const animationFrame = useRef(null);
    const getScrollContainer = useCallback(() => {
        if (!containerRef || !containerRef.current) {
            return window;
        }
        // Find scrollable parent
        let node = containerRef.current.parentElement;
        while (node && node !== document.body) {
            const overflowY = window.getComputedStyle(node).overflowY;
            const isScrollable = overflowY === 'auto' || overflowY === 'scroll';
            if (isScrollable && node.scrollHeight > node.clientHeight) {
                return node;
            }
            node = node.parentElement;
        }
        return window;
    }, [containerRef]);
    const scroll = useCallback(() => {
        if (!isDragging || !currentOffset) {
            animationFrame.current = requestAnimationFrame(scroll);
            return;
        }
        const container = getScrollContainer();
        if (!container) {
            animationFrame.current = requestAnimationFrame(scroll);
            return;
        }
        const { y } = currentOffset;
        let scrollChange = 0;
        if (container === window) {
            const viewportHeight = window.innerHeight;
            if (y < SCROLL_ZONE_SIZE) {
                scrollChange = -SCROLL_SPEED;
            }
            else if (y > viewportHeight - SCROLL_ZONE_SIZE) {
                scrollChange = SCROLL_SPEED;
            }
            if (scrollChange !== 0) {
                window.scrollBy(0, scrollChange);
            }
            animationFrame.current = requestAnimationFrame(scroll);
        }
        else if (container instanceof HTMLElement) {
            const rect = container.getBoundingClientRect();
            if (y < rect.top + SCROLL_ZONE_SIZE) {
                scrollChange = -SCROLL_SPEED;
            }
            else if (y > rect.bottom - SCROLL_ZONE_SIZE) {
                scrollChange = SCROLL_SPEED;
            }
            if (scrollChange !== 0) {
                container.scrollTop += scrollChange;
            }
            animationFrame.current = requestAnimationFrame(scroll);
        }
    }, [isDragging, currentOffset, getScrollContainer]);
    useEffect(() => {
        if (isDragging) {
            animationFrame.current = requestAnimationFrame(scroll);
        }
        else {
            if (animationFrame.current) {
                cancelAnimationFrame(animationFrame.current);
                animationFrame.current = null;
            }
        }
        return () => {
            if (animationFrame.current) {
                cancelAnimationFrame(animationFrame.current);
                animationFrame.current = null;
            }
        };
    }, [isDragging, scroll]);
    return null;
};
export { useDragLayerAutoScroll };
const AutoScroller = ({ containerRef }) => {
    useDragLayerAutoScroll(containerRef);
    return null;
};
export default AutoScroller;
//# sourceMappingURL=AutoScroller.js.map