import ExampleTheme from "./themes/ExampleTheme";
import {LexicalComposer} from "@lexical/react/LexicalComposer";
import {RichTextPlugin} from "@lexical/react/LexicalRichTextPlugin";
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 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, $createCodeNode, $isCodeNode} from "@lexical/code";
import {AutoLinkNode, LinkNode} from "@lexical/link";
import {MarkdownShortcutPlugin} from "@lexical/react/LexicalMarkdownShortcutPlugin";
import {
    TRANSFORMERS, $convertFromMarkdownString,
    $convertToMarkdownString,
} from "@lexical/markdown";
import "./index.less"
import {useEffect, useId, useState} from 'react';
import {useLexicalComposerContext} from '@lexical/react/LexicalComposerContext';
import {importFile, overWriteFile, saveFileWithName} from "../../../utils/File"
import {$getRoot, CLEAR_HISTORY_COMMAND, $createTextNode,} from "lexical";
import md5 from "md5"
import {isEmpty} from "../../../utils/ObjectUtils";
import {useDispatch, useSelector} from "react-redux";
import {updatedSavedFile} from "../../../redux/tableBarItem_reducer";
import {ListPlugin} from "@lexical/react/LexicalListPlugin";
import {LinkPlugin} from "@lexical/react/LexicalLinkPlugin";
import AutoLinkPlugin from "./plugins/AutoLinkPlugin";
import ListMaxIndentLevelPlugin from "./plugins/ListMaxIndentLevelPlugin";
import CodeHighlightPlugin from "./plugins/CodeHighlightPlugin";
import {getFileNameByPath} from "../../../utils/PathOperate";

const {ipcRenderer} = window.require('electron')

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

const editorConfig = {
    // The editor theme
    theme: ExampleTheme,
    // Handling of errors during update
    onError(error) {
        throw error;
    },
    // Any custom nodes go here
    nodes: [
        HeadingNode,
        ListNode,
        ListItemNode,
        QuoteNode,
        CodeNode,
        CodeHighlightNode,
        TableNode,
        TableCellNode,
        TableRowNode,
        AutoLinkNode,
        LinkNode
    ]
};

function OnChangePlugin({onChange}) {
    const [editor] = useLexicalComposerContext();
    console.log('editor', editor)
    useEffect(() => {
        return editor.registerUpdateListener(({editorState}) => {
            onChange(editorState);
        });
    }, [editor, onChange]);
}

function ImportFilePlugin(props) {
    const [editor] = useLexicalComposerContext();
    useEffect(() => {
        if (props.filePath) {
            importFile(props.filePath).then(value => {
                if (isEmpty(value)) {
                    return
                }
                if (props.filePath.endsWith(".md")) {
                    const root = $getRoot();
                    const firstChild = root.getFirstChild();
                    if ($isCodeNode(firstChild) && firstChild.getLanguage() === 'markdown') {
                        $convertFromMarkdownString(
                            firstChild.getTextContent(),
                            PLAYGROUND_TRANSFORMERS,
                        );
                    } else {
                        const markdown = $convertToMarkdownString(PLAYGROUND_TRANSFORMERS);
                        root
                            .clear()
                            .append(
                                $createCodeNode('markdown').append($createTextNode(markdown)),
                            );
                    }
                    root.selectEnd();
                } else {
                    const editorState = editor.parseEditorState(
                        JSON.stringify(JSON.parse(value.toString()).editorState)
                    );
                    editor.setEditorState(editorState);
                    editor.dispatchCommand(CLEAR_HISTORY_COMMAND, undefined);
                }
            }).catch(error =>
                console.error(error)
            )
        }
    }, [])
}


// 从字符串化 JSON 设置编辑器状态
// const editorState = editor.parseEditorState(editorStateJSONString);
// editor.setEditorState(editorState);

export default function Hlexical(props) {
    console.log("Hlexical(props):this.props.filePath:", props.filePath)
    const [editorState, setEditorState] = useState();
    const dispatch = useDispatch();

    function onChange(editorState) {
        // Call toJSON on the EditorState object, which produces a serialization safe string
        const editorStateJSON = editorState.toJSON();
        console.log('onChange-editorStateJSON')
        // However, we still have a JavaScript object, so we need to convert it to an actual string with JSON.stringify
        setEditorState(JSON.stringify(editorStateJSON));
    }

    let pushHotKey = useSelector(state => state.pushHotkeys.data);
    let activeKey = useSelector(state => state.tableBarItem.activeKey);
    const saveFile = (event, args) => {
        console.log("event,args:", event, args)
        console.log("触发保存pushHotKey:", pushHotKey)
        if (pushHotKey !== "CTRL+S") {
            return
        }
        let filePath = props.filePath;
        if (filePath !== activeKey) {
            console.log("文件不同", filePath, activeKey)
            return;
        }
        console.log("触发保存filePath:", filePath)
        if (isEmpty(editorState)) {
            return
        }
        const editorStateSave = {"editorState": JSON.parse(editorState)};
        let resultSave = JSON.stringify(editorStateSave);

        // 如果文件地址为空需要用户选择目录并设置文件。
        if (!filePath) {
            let saveDialogReturnValuePromise = saveFileWithName();
            console.log("saveDialogReturnValuePromise", saveDialogReturnValuePromise)
            saveDialogReturnValuePromise.then(result => {
                if (!result.canceled) {
                    let fileKey = getFileNameByPath(result.filePath)
                    if (isEmpty(fileKey)){
                        fileKey = fileKey+".lexical"
                    }
                    overWriteFile(fileKey, resultSave)
                    // 修改当前文件名
                    dispatch(updatedSavedFile({filePath: result.filePath}))
                    // 文件目录更新
                    dispatch()
                }
            })
            return
        }
        importFile(filePath).then(value => {
            let save = (isEmpty(value)) || md5(resultSave) !== md5(JSON.stringify(JSON.parse(value.toString())));
            if (save) {
                console.log("保存重写" + filePath)
                overWriteFile(filePath, resultSave)
            }
        }).catch(error =>
            console.error(error)
        )
    }
    useEffect(() => {
            ipcRenderer.on("pushHotkeys", saveFile);
            return () => {
                console.log("销毁取消监听");
                ipcRenderer.removeListener("pushHotkeys", saveFile)
            };
        }
    )


    return (
        <LexicalComposer initialConfig={editorConfig}>
            <div className="editor-container">
                {/* 富文本插件 */}
                <ToolbarPlugin/>
                <div className="editor-inner">
                    <RichTextPlugin
                        contentEditable={<ContentEditable className="editor-input"/>}
                        placeholder={<Placeholder/>}
                        ErrorBoundary={LexicalErrorBoundary}
                    />
                    <HistoryPlugin/>
                    {/*黑窗口动态记录当前操作*/}
                    {/*<TreeViewPlugin/>*/}

                    <AutoFocusPlugin/>
                    <CodeHighlightPlugin/>
                    <ListPlugin/>
                    <LinkPlugin/>
                    <AutoLinkPlugin/>
                    <ListMaxIndentLevelPlugin maxDepth={7}/>
                    {/*markdown 快捷键*/}
                    <MarkdownShortcutPlugin transformers={TRANSFORMERS}/>
                    <OnChangePlugin onChange={onChange}/>
                    <ImportFilePlugin filePath={props.filePath}/>
                    {/*文件操作导入文件*/}
                    {/*<ActionPlugin/>*/}
                </div>
            </div>
        </LexicalComposer>
    );
}
