<!-- 富文本编辑器 -->
<template>
  <div>
    <div v-if="props.item?.label" class="ml-2 mb-2 color959595">{{ props.item.label  }}</div>
    <div class="z-10 box mb-5">
      <!-- 工具栏 -->
      <Toolbar
        :editor="editorRef"
        :editorId="editorId"
        class="border-0 b-b-1 border-solid border-[var(--tags-view-border-color)]"
      />
      <!-- 编辑器 -->
      <Editor
        v-model="valueHtml"
        :defaultConfig="editorConfig"
        :editorId="editorId"
        :style="editorStyle"
        @on-maxLength="onMaxLengthFun"
        @on-blur="onBlurFun"
        @on-change="handleChange"
        @on-created="handleCreated"
      />
    </div>
  </div>
</template>
<script setup>
defineOptions({ name: 'wangEditor-index' })
import '@wangeditor/editor/dist/css/style.css' // 引入 css
import { onBeforeUnmount, ref, shallowRef, unref, computed, nextTick, watch } from 'vue'
import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
import { i18nChangeLanguage } from '@wangeditor/editor'
import { isNumber } from '@/utils/is'
import Snackbar from '@/plugins/snackbar'
// import { getAccessToken, getTenantId } from '@/utils/auth'

i18nChangeLanguage('zh-CN')

const props = defineProps({
  modelValue: {
    type: String,
    default: '',
  },
  item: { // 表单配置数据
    type: Object,
    default: () => {}
  },
  editorId: {
    type: String,
    default: 'wangEditor-1',
  },
  height: {
    type: [Number, String],
    default: '300px'
  },
  editorConfig: {
    type: Object,
    default: () => {}
  },
  readonly: {
    type: Boolean,
    default: false
  },
})

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

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

const valueHtml = ref('')

watch(
  () => props.modelValue,
  (val) => {
    if (val === null) val = ''
    if (val === unref(valueHtml)) return
    valueHtml.value = val
  },
  {
    immediate: true
  }
)

// 监听
watch(
  () => valueHtml.value,
  (val) => {
    emit('update:modelValue', val === '<p><br></p>' ? '' : val)
  }
)

const handleCreated = (editor) => {
  editorRef.value = editor
}

const onMaxLengthFun = (editor) => {
  const maxLength = editor?.getConfig()?.maxLength || null
  if (maxLength) Snackbar.info(`最多可输入${maxLength}个字符`)
}

const onBlurFun = (editor) => {
  const text = editor.getText()?.replace(/\s+/g, '')
  if (!text) valueHtml.value = ''
}

// 编辑器配置
const editorConfig = computed(() => {
  return Object.assign(
    {
      placeholder: '请输入内容...',
      readOnly: props.item.readonly || props.readonly,
      maxLength: Number(props.item.maxLength) || Number(props.maxLength) || null,
      customAlert: (s, t) => {
        switch (t) {
          case 'success':
            Snackbar.success(s)
            break
          case 'info':
            Snackbar.info(s)
            break
          case 'warning':
            Snackbar.warning(s)
            break
          case 'error':
            Snackbar.error(s)
            break
          default:
          Snackbar.info(s)
            break
        }
      },
      autoFocus: false,
      scroll: true,
      MENU_CONF: {
        ['uploadImage']: {
          server:`${import.meta.env.VITE_BASE_URL}/commons/upload`,
          // 单个文件的最大体积限制，默认为 2M
          // maxFileSize: 5 * 1024 * 1024,
          // 最多可上传几个文件，默认为 100
          // maxNumberOfFiles: 10,
          // 选择文件时的类型限制，默认为 ['image/*'] 。如不想限制，则设置为 []
          // allowedFileTypes: ['image/*'],

          // 自定义上传参数，例如传递验证的 token 等。参数会被添加到 formData 中，一起上传到服务端。
          // meta: { updateSupport: 0 },
          // 将 meta 拼接到 url 参数中，默认 false
          // metaWithUrl: true,

          // 自定义增加 http  header
          // headers: {
          //   Accept: '*',
          //   Authorization: 'Bearer ' + getAccessToken(),
          //   'tenant-id': getTenantId()
          // },

          // 跨域是否传递 cookie ，默认为 false
          // withCredentials: true,

          // 超时时间，默认为 10 秒
          timeout: 5 * 1000, // 5 秒

          // form-data fieldName，后端接口参数名称，默认值wangeditor-uploaded-image
          fieldName: 'file',

          // 上传之前触发
          onBeforeUpload(file) {
            console.log(file)
            return file
          },
          // 上传进度的回调函数
          onProgress(progress) {
            // progress 是 0-100 的数字
            console.log('progress', progress)
          },
          onSuccess(file, res) {
            console.log('onSuccess', file, res)
          },
          onFailed(file, res) {
            alert(res.message)
            console.log('onFailed', file, res)
          },
          onError(file, err, res) {
            alert(err.message)
            console.error('onError', file, err, res)
          },
          // 自定义插入图片
          // customInsert(res, insertFn: InsertFnType) {
          //   insertFn(res.data, 'image', res.data)
          // }
        }
      },
      uploadImgShowBase64: true,
    },
    props.editorConfig || props.item.editorConfig || {}
  )
})

const editorStyle = computed(() => {
  const h = props.item.height || props.height
  return {
    height: isNumber(h) ? `${h}px` : h
  }
})

// 回调函数
const handleChange = (editor) => {
  emit('change', editor)
}

// 组件销毁时，及时销毁编辑器
onBeforeUnmount(() => {
  const editor = unref(editorRef.value)

  // 销毁，并移除 editor
  editor?.destroy()
})

const getEditorRef = async () => {
  await nextTick()
  return unref(editorRef.value)
}

defineExpose({
  getEditorRef
})
</script>
<style lang="scss" scoped>
.box {
  border: 1px solid #a2a2a2;
  border-radius: 5px;
  padding: 1px;
  &:hover {
    border: 1px solid #2b2b2b;
  }
}
.color959595 {
  color: #959595;
}
</style>
