<script setup lang="ts">
import type {Ref} from "vue";
import {onMounted, reactive, ref, watch} from "vue";

// 编辑器本体
import '@toast-ui/editor/dist/toastui-editor.css';
import "@toast-ui/editor/dist/i18n/zh-cn";
import Editor from "@toast-ui/editor";

// 代码高亮样式
import Prism from 'prismjs'
import 'prismjs/themes/prism.css';
import '@toast-ui/editor-plugin-code-syntax-highlight/dist/toastui-editor-plugin-code-syntax-highlight.css';
import codeSyntaxHighlight from '@toast-ui/editor-plugin-code-syntax-highlight'
// 字体颜色
import 'tui-color-picker/dist/tui-color-picker.css'
import "@toast-ui/editor-plugin-color-syntax/dist/toastui-editor-plugin-color-syntax.css"
import colorSyntax from "@toast-ui/editor-plugin-color-syntax"
// 表格插件
import chart from "@toast-ui/editor-plugin-chart"
// 单元格合并
import tableMergedCell from "@toast-ui/editor-plugin-table-merged-cell"
// uml 插件
import uml from "@toast-ui/editor-plugin-uml"

import {useI18n} from "vue-i18n";
import {OpenFileDialog, SaveFileDialog} from "../../../wailsjs/go/core/App";
import {useApi} from "@/api";
import {ElMessage} from "element-plus";

const emit = defineEmits([
    "update:modelValue"
])
const props = defineProps({
    modelValue: {
        type: String,
        default: ""
    }
})
const chartOptions = {
    minWidth: 100,
    maxWidth: 600,
    minHeight: 100,
    maxHeight: 300
};

const {t, locale} = useI18n()

const editorRef = ref()

function initEditor(editorRef: Ref<any>) {
    let editor = new Editor({
        theme: "dark",
        el: editorRef.value,
        language: locale.value,
        previewStyle: 'vertical',
        height: '85vh',
        initialValue: props.modelValue,
        plugins: [
            [chart, chartOptions],
            [codeSyntaxHighlight, {highlighter: Prism}],
            tableMergedCell,
            uml,
            colorSyntax,
        ],
        useCommandShortcut: true,
        usageStatistics: true,
        hideModeSwitch: false,
        events: {
            change: () => emit('update:modelValue', editor.getMarkdown()),
        },
        // toolbarItems: [
        //     ['heading', 'bold', 'italic', 'strike'],
        //     ['hr', 'quote'],
        //     ['ul', 'ol', 'task', 'indent', 'outdent'],
        //     ['table', 'image', 'link'],
        //     ['code', 'codeblock'],
        //     ['scrollSync'],
        // ]
    })


    // const viewer = Editor.factory({
    //     el: editorRef.value,
    //     viewer: true,
    //     height: '500px',
    //     initialValue: "",
    //     plugins: [[chart, chartOptions], [codeSyntaxHighlight, { highlighter: Prism }], tableMergedCell, uml]
    // });

    return editor;
}

let editor: any = {}
onMounted(() => {
    editor = initEditor(editorRef);
    watch(locale, value => {
        let markdown = editor.getMarkdown()
        editor.destroy()

        editor = initEditor(editorRef);
        editor.setMarkdown(markdown)
    })
})

const ctx = reactive({
    openFilePath: ""
})

function openFile() {
    OpenFileDialog({
        title: `${t("general.open")} markdown ${t("general.file")}`,
        filters: [
            {
                displayName: "Markdown",
                pattern: "*.md;*.markdown"
            }
        ]
    }).then(path => {
        console.log(path)

        if (!path) {
            return
        }

        useApi().readFile({path}).then(resp => {
            ctx.openFilePath = path
            editor.setMarkdown(resp.data)
        })
    })
}

function getDir(path: string) {
    let position = path.lastIndexOf("/")
    if (position === -1) {
        position = path.lastIndexOf("\\")
    }

    return path.substring(0, position)
}

function getFileName(path: string) {
    let position = path.lastIndexOf("/")
    if (position === -1) {
        position = path.lastIndexOf("\\")
    }

    return path.substring(position + 1)
}


function createFile() {
    SaveFileDialog({
        title: `${t("general.new")} markdown ${t("general.file")}`,
        filters: [
            {
                displayName: "Markdown",
                pattern: "*.md;*.markdown"
            }
        ]
    }).then(path => {
        ctx.openFilePath = path
        editor.setMarkdown("")
    })
}

function saveFile(saveAs: boolean = false) {

    function writeFile() {
        useApi().saveFile({
            fileName: ctx.openFilePath,
            data: new Blob([editor.getMarkdown()], {
                type: 'text/plain'
            })
        }).then(resp => {
            let res = resp.data
            if (res.code === 200) {
                ElMessage.success(res.data)
            } else {
                ElMessage.error(res.msg)
            }
        })
    }


    if (ctx.openFilePath && !saveAs) {
        writeFile()
    } else {
        SaveFileDialog({
            title: `${t("general.save")} markdown ${t("general.file")}`,
            defaultDirectory: getDir(ctx.openFilePath),
            defaultFileName: getFileName(ctx.openFilePath),
            filters: [
                {
                    displayName: "Markdown",
                    pattern: "*.md;*.markdown"
                }
            ]
        }).then(path => {
            console.log(path)
            ctx.openFilePath = path

            if (!path) {
                return
            }

            writeFile()
        })
    }
}
</script>

<template>
    <el-button type="primary" @click="createFile">{{ t("general.new") }}</el-button>
    <el-button type="primary" @click="openFile">{{ t("general.open") }}</el-button>
    <el-button type="success" :disabled="!ctx.openFilePath" @click="saveFile()">{{ t("general.save") }}</el-button>
    <el-button type="success" @click="saveFile(true)">{{ t("general.saveAs") }}</el-button>
    <div ref="editorRef" class="overscroll-none"/>
</template>

<style scoped lang="scss">

</style>
