"use client";
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
import "./index.css";
import { useCallback, useEffect, useRef, useState } from "react";
import { $isCodeHighlightNode } from "@lexical/code";
import { useLexicalComposerContext } from "@lexical/react/LexicalComposerContext";
import { mergeRegister } from "@lexical/utils";
import { $getSelection, $isParagraphNode, $isRangeSelection, $isTextNode, COMMAND_PRIORITY_LOW, FORMAT_TEXT_COMMAND, SELECTION_CHANGE_COMMAND } from "lexical";
import { createPortal } from "react-dom";
import { $isLinkNode, TOGGLE_LINK_COMMAND } from "../../nodes/link-nodes/index.js";
import { getDOMRangeRect } from "../../utils/getDOMRangeRect.js";
import { getSelectedNode } from "../../utils/getSelectedNode.js";
import { setFloatingElemPosition } from "../../utils/setFloatingElemPosition.js";
function TextFormatFloatingToolbar({ editor, anchorElem, isLink, isBold, isItalic, isUnderline, isCode, isStrikethrough, isSubscript, isSuperscript }) {
    const popupCharStylesEditorRef = useRef(null);
    const handleOnInsertLink = useCallback(()=>{
        if (isLink) editor.dispatchCommand(TOGGLE_LINK_COMMAND, null);
        else {
            const editorState = editor.getEditorState();
            editorState.read(()=>{
                const selection = $getSelection();
                if ($isRangeSelection(selection)) {
                    if (selection.focus.offset !== selection.anchor.offset) {
                        const linkAttributes = {
                            linkType: 'custom',
                            url: 'https://'
                        };
                        editor.dispatchCommand(TOGGLE_LINK_COMMAND, linkAttributes);
                    }
                }
            });
        }
    }, [
        editor,
        isLink
    ]);
    function mouseMoveListener(e) {
        if (popupCharStylesEditorRef?.current != null && (1 === e.buttons || 3 === e.buttons)) {
            if ('none' !== popupCharStylesEditorRef.current.style.pointerEvents) {
                const x = e.clientX;
                const y = e.clientY;
                const elementUnderMouse = document.elementFromPoint(x, y);
                if (!popupCharStylesEditorRef.current.contains(elementUnderMouse)) popupCharStylesEditorRef.current.style.pointerEvents = 'none';
            }
        }
    }
    function mouseUpListener(_e) {
        if (popupCharStylesEditorRef?.current != null) {
            if ('auto' !== popupCharStylesEditorRef.current.style.pointerEvents) popupCharStylesEditorRef.current.style.pointerEvents = 'auto';
        }
    }
    useEffect(()=>{
        if (popupCharStylesEditorRef?.current != null) {
            document.addEventListener('mousemove', mouseMoveListener);
            document.addEventListener('mouseup', mouseUpListener);
            return ()=>{
                document.removeEventListener('mousemove', mouseMoveListener);
                document.removeEventListener('mouseup', mouseUpListener);
            };
        }
    }, [
        popupCharStylesEditorRef
    ]);
    const updateTextFormatFloatingToolbar = useCallback(()=>{
        const selection = $getSelection();
        const popupCharStylesEditorElem = popupCharStylesEditorRef.current;
        const nativeSelection = window.getSelection();
        if (null === popupCharStylesEditorElem) return;
        const rootElement = editor.getRootElement();
        if (null !== selection && null !== nativeSelection && !nativeSelection.isCollapsed && rootElement?.contains(nativeSelection.anchorNode)) {
            const rangeRect = getDOMRangeRect(nativeSelection, rootElement);
            setFloatingElemPosition(rangeRect, popupCharStylesEditorElem, anchorElem, isLink);
        }
    }, [
        editor,
        anchorElem,
        isLink
    ]);
    useEffect(()=>{
        const scrollerElem = anchorElem.parentElement;
        const update = ()=>{
            editor.getEditorState().read(()=>{
                updateTextFormatFloatingToolbar();
            });
        };
        window.addEventListener('resize', update);
        if (null != scrollerElem) scrollerElem.addEventListener('scroll', update);
        return ()=>{
            window.removeEventListener('resize', update);
            if (null != scrollerElem) scrollerElem.removeEventListener('scroll', update);
        };
    }, [
        editor,
        updateTextFormatFloatingToolbar,
        anchorElem
    ]);
    useEffect(()=>{
        editor.getEditorState().read(()=>{
            updateTextFormatFloatingToolbar();
        });
        return mergeRegister(editor.registerUpdateListener(({ editorState })=>{
            editorState.read(()=>{
                updateTextFormatFloatingToolbar();
            });
        }), editor.registerCommand(SELECTION_CHANGE_COMMAND, ()=>{
            updateTextFormatFloatingToolbar();
            return false;
        }, COMMAND_PRIORITY_LOW));
    }, [
        editor,
        updateTextFormatFloatingToolbar
    ]);
    return /*#__PURE__*/ jsx("div", {
        ref: popupCharStylesEditorRef,
        className: "floating-text-format-popup",
        children: editor.isEditable() && /*#__PURE__*/ jsxs(Fragment, {
            children: [
                /*#__PURE__*/ jsx("button", {
                    type: "button",
                    onClick: ()=>{
                        editor.dispatchCommand(FORMAT_TEXT_COMMAND, 'bold');
                    },
                    className: `popup-item spaced ${isBold ? 'active' : ''}`,
                    "aria-label": "Format text as bold",
                    children: /*#__PURE__*/ jsx("i", {
                        className: "format bold"
                    })
                }),
                /*#__PURE__*/ jsx("button", {
                    type: "button",
                    onClick: ()=>{
                        editor.dispatchCommand(FORMAT_TEXT_COMMAND, 'italic');
                    },
                    className: `popup-item spaced ${isItalic ? 'active' : ''}`,
                    "aria-label": "Format text as italics",
                    children: /*#__PURE__*/ jsx("i", {
                        className: "format italic"
                    })
                }),
                /*#__PURE__*/ jsx("button", {
                    type: "button",
                    onClick: ()=>{
                        editor.dispatchCommand(FORMAT_TEXT_COMMAND, 'underline');
                    },
                    className: `popup-item spaced ${isUnderline ? 'active' : ''}`,
                    "aria-label": "Format text to underlined",
                    children: /*#__PURE__*/ jsx("i", {
                        className: "format underline"
                    })
                }),
                /*#__PURE__*/ jsx("button", {
                    type: "button",
                    onClick: ()=>{
                        editor.dispatchCommand(FORMAT_TEXT_COMMAND, 'strikethrough');
                    },
                    className: `popup-item spaced ${isStrikethrough ? 'active' : ''}`,
                    "aria-label": "Format text with a strikethrough",
                    children: /*#__PURE__*/ jsx("i", {
                        className: "format strikethrough"
                    })
                }),
                /*#__PURE__*/ jsx("button", {
                    type: "button",
                    onClick: ()=>{
                        editor.dispatchCommand(FORMAT_TEXT_COMMAND, "subscript");
                    },
                    className: `popup-item spaced ${isSubscript ? 'active' : ''}`,
                    title: "Subscript",
                    "aria-label": "Format Subscript",
                    children: /*#__PURE__*/ jsx("i", {
                        className: "format subscript"
                    })
                }),
                /*#__PURE__*/ jsx("button", {
                    type: "button",
                    onClick: ()=>{
                        editor.dispatchCommand(FORMAT_TEXT_COMMAND, "superscript");
                    },
                    className: `popup-item spaced ${isSuperscript ? 'active' : ''}`,
                    title: "Superscript",
                    "aria-label": "Format Superscript",
                    children: /*#__PURE__*/ jsx("i", {
                        className: "format superscript"
                    })
                }),
                /*#__PURE__*/ jsx("button", {
                    type: "button",
                    onClick: ()=>{
                        editor.dispatchCommand(FORMAT_TEXT_COMMAND, 'code');
                    },
                    className: `popup-item spaced ${isCode ? 'active' : ''}`,
                    "aria-label": "Insert code block",
                    children: /*#__PURE__*/ jsx("i", {
                        className: "format code"
                    })
                }),
                /*#__PURE__*/ jsx("button", {
                    type: "button",
                    onClick: handleOnInsertLink,
                    className: `popup-item spaced ${isLink ? 'active' : ''}`,
                    "aria-label": "Insert link",
                    children: /*#__PURE__*/ jsx("i", {
                        className: "format link"
                    })
                })
            ]
        })
    });
}
function useFloatingTextFormatToolbar(editor, anchorElem) {
    const [isText, setIsText] = useState(false);
    const [isLink, setIsLink] = useState(false);
    const [isBold, setIsBold] = useState(false);
    const [isItalic, setIsItalic] = useState(false);
    const [isUnderline, setIsUnderline] = useState(false);
    const [isStrikethrough, setIsStrikethrough] = useState(false);
    const [isSubscript, setIsSubscript] = useState(false);
    const [isSuperscript, setIsSuperscript] = useState(false);
    const [isCode, setIsCode] = useState(false);
    const updatePopup = useCallback(()=>{
        editor.getEditorState().read(()=>{
            if (editor.isComposing()) return;
            const selection = $getSelection();
            const nativeSelection = window.getSelection();
            const rootElement = editor.getRootElement();
            if (null !== nativeSelection && (!$isRangeSelection(selection) || null === rootElement || !rootElement.contains(nativeSelection.anchorNode))) return void setIsText(false);
            if (!$isRangeSelection(selection)) return;
            const node = getSelectedNode(selection);
            setIsBold(selection.hasFormat('bold'));
            setIsItalic(selection.hasFormat('italic'));
            setIsUnderline(selection.hasFormat('underline'));
            setIsStrikethrough(selection.hasFormat('strikethrough'));
            setIsSubscript(selection.hasFormat("subscript"));
            setIsSuperscript(selection.hasFormat("superscript"));
            setIsCode(selection.hasFormat('code'));
            const parent = node.getParent();
            $isLinkNode(parent) || $isLinkNode(node) ? setIsLink(true) : setIsLink(false);
            $isCodeHighlightNode(selection.anchor.getNode()) || '' === selection.getTextContent() ? setIsText(false) : setIsText($isTextNode(node) || $isParagraphNode(node));
            const rawTextContent = selection.getTextContent().replace(/\n/g, '');
            if (!selection.isCollapsed() && '' === rawTextContent) setIsText(false);
        });
    }, [
        editor
    ]);
    useEffect(()=>{
        document.addEventListener('selectionchange', updatePopup);
        return ()=>{
            document.removeEventListener('selectionchange', updatePopup);
        };
    }, [
        updatePopup
    ]);
    useEffect(()=>mergeRegister(editor.registerUpdateListener(()=>{
            updatePopup();
        }), editor.registerRootListener(()=>{
            if (null === editor.getRootElement()) setIsText(false);
        })), [
        editor,
        updatePopup
    ]);
    if (!isText) return null;
    return /*#__PURE__*/ createPortal(/*#__PURE__*/ jsx(TextFormatFloatingToolbar, {
        editor: editor,
        anchorElem: anchorElem,
        isLink: isLink,
        isBold: isBold,
        isItalic: isItalic,
        isStrikethrough: isStrikethrough,
        isSubscript: isSubscript,
        isSuperscript: isSuperscript,
        isUnderline: isUnderline,
        isCode: isCode
    }), anchorElem);
}
function FloatingTextFormatToolbarPlugin({ anchorElem = document.body }) {
    const [editor] = useLexicalComposerContext();
    return useFloatingTextFormatToolbar(editor, anchorElem);
}
export { FloatingTextFormatToolbarPlugin };
