"use client";
import { jsx, jsxs } from "react/jsx-runtime";
import { Suspense, useCallback, useEffect, useRef, useState } from "react";
import { useLexicalComposerContext } from "@lexical/react/LexicalComposerContext";
import { LexicalErrorBoundary } from "@lexical/react/LexicalErrorBoundary";
import { HistoryPlugin } from "@lexical/react/LexicalHistoryPlugin";
import { LexicalNestedComposer } from "@lexical/react/LexicalNestedComposer";
import { OnChangePlugin } from "@lexical/react/LexicalOnChangePlugin";
import { RichTextPlugin } from "@lexical/react/LexicalRichTextPlugin";
import { useLexicalNodeSelection } from "@lexical/react/useLexicalNodeSelection";
import { mergeRegister } from "@lexical/utils";
import classnames from "classnames";
import { $getNodeByKey, $getSelection, $isNodeSelection, $setSelection, COMMAND_PRIORITY_LOW, KEY_BACKSPACE_COMMAND, KEY_DELETE_COMMAND, KEY_ENTER_COMMAND, KEY_ESCAPE_COMMAND, SELECTION_CHANGE_COMMAND } from "lexical";
import { useEditorConfig } from "../../config/editor-config-context.js";
import { ContentEditable } from "../../content-editable.js";
import { useSharedHistoryContext } from "../../context/shared-history-context.js";
import { useSharedOnChange } from "../../context/shared-on-change-context.js";
import { AdmonitionModal } from "../../plugins/admonition-plugin/admonition-modal.js";
import { Placeholder } from "../../ui/placeholder.js";
import { $isAdmonitionNode } from "./admonition-node.js";
import { DangerIcon, NoteIcon, TipIcon, WarningIcon } from "./icons/index.js";
import "./admonition-node-component.css";
const icons = {
    note: NoteIcon,
    tip: TipIcon,
    warning: WarningIcon,
    danger: DangerIcon
};
function AdmonitionNodeComponent({ admonitionType, title, content, nodeKey }) {
    const [open, setOpen] = useState(false);
    const [editor] = useLexicalComposerContext();
    const buttonRef = useRef(null);
    const { historyState } = useSharedHistoryContext();
    const [isSelected, setSelected, _clearSelection] = useLexicalNodeSelection(nodeKey);
    const [selection, setSelection] = useState(null);
    const { uuid } = useEditorConfig();
    const { onChange } = useSharedOnChange();
    const editorState = editor.getEditorState();
    const activeEditorRef = useRef(null);
    const node = editorState.read(()=>$getNodeByKey(nodeKey));
    const onDelete = useCallback((payload)=>{
        if (isSelected && $isNodeSelection($getSelection())) {
            const event = payload;
            event.preventDefault();
            const node = $getNodeByKey(nodeKey);
            if ($isAdmonitionNode(node)) node?.remove();
            setSelected(false);
        }
        return false;
    }, [
        isSelected,
        nodeKey,
        setSelected
    ]);
    const onEnter = useCallback((event)=>{
        const latestSelection = $getSelection();
        if (isSelected && $isNodeSelection(latestSelection) && 1 === latestSelection.getNodes().length) {
            $setSelection(null);
            event.preventDefault();
            content.focus();
            return true;
        }
        return false;
    }, [
        content,
        isSelected
    ]);
    const onEscape = useCallback((event)=>{
        if (activeEditorRef.current === content || buttonRef.current === event.target) {
            $setSelection(null);
            editor.update(()=>{
                setSelected(true);
                const parentRootElement = editor.getRootElement();
                if (null !== parentRootElement) parentRootElement.focus();
            });
            return true;
        }
        return false;
    }, [
        content,
        editor,
        setSelected
    ]);
    useEffect(()=>{
        let isMounted = true;
        const unregister = mergeRegister(editor.registerUpdateListener(({ editorState })=>{
            if (isMounted) setSelection(editorState.read(()=>$getSelection()));
        }), editor.registerCommand(SELECTION_CHANGE_COMMAND, (_, activeEditor)=>{
            activeEditorRef.current = activeEditor;
            return false;
        }, COMMAND_PRIORITY_LOW), editor.registerCommand(KEY_DELETE_COMMAND, onDelete, COMMAND_PRIORITY_LOW), editor.registerCommand(KEY_BACKSPACE_COMMAND, onDelete, COMMAND_PRIORITY_LOW), editor.registerCommand(KEY_ENTER_COMMAND, onEnter, COMMAND_PRIORITY_LOW), editor.registerCommand(KEY_ESCAPE_COMMAND, onEscape, COMMAND_PRIORITY_LOW));
        return ()=>{
            isMounted = false;
            unregister();
        };
    }, [
        editor,
        onDelete,
        onEnter,
        onEscape
    ]);
    const draggable = isSelected && $isNodeSelection(selection);
    const isFocused = isSelected;
    const handleToggleModal = ()=>{
        if (null != uuid) setOpen(!open);
    };
    const handleUpdateAdmonition = ({ admonitionType, title })=>{
        setOpen(false);
        if (null != title && null != admonitionType) {
            const admonitionPayload = {
                admonitionType,
                title
            };
            editor.update(()=>{
                node.update(admonitionPayload);
            });
        } else console.error('Error: unable to find image source from document.');
    };
    const classNames = classnames('Admonition__container', {
        focused: isFocused
    }, {
        draggable: $isNodeSelection(selection)
    });
    const Icon = icons[admonitionType];
    return /*#__PURE__*/ jsxs(Suspense, {
        fallback: null,
        children: [
            /*#__PURE__*/ jsxs("div", {
                draggable: draggable,
                className: classNames,
                children: [
                    /*#__PURE__*/ jsx("button", {
                        type: "button",
                        className: "admonition-edit-button",
                        ref: buttonRef,
                        onClick: handleToggleModal,
                        children: "Edit"
                    }),
                    /*#__PURE__*/ jsxs("div", {
                        className: "AdmonitionNode__header",
                        children: [
                            /*#__PURE__*/ jsx(Icon, {}),
                            /*#__PURE__*/ jsx("div", {
                                children: title
                            })
                        ]
                    }),
                    /*#__PURE__*/ jsx("div", {
                        className: "AdmonitionNode__content",
                        children: /*#__PURE__*/ jsxs(LexicalNestedComposer, {
                            initialEditor: content,
                            children: [
                                /*#__PURE__*/ jsx(OnChangePlugin, {
                                    ignoreSelectionChange: true,
                                    onChange: (_nestedEditorState, _nestedEditor, nestedTags)=>{
                                        const editorState = editor.getEditorState();
                                        if (null != onChange) onChange(editorState, editor, nestedTags);
                                    }
                                }),
                                /*#__PURE__*/ jsx(HistoryPlugin, {
                                    externalHistoryState: historyState
                                }),
                                /*#__PURE__*/ jsx(RichTextPlugin, {
                                    contentEditable: /*#__PURE__*/ jsx(ContentEditable, {
                                        className: "AdmonitionNode__contentEditable"
                                    }),
                                    placeholder: /*#__PURE__*/ jsx(Placeholder, {
                                        className: "Admonition__placeholder",
                                        children: "Enter some text..."
                                    }),
                                    ErrorBoundary: LexicalErrorBoundary
                                })
                            ]
                        })
                    })
                ]
            }),
            null != uuid && uuid.length > 0 && /*#__PURE__*/ jsx(AdmonitionModal, {
                open: open,
                onClose: handleToggleModal,
                onSubmit: handleUpdateAdmonition,
                data: {
                    title,
                    admonitionType
                }
            })
        ]
    });
}
export default AdmonitionNodeComponent;
