import { useCallback, useEffect, useRef } from 'react';
import { throttle } from '@reltio/mdm-sdk';
var SCROLL_MARGIN = 50;
var SPEED_MULTIPLIER = 25;
var UPDATE_DATA_INTERVAL = 100;
export var useScrollOnDrag = function (scrollContainer) {
    var scrolling = useRef(false);
    var running = useRef(false);
    var scrollData = useRef(null);
    var getIsScrolling = function () {
        return scrolling === null || scrolling === void 0 ? void 0 : scrolling.current;
    };
    var onStartDragging = function () {
        var container = scrollContainer === null || scrollContainer === void 0 ? void 0 : scrollContainer.current;
        if (container && typeof container.addEventListener === 'function') {
            container.addEventListener('dragover', updateScrollData);
            window.addEventListener('dragover', updateScrollData);
            running.current = true;
        }
    };
    var updateScrollData = useCallback(throttle(function (event) {
        var container = scrollContainer === null || scrollContainer === void 0 ? void 0 : scrollContainer.current;
        if (!container || !running.current)
            return;
        var holder = container.getElementsByClassName('rc-tree-list-holder')[0];
        var calcSpeed = function () {
            var clientY = event.clientY, clientX = event.clientX;
            var _a = container.getBoundingClientRect(), top = _a.top, bottom = _a.bottom, left = _a.left, right = _a.right;
            var maxScroll = holder.scrollHeight - holder.clientHeight;
            var insideContainer = clientY > top && clientY < bottom && clientX >= left && clientX <= right;
            if (insideContainer) {
                if (clientY - top < SCROLL_MARGIN && holder.scrollTop > 0) {
                    return (clientY - top - SCROLL_MARGIN) / SCROLL_MARGIN;
                }
                else if (bottom - clientY < SCROLL_MARGIN && holder.scrollTop < maxScroll) {
                    return -(bottom - clientY - SCROLL_MARGIN) / SCROLL_MARGIN;
                }
            }
            return 0;
        };
        if (holder) {
            scrollData.current = calcSpeed();
            if (scrollData.current) {
                runScrolling(holder);
            }
        }
    }, UPDATE_DATA_INTERVAL), []);
    var removeListeners = useCallback(function () {
        var container = scrollContainer === null || scrollContainer === void 0 ? void 0 : scrollContainer.current;
        if (container && typeof container.removeEventListener === 'function') {
            container.removeEventListener('dragover', updateScrollData);
        }
        window.removeEventListener('dragover', updateScrollData);
    }, [scrollContainer, updateScrollData]);
    var onEndDragging = useCallback(function () {
        scrolling.current = false;
        scrollData.current = null;
        running.current = false;
        removeListeners();
    }, [removeListeners]);
    var runScrolling = function (holder) {
        if (scrolling === null || scrolling === void 0 ? void 0 : scrolling.current) {
            return;
        }
        scrolling.current = true;
        var scroll = function () {
            if (scrolling.current && scrollData.current) {
                holder.scrollTop += scrollData.current * SPEED_MULTIPLIER;
                requestAnimationFrame(scroll);
            }
            else {
                scrolling.current = false;
            }
        };
        scroll();
    };
    useEffect(function () {
        return function () {
            removeListeners();
        };
    }, [removeListeners]);
    return { onStartDragging: onStartDragging, onEndDragging: onEndDragging, getIsScrolling: getIsScrolling };
};
