import { createContext, useEffect, useState } from 'react';
import ExampleTheme from "./themes/ExampleTheme";
import { LexicalComposer } from "@lexical/react/LexicalComposer";
import { RichTextPlugin } from "@lexical/react/LexicalRichTextPlugin";
import {PlainTextPlugin} from '@lexical/react/LexicalPlainTextPlugin';
import { ContentEditable } from "@lexical/react/LexicalContentEditable";
import { HistoryPlugin } from "@lexical/react/LexicalHistoryPlugin";
import { AutoFocusPlugin } from "@lexical/react/LexicalAutoFocusPlugin";
import {LexicalErrorBoundary} from "@lexical/react/LexicalErrorBoundary";
import {TabIndentationPlugin} from '@lexical/react/LexicalTabIndentationPlugin';
import TreeViewPlugin from "./plugins/TreeViewPlugin";
import ToolbarPlugin from "./plugins/ToolbarPlugin";
import { HeadingNode, QuoteNode } from "@lexical/rich-text";
import { TableCellNode, TableNode, TableRowNode } from "@lexical/table";
import { ListItemNode, ListNode } from "@lexical/list";
import { CodeHighlightNode, CodeNode } from "@lexical/code";
import { AutoLinkNode, LinkNode } from "@lexical/link";
// import {ClickableLinkPlugin} from '@lexical/react/LexicalClickableLinkPlugin';
import { LinkPlugin } from "@lexical/react/LexicalLinkPlugin";
import { ListPlugin } from "@lexical/react/LexicalListPlugin";
import { MarkdownShortcutPlugin } from "@lexical/react/LexicalMarkdownShortcutPlugin";
import {HorizontalRulePlugin} from '@lexical/react/LexicalHorizontalRulePlugin';
import {HorizontalRuleNode} from '@lexical/react/LexicalHorizontalRuleNode';
import { TRANSFORMERS } from "@lexical/markdown";

import ListMaxIndentLevelPlugin from "./plugins/ListMaxIndentLevelPlugin";
import CodeHighlightPlugin from "./plugins/CodeHighlightPlugin";
import AutoLinkPlugin from "./plugins/AutoLinkPlugin";
import TabFocusPlugin from './plugins/TabFocusPlugin';
import EditorRefPlugin from './plugins/EditorRefPlugin'
import ImagesPlugin from './plugins/ImagesPlugin';
import InlineImagePlugin from './plugins/InlineImagePlugin';
import DragDropPaste from './plugins/DragDropPastePlugin';
import { ImageNode } from './nodes/ImageNode';
import {InlineImageNode} from './nodes/InlineImageNode/InlineImageNode';
import { ExtendedTextNode } from './nodes/ExtendedTextNode';

import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
// import { useLexicalEditable } from '@lexical/react/useLexicalEditable';

import {TablePlugin} from '@lexical/react/LexicalTablePlugin';
import TableCellActionMenuPlugin from './plugins/TableActionMenuPlugin';
import TableCellResizer from './plugins/TableCellResizer';
// import TableHoverActionsPlugin from './plugins/TableHoverActionsPlugin';

// import {useLexicalEditable} from '@lexical/react/useLexicalEditable';


import { TextNode, $getRoot, $getSelection, $createParagraphNode } from 'lexical';
import { $generateHtmlFromNodes, $generateNodesFromDOM, } from '@lexical/html';
// import {  } from '@lexical/clipboard';
import { isEmpty } from '@/utils/commons';
import {useSettings} from './context/SettingsContext';

import './styles.css';

function Placeholder() {
  return <div className="editor-placeholder">Enter some rich text...</div>;
}

const editorConfig = {
  // The editor theme
  // theme: {},
  theme: ExampleTheme,
  // Handling of errors during update
  onError(error) {
    console.log(error)
    throw error;
  },
  // Any custom nodes go here
  nodes: [
    ExtendedTextNode,
    {
      replace: TextNode,
      with: (node) => new ExtendedTextNode(node.__text),
      withKlass: ExtendedTextNode,
    },
    HeadingNode,
    ListNode,
    ListItemNode,
    QuoteNode,
    CodeNode,
    CodeHighlightNode,
    TableNode,
    TableCellNode,
    TableRowNode,
    AutoLinkNode,
    LinkNode,
    HorizontalRuleNode,
    ImageNode,InlineImageNode,
  ]
};

