<template>
  <div class="dee-editor">
    <editor
      :id="tinymceId"
      :key="editorKey"
      :init="editorInit"
      :value="cloneValue"
      :disabled="disabled"
    />
    <el-upload
      ref="imageUpload"
      action=""
      :http-request="uploadImage"
      :before-upload="beforeUpload"
      style="display: none"
    />
    <!-- 特殊符号 -->
    <dee-dialog v-el-drag-dialog :dialog-visible="symbolDialog" width="60%" title="特殊符号" @handleClose="dialogCancles">
      <!-- <symbol-page @getDom="getSymbol" /> -->
      <dee-symbol-tabs ref="symbolTabs" @loading="loadingFun" />
      <div slot="footer" style="text-align: center;">
        <!-- <el-button type="primary" size="small" @click="addSymbol">确 定</el-button> -->
        <!-- <el-button type="primary" size="small" @click="generateSymbol">预 览</el-button> -->
        <el-button type="primary" size="small" :loading="loadingSave" @click="saveSymbol">确 定</el-button>
        <el-button size="small" @click="dialogCancles">取 消</el-button>
      </div>
    </dee-dialog>
  </div>
</template>
<script>
import 'tinymce/skins/ui/oxide/skin.min.css' // 富文本样式
import 'tinymce/skins/ui/oxide/content.min.css' // 富文本样式
import tinymce from 'tinymce/tinymce' // 配置富文本
import 'tinymce/themes/silver/theme.min.js' // 引入富文本的主要脚本

import 'tinymce/icons/default'

