<script setup>
import { ref, watch, useTemplateRef, onMounted, onUnmounted } from "vue";
import { invoke } from "@tauri-apps/api/core";
import { readTextFile, writeTextFile } from '@tauri-apps/plugin-fs';
import { Message } from 'view-ui-plus'
import MarkdownEditor from './components/MarkdownEditor.vue'
import SelectFolder from './components/SelectFolder.vue'
import FolderTree from './components/FolderTree.vue'

// 原始示例数据，仅供参考
const greetMsg = ref("");
const name = ref("");
async function greet() {
    // Learn more about Tauri commands at https://tauri.app/develop/calling-rust/
    greetMsg.value = await invoke("greet", { name: name.value });
}

const markdownRef = ref(null);
const markdownCode = ref("# Hello Markdown")
const appendToolbar = [
    {
        name: "|",
    },
    {
        name: "save-markdown-code",
        icon: "fa-save", // font-awesome icon. 需确保在 editormd.css 中已定义
        title: "保存当前内容",
        shortcut: [
            navigator.userAgent.toUpperCase().indexOf('MAC') >= 0 ? "Cmd-S" : "Ctrl-S"
        ],
        handler: () => {
            writeFileContent();
        },
        nofocus: true,
    },
    {
        name: "publish",
        icon: "fa-cloud-upload",
        title: "发布文章",
        handler: () => {
            // TODO 调用接口将 markdown 源码或者 HTML 代码发布到云端
            Message.warning('抱歉，该功能暂未开放');
        },
        nofocus: true,
    },
];
// 支持从 localStorage 读写 imageUploadURL
const imageUploadURLOfEditor = ref(localStorage.getItem('imageUploadURLOfEditor') || "")
function changeImageUploadURL(newImageUploadURL) {
    console.log("new imageUploadURL: ", newImageUploadURL)
    localStorage.setItem('imageUploadURLOfEditor', newImageUploadURL)
}
async function initMarkdownEditor() {
    if (currentFilePath.value.length > 0) {
        try {
            markdownCode.value = await readTextFile(currentFilePath.value)
            Message.success('已读取文件内容，并加载到编辑器中:' + currentFilePath.value);
        } catch (err) {
            Message.error('文件读取失败:' + err);
        }
    }
    markdownRef.value.initEditor()
}
// 矫正 markdown 编辑器的高度
function reloadEditorHeight() {
    markdownRef.value.resetHeight(window.innerHeight)
}
// 矫正 markdown 编辑器的宽度
function reloadEditorWidth() {
    // 可以使用 splitRight.value.offsetWidth 也可以使用 100% 来调整
    const width = splitRight.value.offsetWidth
    markdownRef.value.resetWidth("100%")
}
// 监听页面宽度和高度，调整 markdown 编辑器的高宽度
const handleWindowResize = () => {
    reloadEditorHeight()
    reloadEditorWidth()
}

// 动态控制页面左右布局
const split = ref(0.2)
const hiddenSplitRight = ref("")
const splitRight = useTemplateRef('splitRight')
watch(split, (newSplit, oldSplit) => {
    // 当 split 小于某个值时，隐藏左边布局
    if (newSplit < 0.05) {
        split.value = 0.01
        if (hiddenSplitRight.value == "") {
            hiddenSplitRight.value = "hidden"
        }
    } else {
        if (hiddenSplitRight.value == "hidden") {
            hiddenSplitRight.value = ""
        }
    }

    // 动态调整 MarkdownEditor 的宽度。如果不执行 reset 的话，CodeMirror 内部编辑器不会自适应宽度
    reloadEditorWidth()
})

// 如果之前已经选过目录，那么直接加载该目录
const rootPathOfFolderTree = ref(localStorage.getItem('rootPathOfFolderTree') || "")
function changeRootPath(newRootPath) {
    localStorage.setItem('rootPathOfFolderTree', newRootPath)
    rootPathOfFolderTree.value = newRootPath
}

// <SelectFolder> 选择目录后赋值给 folderTreeData，然后再传递给 <FolderTree>
const folderTreeData = ref(null)
function showFileTree(treeData) {
    folderTreeData.value = treeData
}

// <FolderTree> 完成文件树渲染后，点击文件得到 currentFilePath
// 读取 currentFilePath 的文件内容，填充到 MarkdownEditor 之中
const currentFilePath = ref(localStorage.getItem('currentSelectedFilePath') || "");
async function fileSelected(fileNodeData) {
    console.log(fileNodeData)
    const filePath = fileNodeData.path
    localStorage.setItem('currentSelectedFilePath', filePath)
    await readFileContent(filePath)
}
async function readFileContent(filePath) {
    try {
        markdownRef.value.setMarkdownCode(await readTextFile(filePath))
        currentFilePath.value = filePath
        Message.success('已读取文件内容，并加载到编辑器中:' + filePath);
    } catch (err) {
        Message.error('文件读取失败:' + err);
    }
}
async function writeFileContent() {
    // 如果未选择任何文件，则不触发写文件事件
    if (currentFilePath.value.length == 0) {
        Message.warning('当前编辑器暂未关联目标文件，请在左侧打开目录并选择一个文件')
        return;
    }
    try {
        await writeTextFile(currentFilePath.value, markdownRef.value.getMarkdownCode())
        Message.success('文件更新成功:' + currentFilePath.value);
    } catch (err) {
        Message.error('文件更新失败:' + err);
    }
}

onMounted(() => {
    window.addEventListener('resize', handleWindowResize);
    initMarkdownEditor();
})
onUnmounted(() => {
    window.removeEventListener('resize', handleWindowResize);
})
</script>

<template>
    <div>
        <Split v-model="split">
            <template #left>
                <div class="split-left">
                    <SelectFolder :class="hiddenSplitRight" :rootPath="rootPathOfFolderTree"
                        @update:rootPath="changeRootPath" @folder-selected="showFileTree" />
                    <FolderTree :class="hiddenSplitRight" :treeData="folderTreeData" :expandLevel="1"
                        :selectedNode="[currentFilePath]" :specifyFileSuffix="['md']" @file-selected="fileSelected" />
                </div>
            </template>
            <template #trigger>
                <div class="split-trigger"></div>
            </template>
            <template #right>
                <div ref="splitRight" class="split-right">
                    <MarkdownEditor ref="markdownRef" width="100%" height="100%" :autoInit="false"
                        :markdownCode="markdownCode" :imageUpload="true" :imageUploadURL="imageUploadURLOfEditor"
                        :imageUploadURLChange="changeImageUploadURL" :onload="reloadEditorHeight"
                        :onFullScreenExit="handleWindowResize" @update:markdownCode="newCode => markdownCode = newCode"
                        :appendToolbar="appendToolbar" />
                </div>
            </template>
        </Split>
    </div>
</template>

<style scoped>
body {
    overflow: hidden;
    /* 禁用所有方向滚动 */
}

.split-left {
    height: 100vh;
    border-right: 1px solid #dcdee2;
    overflow-x: hidden;
    overflow-y: auto;
    scrollbar-width: none;
}

.split-trigger {
    width: 5px;
    height: 100vh;
    background-color: gray;
}

.split-trigger:hover {
    cursor: ew-resize;
}

.split-right {
    margin-left: 5px;
}

.hidden {
    display: none;
}
</style>
<style></style>
