/**
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 */

import { useCallback, useEffect, useState } from 'react';
import {
  $createParagraphNode,
  $getNodeByKey,
  $getRoot,
  $getSelection,
  $isRangeSelection,
  $isRootOrShadowRoot,
  $isTextNode,
  CAN_REDO_COMMAND,
  CAN_UNDO_COMMAND,
  COMMAND_PRIORITY_CRITICAL,
  DEPRECATED_$isGridSelection,
  FORMAT_TEXT_COMMAND,
  REDO_COMMAND,
  SELECTION_CHANGE_COMMAND,
  UNDO_COMMAND,
  type LexicalEditor,
  type NodeKey,
} from 'lexical';
import {
  $createCodeNode,
  $isCodeNode,
  CODE_LANGUAGE_FRIENDLY_NAME_MAP,
  CODE_LANGUAGE_MAP,
  getLanguageFriendlyName,
} from '@lexical/code';
import { $isLinkNode, TOGGLE_LINK_COMMAND } from '@lexical/link';
import {
  $isListNode,
  INSERT_ORDERED_LIST_COMMAND,
  INSERT_UNORDERED_LIST_COMMAND,
  ListNode,
  REMOVE_LIST_COMMAND,
} from '@lexical/list';
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
import { $isDecoratorBlockNode } from '@lexical/react/LexicalDecoratorBlockNode';
import { INSERT_HORIZONTAL_RULE_COMMAND } from '@lexical/react/LexicalHorizontalRuleNode';
import { $createHeadingNode, $createQuoteNode, $isHeadingNode, HeadingTagType } from '@lexical/rich-text';
import { $selectAll, $setBlocksType } from '@lexical/selection';
import {
  $findMatchingParent,
  $getNearestBlockElementAncestorOrThrow,
  $getNearestNodeOfType,
  mergeRegister,
} from '@lexical/utils';

import { Button } from '../../../button';
import { Dialog } from '../../../dialog';
import { DropdownMenu } from '../../../dropdown-menu';
import { IconButton } from '../../../icon-button';
import { Icon } from '../../../iconography';
import { useTr } from '../../i18n';
import type { CrystallizeRichTextActionMenuItem } from '../../types/types';
import { IS_APPLE } from '../../utils/environment';
import { getSelectedNode } from '../../utils/getSelectedNode';
import { sanitizeUrl } from '../../utils/url';
import ActionsPlugin from './../ActionsPlugin';
import { InsertTableDialog } from './insert-table';

const headingTypeToBlockName: Record<HeadingTagType, string> = {
  h1: 'Heading 1',
  h2: 'Heading 2',
  h3: 'Heading 3',
  h4: 'Heading 4',
  h5: 'Heading 5',
  h6: 'Heading 6',
};
const headings = Object.keys(headingTypeToBlockName) as HeadingTagType[];

const blockTypeToBlockName = {
  ...headingTypeToBlockName,
  bullet: 'Bulleted List',
  check: 'Check List',
  code: 'Code Block',
  number: 'Numbered List',
  paragraph: 'Normal',
  quote: 'Quote',
};

function getCodeLanguageOptions(): [string, string][] {
  const options: [string, string][] = [];

  for (const [lang, friendlyName] of Object.entries(CODE_LANGUAGE_FRIENDLY_NAME_MAP)) {
    options.push([lang, friendlyName]);
  }

  return options;
}

const CODE_LANGUAGE_OPTIONS = getCodeLanguageOptions();

function dropDownActiveClass(active: boolean) {
  if (active) return 'active dropdown-item-active';
  else return '';
}

