"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.MarkdownEditorView = exports.cnEditorComponent = void 0;
const jsx_runtime_1 = require("react/jsx-runtime");
const react_1 = require("react");
const uikit_1 = require("@gravity-ui/uikit");
const react_error_boundary_1 = require("react-error-boundary");
const react_use_1 = require("react-use");
const classname_1 = require("../classname.js");
const bundle_1 = require("../i18n/bundle/index.js");
const logger_1 = require("../logger.js");
const react_utils_1 = require("../react-utils/index.js");
const utils_1 = require("../utils/index.js");
const HorizontalDrag_1 = require("./HorizontalDrag.js");
const MarkupEditorView_1 = require("./MarkupEditorView.js");
const SplitModeView_1 = require("./SplitModeView.js");
const WysiwygEditorView_1 = require("./WysiwygEditorView.js");
const context_1 = require("./context.js");
const settings_1 = require("./settings/index.js");
const sticky_1 = require("./sticky/index.js");
const toolbarsConfigs_1 = require("./toolbar/utils/toolbarsConfigs.js");
require("../styles/styles.css");
require("./MarkdownEditorView.css"); // eslint-disable-line import/order
exports.cnEditorComponent = (0, classname_1.cn)('editor-component');
const b = exports.cnEditorComponent;
exports.MarkdownEditorView = (0, react_1.forwardRef)((props, ref) => {
    const divRef = (0, react_use_1.useEnsuredForwardedRef)(ref);
    const [isMounted, setIsMounted] = (0, react_1.useState)(false);
    (0, react_1.useEffect)(() => {
        setIsMounted(true);
    }, []);
    const [showPreview, , unsetShowPreview, toggleShowPreview] = (0, react_utils_1.useBooleanState)(false);
    const context = (0, context_1.useMarkdownEditorContext)();
    const editor = (props.editor ?? context);
    if (!editor)
        throw new Error('[MarkdownEditorView]: an instance of the editor must be passed through the props or context');
    const { qa, autofocus, className, settingsVisible = true, toolbarsPreset, stickyToolbar, wysiwygToolbarConfig: initialWysiwygToolbarConfig, markupToolbarConfig: initialMarkupToolbarConfig, wysiwygHiddenActionsConfig: initialWysiwygHiddenActionsConfig, markupHiddenActionsConfig: initialMarkupHiddenActionsConfig, enableSubmitInPreview = true, hidePreviewAfterSubmit = false, } = props;
    const { wysiwygToolbarConfig, markupToolbarConfig, wysiwygHiddenActionsConfig, markupHiddenActionsConfig, } = (0, react_1.useMemo)(() => (0, toolbarsConfigs_1.getToolbarsConfigs)({
        toolbarsPreset,
        props: {
            wysiwygToolbarConfig: initialWysiwygToolbarConfig,
            markupToolbarConfig: initialMarkupToolbarConfig,
            wysiwygHiddenActionsConfig: initialWysiwygHiddenActionsConfig,
            markupHiddenActionsConfig: initialMarkupHiddenActionsConfig,
        },
        preset: editor.preset,
    }), [
        toolbarsPreset,
        initialWysiwygToolbarConfig,
        initialMarkupToolbarConfig,
        initialWysiwygHiddenActionsConfig,
        initialMarkupHiddenActionsConfig,
        editor.preset,
    ]);
    const rerender = (0, react_use_1.useUpdate)();
    (0, react_1.useLayoutEffect)(() => {
        editor.on('rerender', rerender);
        return () => {
            editor.off('rerender', rerender);
        };
    }, [editor, rerender]);
    const onModeChange = (0, react_1.useCallback)((type) => {
        editor.changeEditorMode({ mode: type, reason: 'settings' });
        unsetShowPreview();
    }, [editor, unsetShowPreview]);
    const onToolbarVisibilityChange = (0, react_1.useCallback)((visible) => {
        editor.changeToolbarVisibility({ visible });
    }, [editor]);
    const onSplitModeChange = (0, react_1.useCallback)((splitModeEnabled) => {
        unsetShowPreview();
        editor.changeSplitModeEnabled({ splitModeEnabled });
    }, [editor, unsetShowPreview]);
    const onShowPreviewChange = (0, react_1.useCallback)((showPreviewValue) => {
        editor.changeSplitModeEnabled({ splitModeEnabled: false });
        if (showPreviewValue !== showPreview)
            toggleShowPreview();
    }, [editor, showPreview, toggleShowPreview]);
    const editorMode = editor.currentMode;
    const markupSplitMode = editor.splitModeEnabled && editor.splitMode && editorMode === 'markup';
    const canRenderPreview = Boolean(editor.renderPreview && editorMode === 'markup' && !editor.splitModeEnabled);
    (0, react_use_1.useKey)((e) => canRenderPreview && isPreviewKeyDown(e), (e) => {
        e.preventDefault();
        onShowPreviewChange(!showPreview);
    }, { event: 'keydown' }, [showPreview, editorMode, onShowPreviewChange, canRenderPreview]);
    const editorWrapperRef = (0, react_1.useRef)(null);
    const splitModeViewWrapperRef = (0, react_1.useRef)(null);
    (0, react_1.useEffect)(() => {
        if (showPreview) {
            divRef.current.focus();
        }
    }, [divRef, showPreview]);
    (0, react_use_1.useKey)((e) => enableSubmitInPreview &&
        showPreview &&
        isWrapperFocused(divRef) &&
        isSubmitKeyDown(e), () => {
        editor.emit('submit', null);
        if (hidePreviewAfterSubmit) {
            onShowPreviewChange(false);
        }
    }, { event: 'keydown' }, [hidePreviewAfterSubmit, enableSubmitInPreview, showPreview, showPreview]);
    const settings = (0, react_1.useMemo)(() => ((0, jsx_runtime_1.jsx)(Settings, { mode: editorMode, settingsVisible: settingsVisible, onModeChange: onModeChange, toolbarVisibility: editor.toolbarVisible && !showPreview, onToolbarVisibilityChange: onToolbarVisibilityChange, onSplitModeChange: onSplitModeChange, splitModeEnabled: editor.splitModeEnabled, splitMode: editor.splitMode, stickyToolbar: stickyToolbar, onShowPreviewChange: onShowPreviewChange, showPreview: showPreview, renderPreviewButton: canRenderPreview })), [
        editorMode,
        settingsVisible,
        editor.toolbarVisible,
        editor.splitModeEnabled,
        editor.splitMode,
        onModeChange,
        showPreview,
        onToolbarVisibilityChange,
        onSplitModeChange,
        stickyToolbar,
        onShowPreviewChange,
        canRenderPreview,
    ]);
    const toaster = (0, uikit_1.useToaster)();
    return ((0, jsx_runtime_1.jsx)(react_error_boundary_1.ErrorBoundary, { onError: (e) => {
            logger_1.globalLogger.error(e);
            editor.logger.error(e);
        }, fallbackRender: ({ error, resetErrorBoundary }) => {
            toaster.add({
                theme: 'danger',
                name: 'g-md-editor-error',
                title: (0, bundle_1.i18n)('error-title'),
                content: error.message,
            });
            setTimeout(() => {
                resetErrorBoundary();
                editor.changeEditorMode({
                    mode: 'markup',
                    reason: 'error-boundary',
                    emit: false,
                });
            });
            return null;
        }, children: (0, jsx_runtime_1.jsxs)("div", { ref: divRef, "data-qa": qa, className: b({
                settings: settingsVisible,
                split: markupSplitMode && editor.splitMode,
            }, [className]), role: "button", tabIndex: 0, children: [(0, jsx_runtime_1.jsx)("div", { className: b('editor-wrapper'), ref: editorWrapperRef, "data-qa": "g-md-editor-mode", "data-mode": editor.currentMode, children: showPreview ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("div", { className: b('preview-wrapper'), children: editor.renderPreview?.({
                                    getValue: editor.getValue,
                                    mode: 'preview',
                                    md: editor.mdOptions,
                                    directiveSyntax: editor.directiveSyntax,
                                }) }), settings] })) : ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [editorMode === 'wysiwyg' && ((0, jsx_runtime_1.jsx)(WysiwygEditorView_1.WysiwygEditorView, { editor: editor, autofocus: autofocus, settingsVisible: settingsVisible, toolbarConfig: wysiwygToolbarConfig, toolbarVisible: editor.toolbarVisible, hiddenActionsConfig: wysiwygHiddenActionsConfig, className: b('editor', { mode: editorMode }), toolbarClassName: b('toolbar'), stickyToolbar: stickyToolbar, children: editor.toolbarVisible && settingsVisible && settings })), editorMode === 'markup' && ((0, jsx_runtime_1.jsx)(MarkupEditorView_1.MarkupEditorView, { editor: editor, autofocus: autofocus, settingsVisible: settingsVisible, toolbarConfig: markupToolbarConfig, toolbarVisible: editor.toolbarVisible, splitMode: editor.splitMode, splitModeEnabled: editor.splitModeEnabled, hiddenActionsConfig: markupHiddenActionsConfig, className: b('editor', { mode: editorMode }), toolbarClassName: b('toolbar'), stickyToolbar: stickyToolbar, children: editor.toolbarVisible && settings })), !editor.toolbarVisible && settings] })) }), markupSplitMode && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [editor.splitMode === 'horizontal' ? ((0, jsx_runtime_1.jsx)(HorizontalDrag_1.HorizontalDrag, { editor: editor, isMounted: isMounted, leftElRef: editorWrapperRef, rightElRef: splitModeViewWrapperRef, wrapperRef: divRef })) : ((0, jsx_runtime_1.jsx)("div", { className: b('resizer') })), (0, jsx_runtime_1.jsx)(SplitModeView_1.SplitModeView, { editor: editor, ref: splitModeViewWrapperRef })] }))] }) }));
});
exports.MarkdownEditorView.displayName = 'MarkdownEditorView';
const MarkupSearchAnchor = ({ mode }) => ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: mode === 'markup' && (0, jsx_runtime_1.jsx)("div", { className: "g-md-search-anchor" }) }));
function Settings(props) {
    const wrapperRef = (0, react_1.useRef)(null);
    const isSticky = (0, react_utils_1.useSticky)(wrapperRef) && props.toolbarVisibility && props.stickyToolbar;
    return ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: (props.renderPreviewButton || props.settingsVisible) && ((0, jsx_runtime_1.jsx)("div", { className: b('settings-wrapper'), children: (0, jsx_runtime_1.jsxs)("div", { ref: wrapperRef, className: sticky_1.stickyCn.settings({
                    withToolbar: props.toolbarVisibility,
                    stickyActive: isSticky,
                }), children: [(0, jsx_runtime_1.jsx)(settings_1.EditorSettings, { ...props }), (0, jsx_runtime_1.jsx)(MarkupSearchAnchor, { ...props })] }) })) }));
}
function isPreviewKeyDown(e) {
    const modKey = (0, utils_1.isMac)() ? e.metaKey : e.ctrlKey;
    return modKey && e.shiftKey && e.code === 'KeyP';
}
function isWrapperFocused(divRef) {
    return document.activeElement === divRef.current;
}
function isSubmitKeyDown(e) {
    const modKey = (0, utils_1.isMac)() ? e.metaKey : e.ctrlKey;
    return modKey && e.code === 'Enter';
}
//# sourceMappingURL=MarkdownEditorView.js.map
