<template>
  <div>
    <div class="editor-container">
      <Toolbar
        style="border-bottom: 1px solid #ccc"
        :editor="editorRef"
        :defaultConfig="toolbarConfig"
        :mode="mode"
      />
      <Editor
        :defaultConfig="editorConfig"
        :mode="mode"
        v-model="valueHtml"
        :style="editorStyle"
        @onCreated="handleCreated"
        @onChange="handleChange"
      />
      <!-- <a-button @click="getToolbar">获取 toolbar</a-button> -->
    </div>
  </div>
</template>

<script lang="ts">
  import { onBeforeUnmount, shallowRef, computed, watch, ref } from 'vue';
  import { Editor, Toolbar } from '@wangeditor/editor-for-vue';
  import { defineComponent } from 'vue';
  import { isNumber } from '/@/utils/is';
  import { uploadApi } from '/@/api/common';
  import '@wangeditor/editor/dist/css/style.css';
  import { DomEditor } from '@wangeditor/editor';
  export default defineComponent({
    name: 'WangEditor',
    components: { Editor, Toolbar },
    props: {
      editorId: {
        type: String,
        default: 'editor-1',
      },
      modelValue: {
        type: String,
        default: '',
      },
      options: {
        type: Object,
        default: () => {},
      },
      height: {
        type: Number,
        default: 300,
      },
      // 内容框默认 placeholder
      placeholder: {
        type: String,
        default: () => '请输入内容...',
      },
      // 是否禁用
      disable: {
        type: Boolean,
        default: () => false,
      },
    },
    emits: ['change', 'update:modelValue'],
    setup(props, { emit }) {
      // 编辑器实例，必须用 shallowRef，重要！
      const editorRef = shallowRef();

      // 内容 HTML
      const valueHtml = ref(props.modelValue);
      const toolbarConfig = {
        excludeKeys: [
          'group-video',
          'emotion',
          'group-indent',
          'fontFamily',
          'lineHeight',
          'insertTable',
          'todo',
          'undo',
          'redo',
        ],
      };
      const editorConfig = { placeholder: props.placeholder, MENU_CONF: {} } as any;

      editorConfig.MENU_CONF['uploadImage'] = {
        server: uploadApi,

        fieldName: 'image',
        // 单个文件的最大体积限制，默认为 2M
        maxFileSize: 5 * 1024 * 1024, // 1M

        // 最多可上传几个文件，默认为 100
        maxNumberOfFiles: 10,

        // 单个文件上传成功之后
        onSuccess(file: File, res: any) {
          // TS 语法
          // onSuccess(file, res) {          // JS 语法
          console.log(`${file.name} 上传成功`, res);
        },
      };
      // 插入图片
      editorConfig.MENU_CONF['insertImage'] = {
        onInsertedImage(imageNode) {
          // TS 语法
          // onInsertedImage(imageNode) {                    // JS 语法
          if (imageNode == null) return;

          const { src, alt, url, href } = imageNode;
          console.log('inserted image', src, alt, url, href);
        },
      };
      // 编辑器回调函数
      const handleCreated = editor => {
        console.log('created', editor);
        editorRef.value = editor; // 记录 editor 实例，重要！
      };

      const getToolbar = () => {
        const toolbar = DomEditor.getToolbar(editorRef.value);
        const toolbarKeys = toolbar.getConfig().toolbarKeys;
        console.log('🚀 ~ file: index.vue:122 ~ toolbar:', toolbarKeys);
      };

      // 内容修改后
      const handleChange = editor => {
        console.log('change:', editor.getHtml());
        emit('change', editor.getHtml());
      };

      // 组件销毁时，也及时销毁编辑器，重要！
      onBeforeUnmount(() => {
        const editor = editorRef.value;
        if (editor == null) return;
        editor.destroy();
      });

      const editorStyle = computed(() => {
        return {
          height: isNumber(props.height) ? `${props.height}px` : props.height,
        };
      });

      watch(
        () => props.disable,
        bool => {
          const editor = editorRef.value;
          if (editor == null) return;
          bool ? editor.disable() : editor.enable();
        },
      );

      // 监听
      watch(
        () => valueHtml.value,
        (val: string) => {
          emit('update:modelValue', val);
        },
      );

      return {
        mode: 'default',
        editorStyle,
        editorRef,
        valueHtml,
        toolbarConfig,
        editorConfig,
        handleChange,
        handleCreated,
        getToolbar,
      };
    },
  });
</script>

<style lang="less" scoped>
  .editor-container {
    width: 100%;
    border: 1px solid #ccc;
    border-radius: 4px;
    overflow-y: hidden;
  }
</style>