function BlockFormatDropDown({
  editor,
  blockType,
  disabled = false,
}: {
  blockType: keyof typeof blockTypeToBlockName;
  editor: LexicalEditor;
  disabled?: boolean;
}): JSX.Element {
  const formatParagraph = () => {
    if (blockType !== 'paragraph') {
      editor.update(() => {
        const selection = $getSelection();
        if ($isRangeSelection(selection) || DEPRECATED_$isGridSelection(selection))
          $setBlocksType(selection, () => $createParagraphNode());
      });
    }
  };

  const formatHeading = (headingSize: HeadingTagType) => {
    if (blockType !== headingSize) {
      editor.update(() => {
        const selection = $getSelection();
        if ($isRangeSelection(selection) || DEPRECATED_$isGridSelection(selection)) {
          $setBlocksType(selection, () => $createHeadingNode(headingSize));
        }
      });
    }
  };

  const formatBulletList = () => {
    if (blockType !== 'bullet') {
      editor.dispatchCommand(INSERT_UNORDERED_LIST_COMMAND, undefined);
    } else {
      editor.dispatchCommand(REMOVE_LIST_COMMAND, undefined);
    }
  };

  const formatNumberedList = () => {
    if (blockType !== 'number') {
      editor.dispatchCommand(INSERT_ORDERED_LIST_COMMAND, undefined);
    } else {
      editor.dispatchCommand(REMOVE_LIST_COMMAND, undefined);
    }
  };

  const formatQuote = () => {
    if (blockType !== 'quote') {
      editor.update(() => {
        const selection = $getSelection();
        if ($isRangeSelection(selection) || DEPRECATED_$isGridSelection(selection)) {
          $setBlocksType(selection, () => $createQuoteNode());
        } else {
          /**
           * Will select the entire editor, in case it is not selected. This is added
           * to get the unit tests working
           */
          $setBlocksType($getRoot().select(), () => $createQuoteNode());
        }
      });
    }
  };

  const formatCode = () => {
    if (blockType !== 'code') {
      editor.update(() => {
        let selection = $getSelection();

        if ($isRangeSelection(selection) || DEPRECATED_$isGridSelection(selection)) {
          if (selection.isCollapsed()) {
            $setBlocksType(selection, () => $createCodeNode());
          } else {
            const textContent = selection.getTextContent();
            const codeNode = $createCodeNode();
            selection.insertNodes([codeNode]);
            selection = $getSelection();
            if ($isRangeSelection(selection)) selection.insertRawText(textContent);
          }
        } else {
          /**
           * Will select the entire editor, in case it is not selected. This is added
           * to get the unit tests working
           */
          $setBlocksType($getRoot().select(), () => $createCodeNode());
        }
      });
    }
  };

  return (
    <DropdownMenu.Root
      disabled={disabled}
      style={{ zIndex: 1 }}
      content={
        <>
          <DropdownMenu.Item onClick={formatParagraph}>
            <i
              className={`icon paragraph border w-6 h-6 rounded-md bg-no-repeat bg-center bg-[length:18px_18px] ${
                blockType === 'paragraph' ? 'opacity-100 bg-purple-50-900' : 'opacity-60'
              }`}
            />

            <i className="icon paragraph" />
            <span className={`${blockType === 'paragraph' ? 'font-bold' : 'font-normal'} text-sm px-3  min-w-[150px]`}>
              Normal
            </span>
          </DropdownMenu.Item>
          {headings.map(headingSize => (
            <DropdownMenu.Item key={headingSize} onClick={() => formatHeading(headingSize)}>
              <i
                className={`icon ${headingSize} border w-6 h-6 rounded-md bg-no-repeat bg-center bg-[length:18px_18px]  ${
                  blockType === headingSize ? 'opacity-100 bg-purple-50-900' : 'opacity-60'
                }`}
              />
              <span className={`${blockType === headingSize ? 'font-bold' : 'font-normal'} text-sm px-3 min-w-[150px]`}>
                {headingTypeToBlockName[headingSize]}
              </span>
            </DropdownMenu.Item>
          ))}
          <DropdownMenu.Item onClick={formatBulletList}>
            <i
              className={`icon bullet-list border w-6 h-6 rounded-md bg-no-repeat bg-center bg-[length:18px_18px] ${
                blockType === 'bullet' ? 'opacity-100 bg-purple-50-900' : 'opacity-60'
              }`}
            />
            <span className={`${blockType === 'bullet' ? 'font-bold' : 'font-normal'} text-sm px-3  min-w-[150px]`}>
              Bullet List
            </span>
          </DropdownMenu.Item>
          <DropdownMenu.Item onClick={formatNumberedList}>
            <i
              className={`icon numbered-list border w-6 h-6 rounded-md bg-no-repeat bg-center bg-[length:18px_18px] ${
                blockType === 'number' ? 'opacity-100 bg-purple-50-900' : 'opacity-60'
              }`}
            />
            <span className={`${blockType === 'number' ? 'font-bold' : 'font-normal'} text-sm px-3  min-w-[150px]`}>
              Numbered List
            </span>
          </DropdownMenu.Item>
          <DropdownMenu.Item onClick={formatQuote} data-testid="toggle-block-format-quote">
            <i
              className={`icon quote border w-6 h-6 rounded-md bg-no-repeat bg-center bg-[length:18px_18px] ${
                blockType === 'quote' ? 'opacity-100 bg-purple-50-900' : 'opacity-60'
              }`}
            />
            <span className={`${blockType === 'quote' ? 'font-bold' : 'font-normal'} text-sm px-3  min-w-[150px]`}>
              Quote
            </span>
          </DropdownMenu.Item>
          <DropdownMenu.Item onClick={formatCode} data-testid="toggle-block-format-code">
            <i
              className={`icon code border w-6 h-6 rounded-md bg-no-repeat bg-center bg-[length:18px_18px] ${
                blockType === 'code' ? 'opacity-100 bg-purple-50-900' : 'opacity-60'
              }`}
            />
            <span className={`${blockType === 'code' ? 'font-bold' : 'font-normal'} text-sm px-3  min-w-[150px]`}>
              Code block
            </span>
          </DropdownMenu.Item>
        </>
      }
    >
      <Button
        style={{ backgroundColor: 'transparent', padding: '0 8px' }}
        aria-label="Formatting options for text style"
        data-testid="toggle-block-format"
      >
        <i className={`icon ${blockType} border bg-no-repeat bg-center bg-[length:18px_18px] w-6 h-6`} />
        <Icon.Arrow />
      </Button>
    </DropdownMenu.Root>
  );
}