import 'tinymce/plugins/image'
import 'tinymce/plugins/fullscreen'
import 'tinymce/plugins/link'
import 'tinymce/plugins/code'
import 'tinymce/plugins/table'
import 'tinymce/plugins/lists'
import 'tinymce/plugins/contextmenu'
import 'tinymce/plugins/wordcount'
import 'tinymce/plugins/colorpicker'
import 'tinymce/plugins/textcolor'
import Editor from '@tinymce/tinymce-vue' // 引用富文本组件
import DeeSymbolTabs from './DeeSymbolTabs'
import { post } from '@/utils/http'
import { getBucketByAppID, downloadFileById } from '@/api/file'
export default {
  components: {
    Editor,
    DeeSymbolTabs
  },
  props: {
    value: {
      type: String,
      default: () => ''
    },
    disabled: {
      type: Boolean,
      default: false
    },
    appId: {
      type: [Number, String],
      default: ''
    }
  },
  data() {
    return {
      cloneValue: '',
      editorKey: 0,
      tinymceId: 'a' + this.$utils.GenNonDuplicateID(10),
      uploadData: {
        url: '/dfs/fileManager/feign/uploadFile'
      },
      symbolDialog: false,
      symbol: '',
      // 特殊符号当前点击的富文本编辑器
      currentEditor: '',
      loadingSave: false,
      editting: false
    }
  },
  computed: {
    editorInit() {
      const that = this
      return {
        language_url: 'tinymce/langs/zh_CN.js',
        language: 'zh_CN',
        skin_url: '/tinymce/skins/ui/oxide/',
        height: 500,
        content_css: '/tinymce/skins/ui/oxide/content.min.css',
        statusbar: false,
        plugins: this.disabled ? '' : 'link lists image code table colorpicker textcolor wordcount contextmenu fullscreen',
        toolbar: this.disabled ? '' : 'fontselect fontsizeselect forecolor backcolor bold italic underline strikethrough | alignleft aligncenter alignright alignjustify | imageUpload quicklink blockquote table numlist bullist preview fullscreen specialSymbol',
        setup: (editor) => {
          editor.on('init', function(e) {
            this.setContent(that.cloneValue || '') // this 指向 tinymce 编译器
          })
          editor.on('input change undo redo execCommand KeyUp', function(e) {
            if (editor.getContent() === that.tmp) {
              return
            }
            that.tmp = editor.getContent()
            that.editting = true
            setTimeout(() => {
              that.editting = false
            }, 500)
            that.$emit('input', that.tmp)
          })
          editor.ui.registry.addButton('imageUpload', {
            tooltip: '插入图片',
            icon: 'image',
            onAction: () => {
              const upload = that.$refs['imageUpload']
              upload.$refs['upload-inner'].handleClick()
            }
          })
          editor.ui.registry.addButton('specialSymbol', {
            text: '特殊符号',
            // tooltip: '',
            // icon: 'image',
            onAction: () => {
              that.currentEditor = editor
              that.symbolDialog = true
              that.initSymbolTabs()
              editor.execCommand('selectAll')
              editor.selection.getRng().collapse(false)
              editor.focus()
            }
          })
        }
      }
    }
  },
  watch: {
    value(val) {
      if (this.editting && this.cloneValue) {
        return
      }
      if (val) {
        this.cloneValue = this.imgSrcReplace(val)
      } else {
        this.cloneValue = ''
      }

      const ed = tinymce.get(this.tinymceId)
      if (ed && ed.isNotDirty) {
        ed.insertContent(this.cloneValue)
      }
    }
  },
  mounted() {
    this.cloneValue = this.imgSrcReplace(this.value)
    if (!tinymce.get(this.tinymceId)) {
      tinymce.init({})
    }
  },
  activated() {
    this.editorKey++
  },
  methods: {
    imgSrcReplace(htmlstr) {
      let regex3 = new RegExp(/token=[\w|.]+/gi)
      const htmlstr1 = htmlstr.replace(regex3, function(match, capture) {
        return 'token=' + localStorage.getItem('token')
      })
      regex3 = null
      return htmlstr1
    },
    uploadImage(file) {
      const formData = new FormData()
      formData.append('file', file.file)
      formData.append('domainName', 'test')
      const url = '/dfs/fileManager/feign/uploadFile'
      getBucketByAppID({ appId: this.appId }).then(res => {
        formData.append('bucketId', res.items.id)
        post(url, formData).then(res => {
          if (res.items) {
            downloadFileById(res.items.id).then(res => {
              if (res.items.fileBase64) {
                const src = `${window.URL.createObjectURL(new Blob([this.base64ToUint8Array(res.items.fileBase64)]))}`
                tinymce.execCommand('mceInsertContent', true, `<img style="width:100%" src=${src}>`)
              }
            })
          }
        })
      })
    },
    base64ToUint8Array(base64String) {
      const padding = '='.repeat((4 - base64String.length % 4) % 4)
      const base64 = (base64String + padding)
        .replace(/\-/g, '+')
        .replace(/_/g, '/')

      const rawData = window.atob(base64)
      const outputArray = new Uint8Array(rawData.length)

      for (var i = 0; i < rawData.length; ++i) {
        outputArray[i] = rawData.charCodeAt(i)
      }
      return outputArray
    },
    beforeUpload(file) {
      if (!file.type.includes('image/')) {
        this.$message.error('请输入图片')
        return false
      }
    },
    // 特殊符号相关
    dialogCancles() {
      this.symbolDialog = false
      this.symbol = ''
    },
    getSymbol(val) {
      this.symbol = val.currentTarget
    },
    addSymbol() {
      if (this.symbol) {
        // this.$emit('getSymbol', this.symbol)
        // tinymce.activeEditor.selection.setContent(`<p style='display: inline-block;'>${this.symbol.innerHTML}</p>`)
        tinymce.activeEditor.selection.setContent(`${this.symbol.innerHTML}`)
        tinymce.activeEditor.insertContent(`<span>&nbsp;</span>`)
        // tinymce.activeEditor.execCommand('')
        this.dialogCancles()
      } else {
        this.$utils.showMessageWarning('请选择符号')
      }
    },
    // 生成符号图标
    generateSymbol() {
      this.$refs.symbolTabs.generateSymbol()
    },
    // 将生成的预览符号保存到富文本编辑器中
    blobToDataURI(blob, callback) {
      var reader = new FileReader()
      reader.readAsDataURL(blob)
      reader.onload = function(e) {
        callback(e.target.result)
      }
    },
    saveSymbol() {
      if (this.$refs.symbolTabs.formValid) {
        const fileBlob = this.$refs.symbolTabs.fileBlob
        const currentEditor = this.currentEditor
        if (fileBlob) {
          this.blobToDataURI(fileBlob, function(result) {
          // tinymce.activeEditor.selection.setContent(`<img src='${result}' alt='' width='70' height='40'>`)
            currentEditor.insertContent(`<img src='${result}' alt=''>`)
          })
          this.dialogCancles()
        } else {
          this.$utils.showMessageWarning('请先选填数据生成符号!')
        }
      } else {
        this.$utils.showMessageWarning('请先选填相关数据生成符号!')
      }
    },
    initSymbolTabs() {
      if (this.$refs.symbolTabs) {
        this.$refs.symbolTabs.initSymbolTabs()
      }
    },
    loadingFun(x) {
      this.loadingSave = x
    },
    // 全屏设置
    toggleFullScreen(eleId) {
      if (this.canFullScreen) {
        if (this.isFullScreen) {
          // 关闭全屏
          this.exitFullScreen()
          this.isFullScreen = false
        } else {
          // 打开全屏
          this.requestFullScreen(document.getElementById(eleId).parentElement)
          this.isFullScreen = true
        }
      } else {
        this.$message.warning({
          content: '当前浏览器暂不支持全屏模式,请切换浏览器后重新尝试!',
          duration: 3
        })
      }
    },
    requestFullScreen(element) {
      // 判断各种浏览器,找到正确的方法
      const requestMethod = element.requestFullScreen || // W3C
          element.webkitRequestFullScreen || // Chrome, safari
          element.mozRequestFullScreen || // FireFox
          element.msRequestFullscreen // IE11
      if (requestMethod) {
        requestMethod.call(element)
      }
    },
    exitFullScreen() {
      var exitMethod = document.exitFullscreen || // W3C
          document.mozCancelFullScreen || // FireFox
          document.webkitExitFullscreen || // Chrome等
          document.msExitFullscreen // IE11
      if (exitMethod) {
        exitMethod.call(document)
      }
    },
    addFullScreenListener() {
      const self = this
      document.onkeydown = function(e) {
        if (e && e.keyCode === 122) { // 捕捉F11键盘动作
          e.preventDefault() // 阻止F11默认动作
          self.toggleFullScreen()
        }
      }
      // 监听不同浏览器的全屏事件,并件执行相应的代码
      switch (self.browserKernel) {
        case 'webkit':
          document.onwebkitfullscreenchange = function() {
            if (document.webkitIsFullScreen) {
              self.isFullScreen = true
            } else {
              self.isFullScreen = false
            }
          }
          break
        case 'gecko':
          document.onmozfullscreenchange = function() {
            if (document.mozFullScreen) {
              self.isFullScreen = true
            } else {
              self.isFullScreen = false
            }
          }
          break
        case 'trident':
          document.onmsfullscreenchange = function() {
            if (document.msFullscreenElement) {
              self.isFullScreen = true
            } else {
              self.isFullScreen = false
            }
          }
          break
        case 'others':
          document.onfullscreenchange = function() {
            if (document.fullscreen) {
              self.isFullScreen = true
            } else {
              self.isFullScreen = false
            }
          }
          break
        default:
          break
      }
    }
  }
}
</script>

<style lang="scss">
.dee-editor{
  padding-top: 10px;
}
</style>