import { debounce } from '@astral/utils/debounce';
import { useLayoutEffect, useRef, useState } from 'react';
import { useFirstMountState } from '../../../useFirstMountState';
export const useOverflowed = (forwardedRef, hasMultipleRows = false, hasVisibleLastSymbols = false) => {
    const localRef = useRef(null);
    const ref = forwardedRef && typeof forwardedRef !== 'function'
        ? forwardedRef
        : localRef;
    const [isOverflowed, setOverflow] = useState(false);
    const isFirstMount = useFirstMountState();
    const checkOverflow = ([{ target, contentRect },]) => {
        // высота контента больше высоты контейнера -> переполнение
        const isScrollHeightBigger = target.scrollHeight > Math.round(contentRect.height);
        // ширина контента больше ширины контейнера -> переполнение
        const isScrollWidthBigger = target.scrollWidth > Math.round(contentRect.width);
        const newIsOverflowed = hasMultipleRows
            ? isScrollWidthBigger || isScrollHeightBigger
            : isScrollWidthBigger;
        // Обновляем состояние только если значение действительно изменилось
        setOverflow((prev) => (prev !== newIsOverflowed ? newIsOverflowed : prev));
    };
    useLayoutEffect(() => {
        const node = ref.current;
        if (!node) {
            return;
        }
        const resizeEntry = {
            target: node,
            contentRect: node.getBoundingClientRect(),
        };
        let resizeObserver = null;
        // Проверка через ResizeObserver при первом маунте должна быть отключена для элементов,
        // которые имеют hasVisibleLastSymbols (например GuidTypography, FileName) во избежания визуального подергивания
        if (hasVisibleLastSymbols && isFirstMount) {
            checkOverflow([resizeEntry]);
        }
        else {
            resizeObserver = new ResizeObserver(debounce(checkOverflow, 500));
            resizeObserver.observe(node);
        }
        //функция очистки должна обязательно возвращаться в теле хука, иначе она не вызывается
        return () => {
            resizeObserver?.unobserve(node);
        };
    }, [ref.current]);
    return { isOverflowed, ref };
};
