<template>
  <div style="border: 1px solid #ccc">
    <Toolbar
        style="border-bottom: 1px solid #ccc"
        :editor="editorRef"
        :defaultConfig="toolbarConfig"
        mode="simple"
    />
    <Editor
        style="height: 500px; overflow-y: hidden;"
        v-model="valueHtml"
        :defaultConfig="editorConfig"
        mode="simple"
        @onDestroyed="handleDestroyed"
        @onChange="handleChange"
        @onCreated="handleCreated"
    />
  </div>
</template>
<script lang="ts" setup>
import '@wangeditor/editor/dist/css/style.css' // 引入 css
import {nextTick, onBeforeUnmount, onMounted, ref, shallowRef} from 'vue'
import {Editor, InsertFnType, Toolbar} from '@wangeditor/editor-for-vue'
import {IEditorConfig} from '@wangeditor/editor'
import {Msg} from "/@/utils/message";
import {$upload} from "/@/utils/request";


// 编辑器实例，必须用 shallowRef
const editorRef = shallowRef()

const emit = defineEmits(['update:modelValue'])

const props = defineProps({
  modelValue: {
    type: String,
    default: ''
  }
})

// 内容 HTML
const valueHtml = ref('<p></p>')
const init = ref(false);
const toolbarConfig = {}

const editorConfig: Partial<IEditorConfig> = {  // TS 语法
  MENU_CONF: {},
  placeholder: '请输入内容...'
}


/*
watch(props.modelValue, () => {
  if (editorRef.value) {
    valueHtml.value = props.modelValue;
  }
})
*/

onMounted(() => {
  // setTimeout(() => {
  //   valueHtml.value = '<p></p>'
  // }, 1500)
})


const initText = (content: string) => {
  // valueHtml.value = content;
  nextTick(()=>{
    init.value = true;
    editorRef.value.setHtml(content);
  })
}


editorConfig.MENU_CONF['uploadImage'] = {
  async customUpload(file: File, insertFn: InsertFnType) {  // TS 语法
    // async customUpload(file, insertFn) {                   // JS 语法
    // file 即选中的文件
    // 自己实现上传，并得到图片 url alt href
    // 最后插入图片
    let fd = new FormData();
    fd.append('file', file);
    $upload(`file/upload`, fd).then((res: any) => {
      let {name, url} = res;
      insertFn(url, name, url)
    })

  },

  // 上传之前触发
  onBeforeUpload(file: File) { // TS 语法
    return file
  },
  // 上传进度的回调函数
  onProgress(progress: number) {  // TS 语法
    Msg.showLoading('上传中...')
    //console.log('progress', progress)
  },

  // 单个文件上传成功之后
  onSuccess(file: File, res: any) {  // TS 语法
    //console.log(`${file.name} 上传成功`, res)
    Msg.hideLoading();
  },

  // 单个文件上传失败
  onFailed(file: File, res: any) {   // TS 语法
    Msg.hideLoading();                    // onFailed(file, res) {           // JS 语法
    //console.log(`${file.name} 上传失败`, res)
  },

  // 上传错误，或者触发 timeout 超时
  onError(file: File, err: any, res: any) {  // TS 语法
    //console.log(`${file.name} 上传出错`, err, res)
    Msg.hideLoading();
  },
}

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

const handleCreated = (editor) => {
  editorRef.value = editor // 记录 editor 实例，重要！
}

const handleChange = (editor) => {
  //console.log("handleChange>>>>>>>")
  if (init.value) {
    init.value = false;
    //console.log("handleChange>>>>>>> init return.")
    return;
  }
  emit('update:modelValue', editor.getHtml())
}

const handleDestroyed = (editor) => {
  //console.log('destroyed', editor)
}


defineExpose({
  initText
});


</script>

<style scoped>
.toolbar {
  border: 1px solid #ccc;
}

.text {
  border: 1px solid #ccc;
  min-height: 200px;
}
</style>
