"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const jsx_runtime_1 = require("react/jsx-runtime");
const React = tslib_1.__importStar(require("react"));
const icons_1 = require("@gravity-ui/icons");
const uikit_1 = require("@gravity-ui/uikit");
const lodash_1 = tslib_1.__importDefault(require("lodash"));
const postMessage_1 = require("../../../common/postMessage.js");
const editor_1 = require("../../../utils/editor.js");
const useMainEditorStore_1 = require("../../hooks/useMainEditorStore.js");
const cn_1 = require("../../utils/cn.js");
const b = (0, cn_1.editorCn)('overlay');
const findRectByPath = (rectMap, path) => {
    if (!path)
        return null;
    return rectMap.find((entry) => lodash_1.default.isEqual(entry.path, path))?.rect ?? null;
};
const Overlay = ({ className, canvasElement }) => {
    const { rectMap, setRectMap, selectedBlock, setSelectedBlock, deleteBlock, duplicateBlock, manipulateOverlayMode, preInsertBlockType, preReorderBlockPath, insertBlock, reorderBlock, disableMode, } = (0, useMainEditorStore_1.useMainEditorStore)();
    const [hoveredPath, setHoveredPath] = React.useState(null);
    const [insertPosition, setInsertPosition] = React.useState(null);
    (0, postMessage_1.usePostMessageAPIListener)('ON_UPDATE_RECT_MAP', ({ rects }) => {
        setRectMap(rects);
    }, [setRectMap]);
    const selectedRect = React.useMemo(() => findRectByPath(rectMap, selectedBlock), [rectMap, selectedBlock]);
    const hoveredRect = React.useMemo(() => findRectByPath(rectMap, hoveredPath), [rectMap, hoveredPath]);
    // Auto-scroll to selected block when it changes
    React.useEffect(() => {
        if (selectedRect && canvasElement) {
            const canvasHeight = canvasElement.clientHeight;
            const scrollPosition = selectedRect.top - canvasHeight / 2 + selectedRect.height / 2;
            canvasElement.scrollTo({
                top: Math.max(0, scrollPosition),
                behavior: 'smooth',
            });
        }
        // Intentionally depends on selectedBlock identity (path), not rect value, to avoid scroll jitter on rect updates.
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [selectedBlock, canvasElement]);
    const handleClick = React.useCallback((path) => {
        if (selectedBlock && lodash_1.default.isEqual(selectedBlock, path)) {
            setSelectedBlock(null);
        }
        else {
            setSelectedBlock(path);
        }
    }, [selectedBlock, setSelectedBlock]);
    const handleMouseEnter = React.useCallback((path) => {
        setHoveredPath(path);
    }, []);
    const handleMouseLeave = React.useCallback((path) => {
        setHoveredPath((current) => (lodash_1.default.isEqual(current, path) ? null : current));
    }, []);
    const handleMouseMove = React.useCallback((e) => {
        if (!manipulateOverlayMode) {
            return;
        }
        const domRect = e.currentTarget.getBoundingClientRect();
        const position = (0, editor_1.getCursorPositionOverElement)(domRect, e);
        setInsertPosition(position);
    }, [manipulateOverlayMode]);
    const handleKeyDown = React.useCallback((e, path) => {
        if (e.key === 'Enter' || e.key === ' ') {
            e.stopPropagation();
            handleClick(path);
        }
    }, [handleClick]);
    const handleMouseUp = React.useCallback((path) => {
        if (!manipulateOverlayMode)
            return;
        const position = insertPosition;
        const prepend = position === 'left' || position === 'top';
        if (manipulateOverlayMode === 'insert' && preInsertBlockType) {
            insertBlock(path, preInsertBlockType, prepend ? 'prepend' : 'append');
        }
        else if (manipulateOverlayMode === 'reorder' && preReorderBlockPath) {
            reorderBlock(preReorderBlockPath, path, prepend ? 'prepend' : 'append');
        }
        disableMode();
        setInsertPosition(null);
    }, [
        manipulateOverlayMode,
        preInsertBlockType,
        preReorderBlockPath,
        insertBlock,
        reorderBlock,
        disableMode,
        insertPosition,
    ]);
    const handleMoveUp = () => {
        if (!selectedBlock)
            return;
        const destination = [...selectedBlock];
        const newLastDestination = destination[destination.length - 1] - 1;
        if (newLastDestination < 0) {
            return;
        }
        destination[destination.length - 1] = newLastDestination;
        reorderBlock(selectedBlock, destination, 'prepend');
    };
    const handleMoveDown = () => {
        if (!selectedBlock)
            return;
        const destination = [...selectedBlock];
        const newLastDestination = destination[destination.length - 1] + 1;
        destination[destination.length - 1] = newLastDestination;
        reorderBlock(selectedBlock, destination, 'append');
    };
    const showHoverBorder = hoveredRect && (!selectedBlock || !lodash_1.default.isEqual(hoveredPath, selectedBlock));
    return ((0, jsx_runtime_1.jsxs)("div", { className: b(null, className), children: [rectMap.map(({ path, rect, dropZone }) => {
                const key = path.join('.');
                return ((0, jsx_runtime_1.jsx)("div", { role: dropZone ? 'presentation' : 'button', tabIndex: dropZone ? -1 : 0, className: b('hit'), style: {
                        top: rect.top,
                        left: rect.left,
                        width: rect.width,
                        height: rect.height,
                        zIndex: 10 * (path.length + (dropZone ? 0 : 1)),
                    }, onClick: dropZone
                        ? undefined
                        : (e) => {
                            e.stopPropagation();
                            handleClick(path);
                        }, onKeyDown: dropZone ? undefined : (e) => handleKeyDown(e, path), onMouseEnter: () => handleMouseEnter(path), onMouseLeave: () => handleMouseLeave(path), onMouseMove: (e) => handleMouseMove(e), onMouseUp: () => handleMouseUp(path) }, key));
            }), selectedRect ? ((0, jsx_runtime_1.jsx)("div", { className: b('border'), style: {
                    top: selectedRect.top,
                    left: selectedRect.left,
                    width: selectedRect.width,
                    height: selectedRect.height,
                }, children: (0, jsx_runtime_1.jsxs)("div", { className: b('actions'), children: [(0, jsx_runtime_1.jsx)("div", { className: b('actions-box', { reorder: true }), children: (0, jsx_runtime_1.jsx)(uikit_1.Button, { view: "flat", size: 'm', onClick: handleMoveUp, children: (0, jsx_runtime_1.jsx)(uikit_1.Icon, { className: b('reorder-icon'), data: icons_1.ChevronUp, size: 18 }) }) }), (0, jsx_runtime_1.jsxs)("div", { className: b('actions-box', { main: true }), children: [(0, jsx_runtime_1.jsx)(uikit_1.Button, { className: b('action-button'), size: 'm', view: 'action', onClick: () => selectedBlock && duplicateBlock(selectedBlock), children: (0, jsx_runtime_1.jsx)(uikit_1.Icon, { data: icons_1.Copy, size: 18 }) }), (0, jsx_runtime_1.jsx)(uikit_1.Button, { className: b('action-button'), size: 'm', view: 'action', onClick: () => selectedBlock && deleteBlock(selectedBlock), children: (0, jsx_runtime_1.jsx)(uikit_1.Icon, { data: icons_1.TrashBin, size: 18 }) })] }), (0, jsx_runtime_1.jsx)("div", { className: b('actions-box', { reorder: true }), children: (0, jsx_runtime_1.jsx)(uikit_1.Button, { view: "flat", size: 'm', onClick: handleMoveDown, children: (0, jsx_runtime_1.jsx)(uikit_1.Icon, { className: b('reorder-icon'), data: icons_1.ChevronDown, size: 18 }) }) })] }) })) : null, showHoverBorder ? ((0, jsx_runtime_1.jsx)("div", { className: b('border', { hover: true }), style: {
                    top: hoveredRect.top,
                    left: hoveredRect.left,
                    width: hoveredRect.width,
                    height: hoveredRect.height,
                } })) : null, manipulateOverlayMode && hoveredRect && insertPosition ? ((0, jsx_runtime_1.jsx)("div", { className: b('line', { position: insertPosition }), style: {
                    top: hoveredRect.top,
                    left: hoveredRect.left,
                    width: hoveredRect.width,
                    height: hoveredRect.height,
                } })) : null] }));
};
exports.default = Overlay;
//# sourceMappingURL=Overlay.js.map
