"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.TooltipView = void 0;
const jsx_runtime_1 = require("react/jsx-runtime");
const react_1 = require("@floating-ui/react"); // eslint-disable-line import/no-extraneous-dependencies
const uikit_1 = require("@gravity-ui/uikit");
const lodash_1 = require("../../../lodash.js");
const logger_1 = require("../../../logger.js");
const ErrorBoundary_1 = require("../../../react-utils/ErrorBoundary.js");
const toolbar_1 = require("../../../toolbar/index.js");
const ReactRenderer_1 = require("../ReactRenderer/index.js");
const SelectionTooltip = ({ show, poppupProps, ...toolbarProps }) => {
    if (!show)
        return null;
    return ((0, jsx_runtime_1.jsx)(uikit_1.Popup, { open: true, ...poppupProps, style: { padding: '4px 8px' }, children: (0, jsx_runtime_1.jsx)(toolbar_1.Toolbar, { ...toolbarProps }) }));
};
class TooltipView {
    #isTooltipOpen = false;
    actions;
    menuConfig;
    view;
    baseProps = { show: false, poppupProps: {} };
    _tooltipRenderItem = null;
    constructor(actions, menuConfig) {
        this.actions = actions;
        this.menuConfig = menuConfig;
    }
    get isTooltipOpen() {
        return this.#isTooltipOpen;
    }
    show(view, popupProps) {
        this.view = view;
        this.#isTooltipOpen = true;
        this.baseProps = {
            show: true,
            poppupProps: {
                ...popupProps,
                ...this.calcPosition(view),
            },
        };
        this.renderPopup();
    }
    hide(view) {
        this.view = view;
        this.#isTooltipOpen = false;
        this.baseProps = { show: false, poppupProps: {} };
        this.renderPopup();
    }
    destroy() {
        this._tooltipRenderItem?.remove();
        this._tooltipRenderItem = null;
    }
    getSelectionTooltipProps() {
        return {
            ...this.baseProps,
            focus: () => this.view.focus(),
            data: this.getFilteredConfig(),
            editor: this.actions,
            onClick: (id) => logger_1.logger.action({ mode: 'wysiwyg', source: 'context-menu', action: id }),
        };
    }
    getFilteredConfig() {
        return this.baseProps.show
            ? this.menuConfig
                .map((groupData) => groupData.filter((item) => {
                const { condition } = item;
                if (condition === 'enabled') {
                    return item.isEnable(this.actions);
                }
                if ((0, lodash_1.isFunction)(condition)) {
                    return condition(this.view.state);
                }
                return true;
            }))
                .filter((groupData) => Boolean(groupData.length))
            : [];
    }
    renderPopup() {
        this.tooltipRenderItem.rerender();
    }
    get tooltipRenderItem() {
        if (!this._tooltipRenderItem) {
            const reactRenderer = (0, ReactRenderer_1.getReactRendererFromState)(this.view.state);
            this._tooltipRenderItem = reactRenderer.createItem('selection_context', () => ((0, jsx_runtime_1.jsx)(ErrorBoundary_1.ErrorLoggerBoundary, { children: (0, jsx_runtime_1.jsx)(SelectionTooltip, { ...this.getSelectionTooltipProps() }) })));
        }
        return this._tooltipRenderItem;
    }
    calcPosition(view) {
        const viewDom = view.dom;
        // The box in which the tooltip is positioned, to use as base
        const viewBox = viewDom.getBoundingClientRect();
        const viewWidth = viewBox.right - viewBox.left;
        const viewHalfWidth = viewWidth / 2;
        // These are in screen coordinates
        const start = view.coordsAtPos(view.state.selection.from);
        const end = view.coordsAtPos(view.state.selection.to);
        // Find a center-ish x position from the selection endpoints (when
        // crossing lines, end may be more to the left)
        const left = Math.max((start.left + end.left) / 2, start.left + 3);
        const leftOffset = left - (viewBox.left + viewHalfWidth);
        const bottomOffset = -(viewBox.bottom - end.bottom) + this.popupTextOffset;
        return {
            placement: 'bottom',
            anchorElement: viewDom,
            // override floating middlewares
            floatingMiddlewares: [
                (0, react_1.offset)({
                    mainAxis: bottomOffset,
                    crossAxis: leftOffset,
                }),
                (0, react_1.shift)({
                    mainAxis: true,
                    crossAxis: false,
                    padding: 4,
                }),
            ],
        };
    }
    get popupTextOffset() {
        return 4; // 4px offset from text selection
    }
}
exports.TooltipView = TooltipView;
//# sourceMappingURL=tooltip.js.map