function LexicalDefaultValuePlugin({ value = '' }= {}) {
  const [editor] = useLexicalComposerContext();

  const updateHTML = (editor, value, clear) => {
    const root = $getRoot();
    if (clear) {
      root.clear();
    }

    if (isEmpty(value)) {
      root.clear();
    } else {
      const parser = new DOMParser();
      const dom = parser.parseFromString(value, "text/html");
      const nodes = $generateNodesFromDOM(editor, dom);
      nodes.filter(n => n.__size !== 0).forEach((n) => {
        const paragraphNode = $createParagraphNode();
        paragraphNode.append(n);
        root.append(paragraphNode);
      });
    }
  };

  useEffect(() => {
    if (editor) {
      editor.update(() => {
        updateHTML(editor, value, true);
      });
    }
  }, [editor, value]);

  return null;
}
function MyOnChangePlugin({ ignoreHistoryMergeTagChange = true, ignoreSelectionChange = true, onChange }) {
  const [editor] = useLexicalComposerContext();
  useEffect(() => {
    if (typeof onChange === 'function') {
      return editor.registerUpdateListener(({editorState, dirtyElements, dirtyLeaves, prevEditorState, tags}) => {

        if (
          (ignoreSelectionChange &&
            dirtyElements.size === 0 &&
            dirtyLeaves.size === 0) ||
          (ignoreHistoryMergeTagChange && tags.has('history-merge')) ||
          prevEditorState.isEmpty()
        ) {
          return;
        }
        editorState.read(() => {
          const root = $getRoot();
          const textContent = root.getTextContent();
          const html = $generateHtmlFromNodes(editor);
          onChange({ editorStateJSON: editorState.toJSON(), editor, tags, htmlContent: html, textContent });
        });
      });
    }
  }, [editor, ignoreHistoryMergeTagChange, ignoreSelectionChange, onChange]);

  return null;
}
export default function Editor({ isRichText, isDebug, editorRef, onChange, defaultValue, stateJson, ...props }) {
  const {
    settings: {
      isCollab,
      isAutocomplete,
      isMaxLength,
      isCharLimit,
      isCharLimitUtf8,
      // isRichText,
      showTreeView,
      showTableOfContents,
      shouldUseLexicalContextMenu,
      shouldPreserveNewLinesInMarkdown,
      tableCellMerge,
      tableCellBackgroundColor,
    },
  } = useSettings();
  return (
    <LexicalComposer initialConfig={editorConfig}>
      <div className='editor-container'>
        {isRichText && <ToolbarPlugin />}
        <div className='editor-inner'>
          {/* <LexicalPlainText /> */}
          {isRichText ? (
            <RichTextPlugin contentEditable={<ContentEditable className='editor-input' />} placeholder={<Placeholder />} ErrorBoundary={LexicalErrorBoundary} />
          ) : (
            <PlainTextPlugin contentEditable={<ContentEditable className='editor-pure-input' />} ErrorBoundary={LexicalErrorBoundary} />
          )}
          <HistoryPlugin />
          {(import.meta.env.DEV && isDebug) && <TreeViewPlugin />}
          <LexicalDefaultValuePlugin value={defaultValue} />
          <DragDropPaste />
          <AutoFocusPlugin />
          <CodeHighlightPlugin />
          <ListPlugin />
          <ListMaxIndentLevelPlugin maxDepth={7} />
          <AutoLinkPlugin />
          <LinkPlugin />
          <MarkdownShortcutPlugin transformers={TRANSFORMERS} />
          <TablePlugin hasCellMerge={tableCellMerge} hasCellBackgroundColor={tableCellBackgroundColor} />
          <TableCellResizer />
          {/* <TableHoverActionsPlugin /> */}
          <TableCellActionMenuPlugin
            // anchorElem={floatingAnchorElem}
            cellMerge={true}
          />
          <TabFocusPlugin />
          <TabIndentationPlugin />
          <HorizontalRulePlugin />
          <EditorRefPlugin editorRef={editorRef} />
          <ImagesPlugin />
          <InlineImagePlugin />
          <MyOnChangePlugin onChange={onChange}/>
        </div>
      </div>
    </LexicalComposer>
  );
}
