"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.SplitModeView = void 0;
const jsx_runtime_1 = require("react/jsx-runtime");
const react_1 = require("react");
const icons_1 = require("@gravity-ui/icons");
const uikit_1 = require("@gravity-ui/uikit");
const classname_1 = require("../classname.js");
const bundle_1 = require("../i18n/bundle/index.js");
const lodash_1 = require("../lodash.js");
const sync_scroll_1 = require("../utils/sync-scroll.js");
const b = (0, classname_1.cn)('markup-preview');
const SplitModeView = (0, react_1.forwardRef)(({ editor }, ref) => {
    const cm = editor.cm;
    const [, forceUpdate] = (0, react_1.useReducer)((x) => x + 1, 0);
    const outerRef = (0, react_1.useRef)(null);
    const lineElements = (0, react_1.useRef)([]);
    const updateLineElements = () => {
        if (!outerRef.current)
            return;
        const els = Array.from(outerRef.current.querySelectorAll('.line'));
        lineElements.current = els
            .filter((el) => el instanceof HTMLElement && el.parentElement?.offsetHeight !== 0)
            .map((el) => ({
            el: el,
            line: Number(el.getAttribute('data-line')),
        }));
    };
    const handleEditorScroll = (0, react_1.useMemo)(() => (0, lodash_1.throttle)(() => {
        if (!outerRef.current)
            return;
        if (!cm.dom.matches(':hover'))
            return;
        const { range } = cm.scrollSnapshot().value;
        const line = cm.state.doc.lineAt(range.from).number - 1;
        updateLineElements();
        (0, sync_scroll_1.scrollToRevealSourceLine)(line, lineElements.current, outerRef);
    }, 30), [cm]);
    const handlePreviewScroll = (0, react_1.useMemo)(() => (0, lodash_1.throttle)(() => {
        if (!outerRef.current)
            return;
        if (!outerRef.current.matches(':hover'))
            return;
        updateLineElements();
        let lineNumber = (0, sync_scroll_1.getEditorLineNumberForOffset)(outerRef.current.scrollTop, lineElements.current, outerRef);
        if (lineNumber === null || isNaN(lineNumber))
            return;
        lineNumber = Math.max(Math.floor(lineNumber), 0) + 1;
        const line = cm.state.doc.line(lineNumber);
        const { top } = cm.lineBlockAt(line.from);
        cm.scrollDOM.scrollTo({ top });
    }, 30), [cm]);
    (0, react_1.useEffect)(() => {
        const outer = outerRef.current;
        editor.on('change', forceUpdate);
        editor.on('cm-scroll', handleEditorScroll);
        outer?.addEventListener('scroll', handlePreviewScroll);
        editor.cm.requestMeasure();
        return () => {
            editor.off('change', forceUpdate);
            editor.off('cm-scroll', handleEditorScroll);
            outer?.removeEventListener('scroll', handlePreviewScroll);
        };
    }, [editor, handleEditorScroll, handlePreviewScroll]);
    (0, react_1.useImperativeHandle)(ref, () => outerRef.current);
    return ((0, jsx_runtime_1.jsxs)("div", { className: b('outer', {
            vertical: editor.splitMode === 'vertical',
        }), ref: outerRef, children: [(0, jsx_runtime_1.jsx)(uikit_1.Label, { icon: (0, jsx_runtime_1.jsx)(icons_1.Eye, {}), className: b('preview-sign'), size: 'm', children: (0, bundle_1.i18n)('split-mode-text') }), editor.renderPreview?.({
                getValue: editor.getValue,
                mode: 'split',
                md: editor.mdOptions,
                directiveSyntax: editor.directiveSyntax,
            })] }));
});
exports.SplitModeView = SplitModeView;
SplitModeView.displayName = 'SplitModeView';
//# sourceMappingURL=SplitModeView.js.map
