import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import * as React from 'react';
import debounce from "lodash/debounce.js";
import first from "lodash/first.js";
import minBy from "lodash/minBy.js";
import { SSRContext } from "../../gravity-blocks/context/ssrContext/index.js";
import { block, getQaAttrubutes } from "../../utils/index.js";
import './BalancedMasonry.css';
const b = block('BalancedMasonry');
const BalancedMasonry = (props) => {
    const { className, columnClassName, children = [], breakpointCols, qa } = props;
    const qaAttributes = getQaAttrubutes(qa, 'column');
    const { isServer } = React.useContext(SSRContext);
    const getCurrentColumnsCount = React.useCallback(() => {
        const breakpoints = Object.entries(breakpointCols).sort(([firstBreakpoint], [secondBreakpoint]) => {
            return Number(secondBreakpoint) - Number(firstBreakpoint);
        });
        // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
        let [, result] = first(breakpoints);
        if (isServer) {
            return result;
        }
        for (const [rawWidth, columnCount] of breakpoints) {
            const width = Number(rawWidth);
            if (document?.body.clientWidth <= width) {
                result = columnCount;
            }
        }
        return result;
    }, [breakpointCols, isServer]);
    const [columnCount, setColumnCount] = React.useState(getCurrentColumnsCount());
    const [columns, setColumns] = React.useState([]);
    const containerRef = React.useRef(null);
    // eslint-disable-next-line react-hooks/exhaustive-deps
    const balanceColumns = React.useCallback(debounce(() => {
        if (!containerRef.current) {
            return;
        }
        const localColumns = [];
        const columnsMeta = [];
        for (let i = 0; i < columnCount; i++) {
            columnsMeta.push({ id: i, height: 0 });
            localColumns.push([]);
        }
        for (let i = 0; i < containerRef.current.children.length; i++) {
            const node = containerRef.current.children.item(i);
            if (!node) {
                continue;
            }
            const minColumn = minBy(columnsMeta, 'height') || { id: 0, height: 0 };
            const { id: columnId } = minColumn;
            localColumns[columnId].push(children[i]);
            minColumn.height += node.offsetHeight;
        }
        setColumns(localColumns);
    }, 300), [children, columnCount]);
    React.useEffect(() => {
        balanceColumns();
    }, [balanceColumns, children, columnCount]);
    React.useEffect(() => {
        const updateColumnCounter = () => setColumnCount(getCurrentColumnsCount());
        window.addEventListener('resize', updateColumnCounter, { passive: true });
        return () => window.removeEventListener('resize', updateColumnCounter);
    }, [setColumnCount, columns, getCurrentColumnsCount]);
    React.useEffect(() => {
        const currentRef = containerRef.current;
        const isResizeEventsSupported = 'ResizeObserver' in window;
        if (!currentRef || !isResizeEventsSupported) {
            return () => { };
        }
        const observer = new ResizeObserver(balanceColumns);
        for (let i = 0; i < currentRef.children.length; i++) {
            const node = currentRef.children.item(i);
            if (!node) {
                continue;
            }
            observer.observe(node);
        }
        return () => observer.disconnect();
    }, [balanceColumns, children]);
    return (_jsxs("div", { className: b(null, className), "data-qa": qa, children: [_jsx("div", { className: b('hidden-container'), style: { width: `${100 / columnCount}%` }, children: _jsx("div", { ref: containerRef, className: b('hidden-list'), children: children }) }), columns.map((columnElements, index) => (_jsx("div", { className: columnClassName, style: { width: `${100 / columnCount}%` }, "data-qa": qaAttributes.column, children: columnElements }, index)))] }));
};
export default BalancedMasonry;
//# sourceMappingURL=BalancedMasonry.js.map
