<template>
  <div class="editor_root">
    <textarea
      :ref="`${editor_ref}_${randomNum}`"
      :id="`${editor_ref}_${randomNum}`"
      :style="`width: 100%;height: ${height}px;`"
    ></textarea>
  </div>
</template>

<script>
import { pictureFormat } from "@/utils/fileConfig";
export default {
  props: {
    content: {
      type: String,
      default: function () {
        return "";
      }
    },
    editor_ref: {
      type: String,
      default: function () {
        return "myCkeditor";
      }
    },
    content_index: {
      type: Number,
      default: 0
    },
    placeholder: {
      type: String,
      default: "请输入内容"
    },
    height: {
      type: Number,
      default: 150
    }
  },
  data() {
    return {
      randomNum: `${Math.ceil(Math.random() * 10000)}_${Date.now()}`,
      myCkeditor: null,
      imgsObj: {},
      editorHtml: ""
    };
  },
  watch: {
    content: {
      handler(newHtml) {
        if (this.editorHtml !== newHtml) {
          this.setContent(newHtml);
        }
      },
      immediate: true
    }
  },
  mounted() {
    this.initCkeditor();
  },
  beforeDestroy() {
    if (this.myCkeditor) {
      this.myCkeditor.destroy();
    }
    this.myCkeditor = null;
  },
  methods: {
    setContent(content) {
      if (content) {
        if (this.myCkeditor && this.myCkeditor.status === "ready") {
          this.myCkeditor.setData(content);
          this.editorHtml = content;
        }
      } else {
        setTimeout(() => {
          if (this.myCkeditor && this.myCkeditor.status === "ready") {
            this.myCkeditor.setData("");
            this.editorHtml = "";
          }
        }, 100);
      }
    },
    editorContentChange() {
      this.$nextTick(() => {
        if (this.myCkeditor && this.myCkeditor.document.getBody().$) {
          let newHtml = this.myCkeditor.document.getBody().getHtml();
          let newText = this.myCkeditor.document.getBody().getText();
          this.editorHtml = newHtml;
          this.$emit("change", newHtml, newText, this.content_index);
        }
      });
    },
    initCkeditor() {
      let that = this;
      that.myCkeditor = window.CKEDITOR.replace(
        that.$refs[`${this.editor_ref}_${this.randomNum}`],
        {
          height: that.height,
          filebrowserImageUploadUrl: that.$api.baseUrl,
          editorplaceholder: that.placeholder // 占位文本
        }
      );
      that.myCkeditor.on("instanceReady", function () {
        that.setContent(that.content);
        that.myCkeditor.dataProcessor.htmlFilter.addRules({
          elements: {
            img: function (el) {
              let imgSrc = el.attributes.src;
              if (imgSrc) {
                if (
                  imgSrc.indexOf("http://") > -1 ||
                  imgSrc.indexOf("https://") > -1
                ) {
                  if (imgSrc.indexOf(that.$api.showImageUrl) === -1) {
                    that.imgsObj[imgSrc] = "";
                  }
                }
              }
            }
          }
        });
        that.myCkeditor.on("afterPaste", function () {
          let newImgsPromiseArr = [];
          for (const imgSrc in that.imgsObj) {
            if (!that.imgsObj[imgSrc] && imgSrc) {
              newImgsPromiseArr.push(that.changeImageUrl(imgSrc));
            }
          }
          Promise.all(newImgsPromiseArr).then((newImgs) => {
            let oldhtml = "";
            if (that.myCkeditor && that.myCkeditor.document.getBody().$) {
              oldhtml = that.myCkeditor.document.getBody().getHtml();
            }
            for (const imgArr of newImgs) {
              if (imgArr && imgArr[0] && imgArr[1]) {
                oldhtml = oldhtml.replaceAll(
                  imgArr[0],
                  that.$api.showImageUrl + imgArr[1]
                );
              }
            }
            that.setContent(oldhtml);
          });
        });
        that.myCkeditor.on("fileUploadRequest", async function (evt) {
          let fileLoader = evt.data.fileLoader,
            formData = new FormData(),
            xhr = fileLoader.xhr;
          formData.append("savefolder", "news");
          let filename = fileLoader.fileName;
          let myFile = fileLoader.file;
          if (myFile instanceof Blob) {
            formData.append(
              "file",
              new window.File([myFile], filename, { type: myFile.type })
            );
          } else {
            formData.append("file", myFile);
          }
          let strArr = filename.split(".");
          filename = strArr[0];
          let suffix = strArr[strArr.length - 1];
          suffix = suffix.toLowerCase();
          if (pictureFormat.includes(suffix)) {
            xhr.open("POST", that.$api.baseUrl + "file/upload", true);
            xhr.send(formData);
          } else {
            that.$Message.warning("请上传正确的图片格式");
          }
          evt.stop();
        });
        that.myCkeditor.on("fileUploadResponse", function (evt) {
          let data = evt.data,
            xhr = data.fileLoader.xhr;
          let resolve = JSON.parse(xhr.responseText);
          if (resolve.code === 0) {
            data.url = that.$api.showImageUrl + resolve.obj;
          } else {
            data.message = resolve.msg;
            evt.cancel();
          }
          that.editorContentChange();
          evt.stop();
        });
        that.myCkeditor.on("change", function () {
          that.editorContentChange();
        });
        that.myCkeditor.on("blur", function () {
          that.editorContentChange();
        });
      });
    },
    changeImageUrl(imgSrc) {
      return new Promise((resolve, reject) => {
        let that = this;
        let formData = new FormData();
        formData.append("newpath", imgSrc);
        formData.append("filepath", "news");
        that
          .axios({
            method: "POST",
            timeout: 1000 * window._config.axiosFileTimeout,
            url: that.$api.baseUrl + "file/down_webfile",
            data: formData,
            headers: {
              "Content-Type": "multipart/form-data"
            }
          })
          .then((res) => {
            if (!res.data.code) {
              that.imgsObj[imgSrc] = res.data.obj;
              resolve([imgSrc, res.data.obj]);
            } else {
              reject();
              that.$Message.error(res.data.msg);
            }
          })
          .catch(() => {
            reject();
          });
      });
    }
  }
};
</script>

<style>
.ivu-message {
  z-index: 999999 !important;
}
</style>
<style scoped>
.editor_root {
  width: 100%;
}
</style>