function Divider(): JSX.Element {
  return <div className="divider" />;
}

export default function ToolbarPlugin({
  actionsMenuPrepend,
  actionsMenuAppend,
}: {
  actionsMenuPrepend?: CrystallizeRichTextActionMenuItem[];
  actionsMenuAppend?: CrystallizeRichTextActionMenuItem[];
}): JSX.Element {
  const [editor] = useLexicalComposerContext();
  const [activeEditor, setActiveEditor] = useState(editor);
  const [blockType, setBlockType] = useState<keyof typeof blockTypeToBlockName>('paragraph');
  const [selectedElementKey, setSelectedElementKey] = useState<NodeKey | null>(null);
  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 [canUndo, setCanUndo] = useState(false);
  const [canRedo, setCanRedo] = useState(false);
  const tr = useTr();

  const [codeLanguage, setCodeLanguage] = useState<string>('');
  const [isEditable, setIsEditable] = useState(() => editor.isEditable());

  const updateToolbar = useCallback(() => {
    const selection = $getSelection();
    if ($isRangeSelection(selection)) {
      const anchorNode = selection.anchor.getNode();
      let element =
        anchorNode.getKey() === 'root'
          ? anchorNode
          : $findMatchingParent(anchorNode, e => {
              const parent = e.getParent();
              return parent !== null && $isRootOrShadowRoot(parent);
            });

      if (element === null) {
        element = anchorNode.getTopLevelElementOrThrow();
      }

      const elementKey = element.getKey();
      const elementDOM = activeEditor.getElementByKey(elementKey);

      // Update text format
      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'));

      // Update links
      const node = getSelectedNode(selection);
      const parent = node.getParent();
      if ($isLinkNode(parent) || $isLinkNode(node)) {
        setIsLink(true);
      } else {
        setIsLink(false);
      }

      if (elementDOM !== null) {
        setSelectedElementKey(elementKey);
        if ($isListNode(element)) {
          const parentList = $getNearestNodeOfType<ListNode>(anchorNode, ListNode);
          const type = parentList ? parentList.getListType() : element.getListType();
          setBlockType(type);
        } else {
          const type = $isHeadingNode(element) ? element.getTag() : element.getType();
          if (type in blockTypeToBlockName) {
            setBlockType(type as keyof typeof blockTypeToBlockName);
          }
          if ($isCodeNode(element)) {
            const language = element.getLanguage() as keyof typeof CODE_LANGUAGE_MAP;
            setCodeLanguage(language ? CODE_LANGUAGE_MAP[language] || language : '');
            return;
          }
        }
      }
    }
  }, [activeEditor]);

  useEffect(() => {
    return editor.registerCommand(
      SELECTION_CHANGE_COMMAND,
      (_payload, newEditor) => {
        updateToolbar();
        setActiveEditor(newEditor);
        return false;
      },
      COMMAND_PRIORITY_CRITICAL,
    );
  }, [editor, updateToolbar]);

  useEffect(() => {
    return mergeRegister(
      editor.registerEditableListener(editable => {
        setIsEditable(editable);
      }),
      activeEditor.registerUpdateListener(({ editorState }) => {
        editorState.read(() => {
          updateToolbar();
        });
      }),
      activeEditor.registerCommand<boolean>(
        CAN_UNDO_COMMAND,
        payload => {
          setCanUndo(payload);
          return false;
        },
        COMMAND_PRIORITY_CRITICAL,
      ),
      activeEditor.registerCommand<boolean>(
        CAN_REDO_COMMAND,
        payload => {
          setCanRedo(payload);
          return false;
        },
        COMMAND_PRIORITY_CRITICAL,
      ),
    );
  }, [activeEditor, editor, updateToolbar]);

  const clearFormatting = useCallback(() => {
    activeEditor.update(() => {
      const selection = $getSelection();
      if ($isRangeSelection(selection)) {
        $selectAll(selection);
        selection.getNodes().forEach(node => {
          if ($isTextNode(node)) {
            node.setFormat(0);
            node.setStyle('');
            $getNearestBlockElementAncestorOrThrow(node).setFormat('');
          }
          if ($isDecoratorBlockNode(node)) {
            node.setFormat('');
          }
        });
      }
    });
  }, [activeEditor]);

  const insertLink = useCallback(() => {
    if (!isLink) {
      editor.dispatchCommand(TOGGLE_LINK_COMMAND, sanitizeUrl('https://'));
    } else {
      editor.dispatchCommand(TOGGLE_LINK_COMMAND, null);
    }
  }, [editor, isLink]);

  const onCodeLanguageSelect = useCallback(
    (value: string) => {
      activeEditor.update(() => {
        if (selectedElementKey !== null) {
          const node = $getNodeByKey(selectedElementKey);
          if ($isCodeNode(node)) {
            node.setLanguage(value);
          }
        }
      });
    },
    [activeEditor, selectedElementKey],
  );

  return (
    <div className="toolbar">
      <div className="flex">
        <IconButton
          disabled={!canUndo || !isEditable}
          onClick={() => {
            activeEditor.dispatchCommand(UNDO_COMMAND, undefined);
          }}
          type="button"
          title={tr(IS_APPLE ? 'actionUndoTitleApple' : 'actionUndoTitle')}
          aria-label={tr('actionUndoLabel')}
        >
          <i
            className={`format icon undo border w-4 h-6 bg-no-repeat bg-center bg-[length:17px_17px] ${
              canUndo ? 'opacity-100' : 'opacity-30'
            }
        `}
          />
        </IconButton>
        <IconButton
          disabled={!canRedo || !isEditable}
          onClick={() => {
            activeEditor.dispatchCommand(REDO_COMMAND, undefined);
          }}
          type="button"
          title={tr(IS_APPLE ? 'actionRedoTitleApple' : 'actionRedoTitle')}
          aria-label={tr('actionRedoLabel')}
        >
          <i
            className={`format icon redo border w-4 h-6 bg-no-repeat bg-center bg-[length:17px_17px] ${
              canRedo ? 'opacity-100' : 'opacity-30'
            }`}
          />
        </IconButton>
        <Divider />
        {blockType in blockTypeToBlockName && activeEditor === editor && (
          <>
            <BlockFormatDropDown disabled={!isEditable} blockType={blockType} editor={editor} />
            <Divider />
          </>
        )}
        {blockType === 'code' ? (
          <>
            <DropdownMenu.Root
              disabled={!isEditable}
              style={{ zIndex: 1 }}
              content={
                <>
                  {CODE_LANGUAGE_OPTIONS.map(([value, name]) => {
                    return (
                      <DropdownMenu.Item
                        className={`item ${dropDownActiveClass(value === codeLanguage)}`}
                        onClick={() => onCodeLanguageSelect(value)}
                        key={value}
                      >
                        <span
                          className={`text min-w-[200px] block text-sm px-3 ${
                            dropDownActiveClass(value === codeLanguage)
                              ? 'font-bold opacity-100'
                              : 'font-normal opacity-80'
                          }`}
                        >
                          {name}
                        </span>
                      </DropdownMenu.Item>
                    );
                  })}
                </>
              }
            >
              <Button aria-label={tr('codeSelectLanguage')} append={<Icon.Arrow />}>
                <span className="font-medium text-sm">{getLanguageFriendlyName(codeLanguage)}</span>
              </Button>
            </DropdownMenu.Root>
          </>
        ) : (
          <Dialog>
            <div className="flex gap-1">
              <IconButton
                disabled={!isEditable}
                className={`${isBold ? 'opacity-100 !bg-purple-50-900' : 'opacity-60'}`}
                type="button"
                title={tr(IS_APPLE ? 'actionFormatAsStrongTitleApple' : 'actionFormatAsStrongTitle')}
                aria-label={tr('actionFormatAsStrongLabel')}
                data-testid="toggle-format-bold"
                onClick={() => {
                  activeEditor.dispatchCommand(FORMAT_TEXT_COMMAND, 'bold');
                }}
              >
                <i className={`format icon bold border w-full h-full bg-no-repeat bg-center bg-[length:18px_18px]`} />
              </IconButton>
              <IconButton
                className={`${isItalic ? 'opacity-100 !bg-purple-50-900' : 'opacity-60'}`}
                disabled={!isEditable}
                onClick={() => {
                  activeEditor.dispatchCommand(FORMAT_TEXT_COMMAND, 'italic');
                }}
                type="button"
                title={tr(IS_APPLE ? 'actionFormatAsEmphasizedTitleApple' : 'actionFormatAsEmphasizedTitle')}
                aria-label={tr('actionFormatAsEmphasizedLabel')}
                data-testid="toggle-format-emphasized"
              >
                <i className={`format icon italic border w-full h-full bg-no-repeat bg-center bg-[length:18px_18px]`} />
              </IconButton>

              <IconButton
                className={`${isUnderline ? 'opacity-100 !bg-purple-50-900' : 'opacity-60'}`}
                disabled={!isEditable}
                onClick={() => {
                  activeEditor.dispatchCommand(FORMAT_TEXT_COMMAND, 'underline');
                }}
                type="button"
                title={tr(IS_APPLE ? 'actionFormatAsUnderlinedTitleApple' : 'actionFormatAsUnderlinedTitle')}
                aria-label={tr('actionFormatAsUnderlinedLabel')}
                data-testid="toggle-format-underlined"
              >
                <i
                  className={`format icon underline border w-full h-full bg-no-repeat bg-center bg-[length:18px_18px]`}
                />
              </IconButton>

              <IconButton
                className={`${isCode ? 'opacity-100 !bg-purple-50-900' : 'opacity-60'}`}
                disabled={!isEditable}
                onClick={() => {
                  activeEditor.dispatchCommand(FORMAT_TEXT_COMMAND, 'code');
                }}
                type="button"
                title={tr('actionInsertCodeBlock')}
                aria-label={tr('actionInsertCodeBlock')}
              >
                <i className={`format icon code border w-full h-full bg-no-repeat bg-center bg-[length:18px_18px]`} />
              </IconButton>

              <IconButton
                className={`${isLink ? 'opacity-100 !bg-purple-50-900' : 'opacity-60'}`}
                disabled={!isEditable}
                onClick={insertLink}
                type="button"
                aria-label={tr('actionInsertlink')}
                title={tr('actionInsertlink')}
              >
                <i className={`format icon link border w-full h-full bg-no-repeat bg-center bg-[length:18px_18px]`} />
              </IconButton>

              <DropdownMenu.Root
                disabled={!isEditable}
                style={{ zIndex: 1 }}
                content={
                  <>
                    <DropdownMenu.Item
                      onClick={() => {
                        activeEditor.dispatchCommand(FORMAT_TEXT_COMMAND, 'strikethrough');
                      }}
                      title={tr('actionFormatWithStrikethroughTitle')}
                      aria-label={tr('actionFormatWithStrikethroughLabel')}
                    >
                      <i
                        className={`icon w-6 h-6 strikethrough border bg-no-repeat bg-center bg-[length:16px_16px]  rounded-sm ${
                          isStrikethrough ? 'opacity-100 !bg-purple-50-900' : 'opacity-60'
                        }`}
                      />
                      <span className={`px-3 text-sm font-sans ${isStrikethrough ? 'font-medium' : 'font-normal'}`}>
                        {tr('actionFormatAsStrongTitle')}
                      </span>
                    </DropdownMenu.Item>
                    <DropdownMenu.Item
                      onClick={() => {
                        activeEditor.dispatchCommand(FORMAT_TEXT_COMMAND, 'subscript');
                      }}
                      title={tr('actionFormatWithSubscriptTitle')}
                      aria-label={tr('actionFormatWithSubscriptLabel')}
                    >
                      <i
                        className={`icon w-6 h-6 subscript border bg-no-repeat bg-center bg-[length:16px_16px]  rounded-sm ${
                          isSubscript ? 'opacity-100 !bg-purple-50-900' : 'opacity-60'
                        }`}
                      />
                      <span className={`px-3 text-sm font-sans ${isSubscript ? 'font-medium' : 'font-normal'}`}>
                        {tr('actionFormatWithSubscriptTitle')}
                      </span>
                    </DropdownMenu.Item>
                    <DropdownMenu.Item
                      onClick={() => {
                        activeEditor.dispatchCommand(FORMAT_TEXT_COMMAND, 'superscript');
                      }}
                      title={tr('actionFormatWithSuperscriptTitle')}
                      aria-label={tr('actionFormatWithSuperscriptLabel')}
                    >
                      <i
                        className={`icon w-6 h-6 superscript border bg-no-repeat bg-center bg-[length:16px_16px]  rounded-sm ${
                          isSuperscript ? 'opacity-100 !bg-purple-50-900' : 'opacity-60'
                        }`}
                      />
                      <span className={`px-3 text-sm font-sans ${isSuperscript ? 'bg-purple-50-900' : 'font-normal'}`}>
                        {tr('actionFormatWithSuperscriptTitle')}
                      </span>
                    </DropdownMenu.Item>
                    <DropdownMenu.Item
                      onClick={clearFormatting}
                      className="item"
                      title={tr('actionClearTextFormatting')}
                      aria-label={tr('actionClearTextFormatting')}
                    >
                      <i className="icon w-6 h-6 clear border bg-no-repeat bg-center bg-[length:16px_16px] opacity-60" />
                      <span className="px-3 text-sm text-pink-600-300 font-sans font-normal">Clear Formatting</span>
                    </DropdownMenu.Item>
                  </>
                }
              >
                <Button
                  style={{ backgroundColor: 'transparent', padding: '0 8px' }}
                  aria-label={tr('actionTextFormattingOptions')}
                >
                  <i className={`icon dropdown-more border bg-no-repeat bg-center bg-[length:18px_18px] w-6 h-6`} />
                  <Icon.Arrow />
                </Button>
              </DropdownMenu.Root>
              <Divider />
              <DropdownMenu.Root
                style={{ zIndex: 1 }}
                disabled={!isEditable}
                content={
                  <>
                    <DropdownMenu.Item
                      onClick={() => {
                        activeEditor.dispatchCommand(INSERT_HORIZONTAL_RULE_COMMAND, undefined);
                      }}
                    >
                      <div className="flex items-center font-sans font-normal">
                        <i className="icon w-5 h-5 horizontal-rule border bg-no-repeat bg-center bg-[length:16px_16px] opacity-60" />
                        <span className="px-3 text-sm">{tr('horizontalRule')}</span>
                      </div>
                    </DropdownMenu.Item>
                    <DropdownMenu.Item>
                      <Dialog.Trigger asChild>
                        <div className="flex items-center font-sans font-normal">
                          <i className="icon w-5 h-5 table border bg-no-repeat bg-center bg-[length:16px_16px] opacity-60" />
                          <span className="px-3 text-sm">{tr('table')}</span>
                        </div>
                      </Dialog.Trigger>
                    </DropdownMenu.Item>
                  </>
                }
              >
                <IconButton>
                  <i className="icon plus border w-full h-full bg-no-repeat bg-center bg-[length:20px_20px] " />
                </IconButton>
              </DropdownMenu.Root>
              <Dialog.Content>
                <Dialog.Title>{tr('insertTableTitle')}</Dialog.Title>
                <Dialog.Description>{tr('insertTableDescription')}</Dialog.Description>
                <div className="items-center justify-between">
                  <InsertTableDialog activeEditor={activeEditor} />
                </div>
              </Dialog.Content>
            </div>
          </Dialog>
        )}
      </div>
      <ActionsPlugin prepend={actionsMenuPrepend} append={actionsMenuAppend} />
    </div>
  );
}
