<template>
  <div ref="wrapRef"></div>
</template>
<script lang="ts">
import type { Ref } from "vue";
import {
  defineComponent,
  ref,
  unref,
  nextTick,
  computed,
  watch,
  onBeforeUnmount,
  onDeactivated,
} from "vue";
import Vditor from "vditor";
import "vditor/dist/index.css";
import { getTheme } from "./getTheme";
import { onMountedOrActivated } from "@/hooks/onMountedOrActivated";
import { useMessage } from "@/hooks/useMessage";

type Lang = "zh_CN" | "en_US" | "ja_JP" | "ko_KR" | undefined;
const { createMessage } = useMessage();

export default defineComponent({
  inheritAttrs: false,
  props: {
    height: { type: Number, default: 360 },
    value: { type: String, default: "" },
    dark: { type: String, default: "light" },
    locale: { type: String, default: "zh_CN" },
  },
  emits: ["change", "get", "update:value"],
  setup(props, { attrs, emit }) {
    const wrapRef = ref(null);
    const vditorRef = ref(null) as Ref<Vditor | null>;
    const initedRef = ref(false);

    const getLocale = computed(() => {
      return props.locale;
    });
    const getDarkMode = computed(() => {
      // 'light' | 'dark'
      return props.dark;
    });
    const valueRef = ref(props.value || "");

    watch(
      [() => getDarkMode.value, () => initedRef.value],
      ([val, inited]) => {
        if (!inited) {
          return;
        }
        instance
          .getVditor()
          ?.setTheme(
            getTheme(val) as any,
            getTheme(val, "content"),
            getTheme(val, "code")
          );
      },
      {
        immediate: true,
        flush: "post",
      }
    );

    watch(
      () => props.value,
      (v) => {
        if (v !== valueRef.value) {
          instance.getVditor()?.setValue(v);
        }
        valueRef.value = v;
      }
    );

    const getCurrentLang = computed(
      (): "zh_CN" | "en_US" | "ja_JP" | "ko_KR" => {
        let lang: Lang;
        switch (unref(getLocale)) {
          case "en":
            lang = "en_US";
            break;
          case "ja":
            lang = "ja_JP";
            break;
          case "ko":
            lang = "ko_KR";
            break;
          default:
            lang = "zh_CN";
        }
        return lang;
      }
    );
    function init() {
      const wrapEl = unref(wrapRef);
      if (!wrapEl) return;
      const bindValue = { ...attrs, ...props };
      const insEditor = new Vditor(wrapEl, {
        // 设置外观主题
        theme: getTheme(getDarkMode.value) as any,
        // lang: unref(getCurrentLang),
        i18n: {
          alignCenter: "居中",
          alignLeft: "居左",
          alignRight: "居右",
          alternateText: "替代文本",
          bold: "粗体",
          both: "编辑 & 预览",
          check: "任务列表",
          close: "关闭",
          code: "代码块",
          "code-theme": "代码块主题预览",
          column: "列",
          comment: "评论",
          confirm: "确定",
          "content-theme": "内容主题预览",
          copied: "已复制",
          copy: "复制",
          "delete-column": "删除列",
          "delete-row": "删除行",
          devtools: "开发者工具",
          down: "下",
          downloadTip: "该浏览器不支持下载功能",
          edit: "编辑",
          "edit-mode": "切换编辑模式",
          emoji: "表情",
          export: "导出",
          fileTypeError: "文件类型不允许上传，请压缩后再试",
          footnoteRef: "脚注标识",
          fullscreen: "全屏切换",
          generate: "生成中",
          headings: "标题",
          heading1: "一级标题",
          heading2: "二级标题",
          heading3: "三级标题",
          heading4: "四级标题",
          heading5: "五级标题",
          heading6: "六级标题",
          help: "帮助",
          imageURL: "图片地址",
          indent: "列表缩进",
          info: "关于",
          "inline-code": "行内代码",
          "insert-after": "末尾插入行",
          "insert-before": "起始插入行",
          insertColumnLeft: "在左边插入一列",
          insertColumnRight: "在右边插入一列",
          insertRowAbove: "在上方插入一行",
          insertRowBelow: "在下方插入一行",
          instantRendering: "即时渲染",
          italic: "斜体",
          language: "语言",
          line: "分隔线",
          link: "链接",
          linkRef: "引用标识",
          list: "无序列表",
          more: "更多",
          nameEmpty: "文件名不能为空",
          "ordered-list": "有序列表",
          outdent: "列表反向缩进",
          outline: "大纲",
          over: "超过",
          performanceTip: "实时预览需 ${x}ms，可点击编辑 & 预览按钮进行关闭",
          preview: "预览",
          quote: "引用",
          record: "开始录音/结束录音",
          "record-tip": "该设备不支持录音功能",
          recording: "录音中...",
          redo: "重做",
          remove: "删除",
          row: "行",
          spin: "旋转",
          splitView: "分屏预览",
          strike: "删除线",
          table: "表格",
          textIsNotEmpty: "文本（不能为空）",
          title: "标题",
          tooltipText: "提示文本",
          undo: "撤销",
          up: "上",
          update: "更新",
          upload: "上传图片或文件",
          uploadError: "上传错误",
          uploading: "上传中...",
          wysiwyg: "所见即所得",
        },
        cdn: "https://cdn.jsdelivr.net/npm/vditor@3.9.5",
        mode: "sv",
        hint: {
          extend: [],
        },
        fullscreen: {
          index: 520,
        },
        tab: "\n",
        preview: {
          theme: {
            // 设置内容主题
            current: getTheme(getDarkMode.value, "content"),
            path: "https://cdn.jsdelivr.net/npm/vditor@3.9.5/dist/css/content-theme"
          },
          hljs: {
            // 设置代码块主题
            // style: getTheme(getDarkMode.value, 'code'),
            enable: false,
          },
          actions: [],
          markdown: {
            codeBlockPreview: false,
          },
        },
        counter: {
          enable: false,
        },
        image: {
          isPreview: false,
        },
        input: (v) => {
          // v = v.replace(/`{3}(\s|.)*`{3}/g, '');
          valueRef.value = v;
          emit("update:value", v);
          emit("change", v);
          nextTick(() => {
            // 限制图片粘贴
            if (/!\[[^\]]*\]\((.*?)\)/.test(v)) {
              const removBtn = insEditor.vditor.element.querySelector(
                '.vditor-wysiwyg .vditor-panel [data-type="remove"]'
              );
              if (removBtn) {
                // @ts-ignore
                removBtn.click();
                insEditor.focus();
              }
            }
          });
        },
        after: () => {
          insEditor.vditor.element.addEventListener(
            "paste",
            function (event) {
              console.log(event, ":paste");
              const items = event.clipboardData?.items;
              if (items) {
                for (let i = 0; i < items.length; i++) {
                  const item = items[i];
                  if (item.type.indexOf("image") !== -1) {
                    event.preventDefault();
                    insEditor.focus();
                    createMessage.warning("不支持粘贴图片！");
                    return;
                  }
                }
              }
            },
            true
          );
          // insEditor.vditor.lute.SetJSRenderers({
          //   renderers: {
          //     Md2VditorDOM: {
          //       renderCodeBlock: (node,entering) => {
          //         if(entering) {
          //           return [``,Lute.WalkContinue]
          //         }
          //         return [``,Lute.WalkContinue]
          //       },
          //       renderCodeBlockCode: (node,entering) => {
          //         if(entering) {
          //           return [``,Lute.WalkContinue]
          //         }
          //         return [``,Lute.WalkContinue]
          //       },
          //       renderHTML: (node,entering) => {
          //         console.log('渲染 HTML 块');
          //         if(entering) {
          //           return [``,Lute.WalkContinue]
          //         }
          //         return [``,Lute.WalkContinue]
          //       },
          //       renderImage: (node,entering) => {
          //         console.log('渲染图片');
          //         if(entering) {
          //           return [``,Lute.WalkContinue]
          //         }
          //         return [``,Lute.WalkContinue]
          //       },
          //       renderText: (node,entering) => {
          //         console.log('渲染文本');
          //         if(entering) {
          //           return [``,Lute.WalkContinue]
          //         }
          //         return [``,Lute.WalkContinue]
          //       },
          //       renderBlockquote: (node,entering) => {
          //         console.log("渲染块引用");
          //         if(entering) {
          //           return [``,Lute.WalkContinue]
          //         }
          //         return [``,Lute.WalkContinue]
          //       },
          //       renderLink: (node,entering) => {
          //         if(entering) {
          //           return [``,Lute.WalkContinue]
          //         }
          //         return [``,Lute.WalkContinue]
          //       }
          //     }
          //   }
          // });
          nextTick(() => {
            insEditor.setValue(valueRef.value);
            vditorRef.value = insEditor;
            initedRef.value = true;
            emit("get", instance);
          });
        },
        blur: () => {
          //unref(vditorRef)?.setValue(props.value);
        },
        ...bindValue,
        cache: {
          enable: false,
        },
      });
    }

    const instance = {
      getVditor: (): Vditor => vditorRef.value!,
    };

    function destroy() {
      const vditorInstance = unref(vditorRef);
      if (!vditorInstance) return;
      try {
        vditorInstance?.destroy?.();
      } catch (error) {
        //
      }
      vditorRef.value = null;
      initedRef.value = false;
    }

    onMountedOrActivated(init);

    onBeforeUnmount(destroy);
    onDeactivated(destroy);
    return {
      wrapRef,
      ...instance,
    };
  },
});
</script>
<style>
.vditor-reset p {
  margin-bottom: 10px;
}
</style>
