"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;
const EditorWrapper = (0, react_1.forwardRef)(({ autofocus, editor, editorMode, enableSubmitInPreview, hidePreviewAfterSubmit, isFocused, markupHiddenActionsConfig: initialMarkupHiddenActionsConfig, markupToolbarConfig: initialMarkupToolbarConfig, qa, settingsVisible: settingsVisibleProp, showPreview, stickyToolbar, toggleShowPreview, toolbarsPreset, unsetShowPreview, wysiwygHiddenActionsConfig: initialWysiwygHiddenActionsConfig, wysiwygToolbarConfig: initialWysiwygToolbarConfig, }, ref) => {
    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 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 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]);
    (0, react_use_1.useKey)((e) => Boolean(enableSubmitInPreview && showPreview && isFocused && isSubmitKeyDown(e)), () => {
        editor.emit('submit', null);
        if (hidePreviewAfterSubmit) {
            onShowPreviewChange(false);
        }
    }, { event: 'keydown' }, [hidePreviewAfterSubmit, enableSubmitInPreview, showPreview, showPreview]);
    const settingsProps = {
        mode: editorMode,
        onModeChange,
        onShowPreviewChange,
        onSplitModeChange,
        onToolbarVisibilityChange,
        renderPreviewButton: canRenderPreview,
        showPreview,
        splitMode: editor.splitMode,
        splitModeEnabled: editor.splitModeEnabled,
        stickyToolbar,
        toolbarVisibility: editor.toolbarVisible && !showPreview,
        disableMark: editor.mobile,
    };
    const areSettingsVisible = settingsVisibleProp === true ||
        (Array.isArray(settingsVisibleProp) && settingsVisibleProp.length > 0);
    const toolbarDisplay = editor.mobile ? 'scroll' : 'shrink';
    return ((0, jsx_runtime_1.jsx)("div", { className: b('editor-wrapper'), ref: ref, "data-qa": qa, "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,
                    }) }), (0, jsx_runtime_1.jsx)(Settings, { ...settingsProps, settingsVisible: settingsVisibleProp })] })) : ((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: areSettingsVisible, toolbarConfig: wysiwygToolbarConfig, toolbarVisible: editor.toolbarVisible, hiddenActionsConfig: wysiwygHiddenActionsConfig, className: b('editor', { mode: editorMode }), toolbarClassName: b('toolbar'), stickyToolbar: stickyToolbar, toolbarDisplay: toolbarDisplay, children: (0, jsx_runtime_1.jsx)(Settings, { ...settingsProps, settingsVisible: editor.toolbarVisible && settingsVisibleProp }) })), editorMode === 'markup' && ((0, jsx_runtime_1.jsx)(MarkupEditorView_1.MarkupEditorView, { editor: editor, autofocus: autofocus, settingsVisible: areSettingsVisible, toolbarConfig: markupToolbarConfig, toolbarVisible: editor.toolbarVisible, splitMode: editor.splitMode, splitModeEnabled: editor.splitModeEnabled, hiddenActionsConfig: markupHiddenActionsConfig, className: b('editor', { mode: editorMode }), toolbarClassName: b('toolbar'), stickyToolbar: stickyToolbar, toolbarDisplay: toolbarDisplay, children: (0, jsx_runtime_1.jsx)(Settings, { ...settingsProps, settingsVisible: editor.toolbarVisible && settingsVisibleProp }) })), (0, jsx_runtime_1.jsx)(Settings, { ...settingsProps, settingsVisible: !editor.toolbarVisible && settingsVisibleProp, renderPreviewButton: !editor.toolbarVisible && canRenderPreview })] })) }));
});
EditorWrapper.displayName = 'EditorWrapper';
exports.MarkdownEditorView = (0, react_1.forwardRef)((props, ref) => {
    const divRef = (0, react_use_1.useEnsuredForwardedRef)(ref);
    const editorWrapperRef = (0, react_1.useRef)(null);
    const [showPreview, , unsetShowPreview, toggleShowPreview] = (0, react_utils_1.useBooleanState)(false);
    const [isMounted, setIsMounted] = (0, react_1.useState)(false);
    (0, react_1.useEffect)(() => {
        setIsMounted(true);
    }, []);
    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 { autofocus, className, enableSubmitInPreview = true, hidePreviewAfterSubmit = false, markupHiddenActionsConfig, markupToolbarConfig, qa, settingsVisible = true, stickyToolbar, toolbarsPreset, wysiwygHiddenActionsConfig, wysiwygToolbarConfig, } = props;
    const rerender = (0, react_use_1.useUpdate)();
    (0, react_1.useLayoutEffect)(() => {
        editor.on('rerender', rerender);
        return () => {
            editor.off('rerender', rerender);
        };
    }, [editor, rerender]);
    const editorMode = editor.currentMode;
    const markupSplitMode = editor.splitModeEnabled && editor.splitMode && editorMode === 'markup';
    const splitModeViewWrapperRef = (0, react_1.useRef)(null);
    const toaster = (0, uikit_1.useToaster)();
    (0, react_1.useEffect)(() => {
        if (showPreview) {
            divRef.current.focus();
        }
    }, [divRef, showPreview]);
    const areSettingsVisible = settingsVisible === true ||
        (Array.isArray(settingsVisible) && settingsVisible.length > 0);
    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: areSettingsVisible,
                split: markupSplitMode && editor.splitMode,
            }, [className]), role: "button", tabIndex: 0, children: [(0, jsx_runtime_1.jsx)(EditorWrapper, { autofocus: autofocus, editor: editor, editorMode: editorMode, enableSubmitInPreview: enableSubmitInPreview, hidePreviewAfterSubmit: hidePreviewAfterSubmit, isFocused: isWrapperFocused(divRef), markupHiddenActionsConfig: markupHiddenActionsConfig, markupToolbarConfig: markupToolbarConfig, qa: "g-md-editor-mode", ref: editorWrapperRef, settingsVisible: settingsVisible, showPreview: showPreview, stickyToolbar: stickyToolbar, toggleShowPreview: toggleShowPreview, toolbarsPreset: toolbarsPreset, unsetShowPreview: unsetShowPreview, wysiwygHiddenActionsConfig: wysiwygHiddenActionsConfig, wysiwygToolbarConfig: wysiwygToolbarConfig }), 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
