<template>
  <div :class="prefixCls">
    <a-spin :spinning="spinning">
      <div ref="editor" class="editor-wrapper"></div>
      <a-progress
        v-if="spinning && percent > 0"
        :stroke-color="{
          '0%': '#108ee9',
          '100%': '#87d068',
        }"
        :percent="percent"
      />
    </a-spin>
  </div>
</template>

<script>
import WEditor from 'wangeditor'
import { getStsAssumeRole } from '@/api/storage'
import moment from 'moment'

const OSS = require('ali-oss')
const md5 = require('md5')

export default {
  name: 'WangEditor',
  props: {
    prefixCls: {
      type: String,
      default: 'ant-editor-wang'
    },
    // eslint-disable-next-line
    value: {
      type: String
    }
  },
  data () {
    return {
      editor: null,
      editorContent: null,
      store: null,
      spinning: false,
      percent: 0
    }
  },
  watch: {
    value (val) {
      this.editorContent = val
      this.editor.txt.html(val)
    }
  },
  mounted () {
    this.initEditor()
    getStsAssumeRole().then(res => {
      this.store = new OSS(res)
    }).catch(() => {
      this.$message.error('OSS 初始化失败，图片无法上传')
    })
  },
  methods: {
    computeFileMd5 (file) {
      return new Promise((resolve, reject) => {
        const fileReader = new FileReader()
        fileReader.readAsArrayBuffer(file)

        fileReader.onload = (e) => {
          resolve(md5(new Uint8Array(e.target.result)))
        }

        fileReader.onerror = (e) => {
          reject(e)
        }
      })
    },
    initEditor () {
      this.editor = new WEditor(this.$refs.editor)
      // this.editor.onchangeTimeout = 200
      this.editor.config.onchange = (html) => {
        this.editorContent = html
        this.$emit('change', this.editorContent)
      }
      this.editor.config.zIndex = 500
      this.editor.config.pasteIgnoreImg = true
      this.editor.config.pasteFilterStyle = true
      this.editor.config.customUploadImg = (files, insertImgFn) => {
        this.spinning = true

        files.map(async file => {
          const fileMd5 = await this.computeFileMd5(file)
          const fileName = 'front' + moment().format('/YYYY/MM/DD/') + fileMd5 + '.' + file.type.replace('image/', '')

          this.store.put(fileName, file).then(res => {
            insertImgFn(res.url)
          }).catch(err => {
            this.$message.error(err.message)
          }).finally(() => {
            this.spinning = false
          })
        })
      }

      this.editor.config.customUploadVideo = (files, insertVideoFn) => {
        this.spinning = true

        files.map(async file => {
          const fileMd5 = await this.computeFileMd5(file)
          const fileName = 'front' + moment().format('/YYYY/MM/DD/') + fileMd5 + '.' + file.type.replace('image/', '')

          this.store.multipartUpload(fileName, file, {
            progress: (e) => {
               this.percent = Math.round(e * 100)
            },
            partSize: 200 * 1024
          }).then(res => {
            let fileUrl = ''

            const result = res.res.requestUrls
            if (result[0].indexOf('?') !== -1) {
              fileUrl = result[0].slice(0, result[0].indexOf('?'))
            } else {
              fileUrl = result[0]
            }
            insertVideoFn(fileUrl)
          }).catch(err => {
            this.$message.error(err.message)
          }).finally(() => {
            this.percent = 0
            this.spinning = false
          })
        })
      }

      this.editor.create()
    },
    getContent: function () {
      return this.editorContent
    }
  }
}
</script>

<style lang="less" scoped>
.ant-editor-wang {
  .editor-wrapper {
    text-align: left;
  }
}
</style>
