"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.GptWidgetDecoView = exports.cnGptPopup = void 0;
const jsx_runtime_1 = require("react/jsx-runtime");
const react_1 = require("react");
const uikit_1 = require("@gravity-ui/uikit");
const prosemirror_model_1 = require("prosemirror-model");
const prosemirror_state_1 = require("prosemirror-state");
const react_use_1 = require("react-use");
const classname_1 = require("../../../../classname.js");
const behavior_1 = require("../../../behavior/index.js");
const GptDialog_1 = require("../GptDialog/GptDialog.js");
const constants_1 = require("../constants.js");
const plugin_1 = require("../plugin.js");
require("./view.css");
exports.cnGptPopup = (0, classname_1.cn)('gpt-popup');
class GptWidgetDecoView {
    _view;
    _renderer;
    _decoElem = null;
    _params;
    _serializer;
    _parser;
    _confirmOpen;
    constructor(view, params) {
        this._view = view;
        this._params = params;
        this._serializer = params.serializer;
        this._parser = params.parser;
        this._confirmOpen = false;
        this._renderer = (0, behavior_1.getReactRendererFromState)(view.state).createItem('gpt-widget-view', this._render.bind(this));
    }
    update(view, prevState) {
        const { state, dispatch } = view;
        if (this._decoElem && !state.selection.eq(prevState.selection)) {
            const transaction = state.tr;
            const meta = { action: 'hide' };
            dispatch(transaction.setMeta(plugin_1.pluginKey, meta));
            this._view.focus();
            return;
        }
        const decoElements = Array.from(view.dom.querySelectorAll(`.${constants_1.WIDGET_DECO_CLASS_NAME}`));
        this._decoElem = decoElements.at(-1) ?? null;
        this._renderer.rerender();
    }
    destroy() {
        this._resetState();
        this._renderer.remove();
    }
    _resetState() {
        this._decoElem = null;
        this._confirmOpen = false;
    }
    _onConfirmCancel = () => {
        this._confirmOpen = false;
        this._renderer.rerender();
    };
    _onConfirmOk = () => {
        this._onClose();
    };
    _render() {
        if (!this._decoElem)
            return null;
        const markup = this._getContentOfDecoration();
        if (markup === undefined) {
            return null;
        }
        return ((0, jsx_runtime_1.jsx)(Widget, { markup: markup, anchorElement: this._decoElem, answerRender: this._params.answerRender, promptPresets: this._params.promptPresets, disablePromptPresets: this._params.disablePromptPresets, customPromptPlaceholder: this._params.customPromptPlaceholder, disabledPromptPlaceholder: this._params.disabledPromptPlaceholder, gptAlertProps: this._params.gptAlertProps, onApplyResult: this._onSubmit, onCustomPromptApply: this._params.onCustomPromptApply, onPromptPresetClick: this._params.onPromptPresetClick, onTryAgain: this._params.onTryAgain, onLike: this._params.onLike, onDislike: this._params.onDislike, onClose: this._onClose, onUpdate: this._onGptAnswerUpdate, confirmOpen: this._confirmOpen, onConfirmOk: this._onConfirmOk, onConfirmCancel: this._onConfirmCancel }));
    }
    _onGptAnswerUpdate = (answer) => {
        this._params.onUpdate?.(answer);
    };
    _onSubmit = (answer) => {
        const deco = this._getCurrentDecoration();
        if (!deco)
            return;
        const { from, to } = deco;
        const answerNode = this._parser.parse(answer);
        const tr = this._view.state.tr;
        const meta = { action: 'hide' };
        tr.setMeta(plugin_1.pluginKey, meta);
        tr.replace(from, to, new prosemirror_model_1.Slice(answerNode.content, 1, 1));
        tr.setSelection(prosemirror_state_1.TextSelection.create(tr.doc, tr.mapping.map(to)));
        this._view.dispatch(tr);
        setTimeout(() => {
            this._view.focus();
        }, 0);
        this._params.onApplyResult?.(answer);
        this._resetState();
    };
    _onClose = () => {
        const deco = this._getCurrentDecoration();
        if (!deco) {
            return;
        }
        const tr = this._view.state.tr;
        const meta = { action: 'hide' };
        tr.setSelection(prosemirror_state_1.TextSelection.create(tr.doc, deco.from, deco.to));
        tr.setMeta(plugin_1.pluginKey, meta);
        this._view.dispatch(tr);
        setTimeout(() => {
            this._view.focus();
        }, 0);
        this._params.onClose?.();
        this._resetState();
    };
    _getContentOfDecoration() {
        const deco = this._getCurrentDecoration();
        if (!deco)
            return undefined;
        const { from, to } = deco;
        try {
            // FIXME: Verify and use Node instead of Fragment
            const fragment = this._view.state.doc.slice(from, to, true).content;
            const yfmMarkup = this._serializer.serialize(fragment);
            return yfmMarkup;
        }
        catch (error) {
            console.error(error);
            return this._view.state.doc.textBetween(from, to, '\n', '');
        }
    }
    _getCurrentDecoration() {
        return this._getPluginState()?.find(undefined, undefined, 
        // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-return
        (spec) => spec[constants_1.WIDGET_DECO_SPEC_FLAG])[0];
    }
    _getPluginState() {
        return plugin_1.pluginKey.getState(this._view.state);
    }
}
exports.GptWidgetDecoView = GptWidgetDecoView;
function Widget({ markup, anchorElement, answerRender, promptPresets, disablePromptPresets, customPromptPlaceholder, disabledPromptPlaceholder, onCustomPromptApply, onApplyResult, onPromptPresetClick, onTryAgain, onLike, onDislike, onClose, onUpdate, gptAlertProps, }) {
    (0, react_use_1.useMount)(() => {
        if (anchorElement && 'scrollIntoView' in anchorElement) {
            anchorElement.scrollIntoView({
                behavior: 'smooth',
                block: 'center',
            });
        }
    });
    const handleUpdate = (0, react_1.useCallback)((result) => {
        onUpdate?.(result);
    }, [onUpdate]);
    return ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: (0, jsx_runtime_1.jsx)(uikit_1.Popup, { className: (0, exports.cnGptPopup)(), open: true, anchorElement: anchorElement, placement: constants_1.gptPopupPlacement, onOpenChange: (open) => {
                if (!open)
                    onClose();
            }, strategy: "absolute", children: (0, jsx_runtime_1.jsx)("div", { className: (0, exports.cnGptPopup)('content'), children: (0, jsx_runtime_1.jsx)(GptDialog_1.GptDialog, { markup: markup, answerRender: answerRender, promptPresets: promptPresets, disablePromptPresets: disablePromptPresets, customPromptPlaceholder: customPromptPlaceholder, disabledPromptPlaceholder: disabledPromptPlaceholder, onApplyResult: onApplyResult, onCustomPromptApply: onCustomPromptApply, onPromptPresetClick: onPromptPresetClick, onTryAgain: onTryAgain, onLike: onLike, onDislike: onDislike, onClose: onClose, onUpdate: handleUpdate, gptAlertProps: gptAlertProps }) }) }) }));
}
//# sourceMappingURL=view.js.map
