"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const jsx_runtime_1 = require("react/jsx-runtime");
const link_1 = require("@lexical/link");
const LexicalComposerContext_1 = require("@lexical/react/LexicalComposerContext");
const utils_1 = require("@lexical/utils");
const lexical_1 = require("lexical");
const react_1 = require("react");
const editor_1 = require("../../../utils/editor");
const utils_2 = require("@selfcommunity/utils");
const styles_1 = require("@mui/material/styles");
const material_1 = require("@mui/material");
const Icon_1 = tslib_1.__importDefault(require("@mui/material/Icon"));
const constants_1 = require("../constants");
const classes = {
    root: `${constants_1.PREFIX}-floating-link-plugin-root`
};
const Root = (0, styles_1.styled)(material_1.Popper, {
    name: constants_1.PREFIX,
    slot: 'FloatingLinkPluginRoot'
})(() => ({}));
function FloatingLinkPlugin({ editor, isLink, setIsLink }) {
    const [anchorEl, setAnchorEl] = (0, react_1.useState)(null);
    const [linkUrl, setLinkUrl] = (0, react_1.useState)('');
    const [hideForUrl, setHideForUrl] = (0, react_1.useState)(null);
    const [lastSelection, setLastSelection] = (0, react_1.useState)(null);
    const updateLinkEditor = (0, react_1.useCallback)(() => {
        var _a;
        const selection = (0, lexical_1.$getSelection)();
        if ((0, lexical_1.$isRangeSelection)(selection)) {
            const node = (0, editor_1.getSelectedNode)(selection);
            const parent = node.getParent();
            if ((0, link_1.$isLinkNode)(parent)) {
                setLinkUrl(parent.getURL());
            }
            else if ((0, link_1.$isLinkNode)(node)) {
                setLinkUrl(node.getURL());
            }
            else {
                setLinkUrl('');
            }
        }
        const nativeSelection = window.getSelection();
        const activeElement = document.activeElement;
        const rootElement = editor.getRootElement();
        if (selection !== null &&
            nativeSelection !== null &&
            rootElement !== null &&
            rootElement.contains(nativeSelection.anchorNode) &&
            editor.isEditable()) {
            setAnchorEl((_a = nativeSelection.focusNode) === null || _a === void 0 ? void 0 : _a.parentElement);
            setLastSelection(selection);
        }
        else if (!activeElement) {
            setAnchorEl(null);
            setLastSelection(null);
            setLinkUrl('');
        }
        return true;
    }, [editor]);
    (0, react_1.useEffect)(() => {
        if (linkUrl != hideForUrl) {
            setHideForUrl(null);
        }
    }, [linkUrl]);
    (0, react_1.useEffect)(() => {
        return (0, utils_1.mergeRegister)(editor.registerUpdateListener(({ editorState }) => {
            editorState.read(() => {
                updateLinkEditor();
            });
        }), editor.registerCommand(lexical_1.SELECTION_CHANGE_COMMAND, () => {
            updateLinkEditor();
            return true;
        }, lexical_1.COMMAND_PRIORITY_LOW), editor.registerCommand(lexical_1.KEY_ESCAPE_COMMAND, () => {
            if (isLink) {
                setIsLink(false);
                return true;
            }
            return false;
        }, lexical_1.COMMAND_PRIORITY_HIGH));
    }, [editor, updateLinkEditor, setIsLink, isLink]);
    (0, react_1.useEffect)(() => {
        editor.getEditorState().read(() => {
            updateLinkEditor();
        });
    }, [editor, updateLinkEditor]);
    const handleLinkSubmission = () => {
        if (lastSelection !== null) {
            if (linkUrl !== '') {
                setHideForUrl(linkUrl);
                editor.dispatchCommand(link_1.TOGGLE_LINK_COMMAND, (0, utils_2.isValidUrl)(linkUrl) ? linkUrl : 'https://');
            }
        }
    };
    if (!isLink || linkUrl === hideForUrl) {
        return null;
    }
    return ((0, jsx_runtime_1.jsx)(Root, Object.assign({ className: classes.root, open: Boolean(anchorEl), anchorEl: anchorEl, placement: "right" }, { children: (0, jsx_runtime_1.jsx)(material_1.Paper, { children: (0, jsx_runtime_1.jsx)(material_1.TextField, { size: "small", value: linkUrl, variant: "outlined", onChange: (event) => {
                    setLinkUrl(event.target.value);
                }, InputProps: {
                    endAdornment: ((0, jsx_runtime_1.jsxs)(material_1.InputAdornment, Object.assign({ position: "end" }, { children: [(0, jsx_runtime_1.jsx)(material_1.IconButton, Object.assign({ size: "small", tabIndex: 0, onClick: () => {
                                    setIsLink(false);
                                } }, { children: (0, jsx_runtime_1.jsx)(Icon_1.default, { children: "close" }) })), (0, jsx_runtime_1.jsx)(material_1.IconButton, Object.assign({ size: "small", tabIndex: 1, onClick: handleLinkSubmission }, { children: (0, jsx_runtime_1.jsx)(Icon_1.default, { children: "check" }) }))] })))
                } }) }) })));
}
function useFloatingLinkEditorToolbar(editor) {
    const [activeEditor, setActiveEditor] = (0, react_1.useState)(editor);
    const [isLink, setIsLink] = (0, react_1.useState)(false);
    const updateToolbar = (0, react_1.useCallback)(() => {
        const selection = (0, lexical_1.$getSelection)();
        if ((0, lexical_1.$isRangeSelection)(selection)) {
            const node = (0, editor_1.getSelectedNode)(selection);
            const linkParent = (0, utils_1.$findMatchingParent)(node, link_1.$isLinkNode);
            const autoLinkParent = (0, utils_1.$findMatchingParent)(node, link_1.$isAutoLinkNode);
            // We don't want this menu to open for auto links.
            if (linkParent != null && autoLinkParent == null) {
                setIsLink(true);
            }
            else {
                setIsLink(false);
            }
        }
    }, []);
    (0, react_1.useEffect)(() => {
        return (0, utils_1.mergeRegister)(editor.registerUpdateListener(({ editorState }) => {
            editorState.read(() => {
                updateToolbar();
            });
        }), editor.registerCommand(lexical_1.SELECTION_CHANGE_COMMAND, (_payload, newEditor) => {
            updateToolbar();
            setActiveEditor(newEditor);
            return false;
        }, lexical_1.COMMAND_PRIORITY_CRITICAL));
    }, [editor, updateToolbar]);
    return (0, jsx_runtime_1.jsx)(FloatingLinkPlugin, { editor: activeEditor, isLink: isLink, setIsLink: setIsLink });
}
exports.default = () => {
    const [editor] = (0, LexicalComposerContext_1.useLexicalComposerContext)();
    return useFloatingLinkEditorToolbar(editor);
};
