import { useEffect, useState } from 'react';
import throttle from "lodash/throttle.js";
import { useBooleanState } from "./hooks.js";
const RESIZE_DELAY = 50;
const MIN_WIDTH = 40;
const THRESHOLD = 4;
export const useNodeResizing = ({ width, height, onResize, ref, delay = RESIZE_DELAY, threshold = THRESHOLD, minWidth = MIN_WIDTH, }) => {
    const state = useBooleanState(false);
    const [resizing, , , toggleResizing] = state;
    const [initialWidth, setInitialWidth] = useState(width);
    const [initialHeight, setInitialHeight] = useState(height);
    const [currentWidth, setCurrentWidth] = useState(width);
    const [currentHeight, setCurrentHeight] = useState(height);
    // The dimensions specified as arguments take primacy over
    // the dimensions detected during the mouse movement.
    useEffect(() => {
        if (width !== initialWidth) {
            setCurrentWidth(width);
            setInitialWidth(width);
        }
        if (height !== initialHeight) {
            setCurrentHeight(height);
            setInitialHeight(height);
        }
    }, [width, height, initialWidth, initialHeight]);
    const startResizing = (event, direction) => {
        // prohibit the selection of text and other artifacts when resizing.
        event.preventDefault();
        const element = ref?.current;
        if (!element) {
            throw new Error('Reference element not found!');
        }
        const startX = event.pageX;
        const startWidth = element.getBoundingClientRect().width || 0;
        const startHeight = element.getBoundingClientRect().height || 0;
        let animationFrameId;
        const handleMouseMove = throttle((event) => {
            if (animationFrameId) {
                cancelAnimationFrame(animationFrameId);
            }
            animationFrameId = requestAnimationFrame(() => {
                const currentX = event.pageX;
                const diffX = currentX - startX;
                const newWidthByDirection = direction === 'right' ? startWidth + diffX : startWidth - diffX;
                if (Math.abs(newWidthByDirection - startWidth) >= threshold) {
                    const newWidth = newWidthByDirection >= minWidth ? newWidthByDirection : minWidth;
                    const newHeight = (startHeight / startWidth) * newWidth;
                    setCurrentWidth(newWidth);
                    setCurrentHeight(newHeight);
                    // If neither width nor height are provided, the width is set automatically.
                    const shouldSetWidth = !initialWidth &&
                        initialWidth !== 0 &&
                        !(initialWidth === null && initialHeight === null);
                    const shouldSetHeight = !initialHeight && initialHeight !== 0;
                    onResize?.({
                        width: shouldSetWidth ? undefined : newWidth,
                        height: shouldSetHeight ? undefined : newHeight,
                    });
                }
            });
        }, delay);
        const handleMouseUp = () => {
            document.removeEventListener('mousemove', handleMouseMove);
            document.removeEventListener('mouseup', handleMouseUp);
            toggleResizing();
            if (animationFrameId) {
                cancelAnimationFrame(animationFrameId);
            }
        };
        document.addEventListener('mousemove', handleMouseMove);
        document.addEventListener('mouseup', handleMouseUp);
        toggleResizing();
    };
    return {
        startResizing,
        state: {
            resizing,
            width: !initialWidth && initialWidth !== 0 ? undefined : currentWidth,
            height: !initialHeight && initialHeight !== 0 ? undefined : currentHeight,
        },
    };
};
//# sourceMappingURL=useNodeResizing.js.map
