<template>
  <div :id="uploadId" class="fm-uplaod-container">
    <draggable
      v-model="fileList"
      class="drag-img-list"
      v-bind="{ group: uploadId, ghostClass: 'ghost', animation: 200 }"
      :no-transition-on-drag="true"
    >
      <div
        v-for="item in fileList"
        :id="item.key"
        :key="item.key"
        :style="{ width: width + 'px', height: height + 'px' }"
        :class="{
          uploading: item.status == 'uploading',
          'is-success': item.status == 'success',
          'is-diabled': disabled,
        }"
        class="upload-file"
      >
        <img :src="item.url" />

        <el-progress
          v-if="item.status == 'uploading'"
          :width="miniWidth * 0.9"
          class="upload-progress"
          type="circle"
          :percentage="item.percent"
        />

        <label v-if="item.status == 'success'" class="item-status">
          <i class="el-icon-upload-success el-icon-check" />
        </label>

        <div
          v-if="!disabled"
          class="uplaod-action"
          :style="{ height: miniWidth / 4 + 'px' }"
        >
          <i
            class="iconfont icon-tupianyulan"
            :title="'预览'"
            :style="{ 'font-size': miniWidth / 8 + 'px' }"
            @click="handlePreviewFile(item.key)"
          />
          <!-- <i
            v-if="isEdit"
            class="iconfont icon-sync1"
            :title="'替换'"
            :style="{ 'font-size': miniWidth / 8 + 'px' }"
            @click="handleEdit(item.key)"
          /> -->
          <i
            class="iconfont icon-delete"
            :title="'删除'"
            :style="{ 'font-size': miniWidth / 8 + 'px' }"
            @click="handleRemove(item.key)"
          />
        </div>
      </div>
    </draggable>
    <!-- @click.self="handleAdd" -->
    <div
      v-if="!preview"
      v-show="(!isQiniu || (isQiniu && token)) && fileList.length < length"
      class="el-upload el-upload--picture-card"
      :class="{ 'is-disabled': disabled }"
      :style="{ width: width + 'px', height: height + 'px' }"
    >
      <el-upload
        :action="ossUploadUrl"
        :on-success="handleSuccess"
        :on-exceed="handleExceed"
        :before-upload="beforeUpload"
        :show-file-list="false"
        accept="image/*"
        :limit="5"
        :data="dataObj"
      >
        <i
          class="el-icon-plus"
          :style="{
            fontSize: miniWidth / 4 + 'px',
            marginTop: -miniWidth / 8 + 'px',
            marginLeft: -miniWidth / 8 + 'px',
          }"
        ></i>
      </el-upload>
      <!-- <i
        class="el-icon-plus"
        :style="{
          fontSize: miniWidth / 4 + 'px',
          marginTop: -miniWidth / 8 + 'px',
          marginLeft: -miniWidth / 8 + 'px'
        }"
        @click.self="handleAdd"
      />
      <input
        v-if="multiple"
        ref="uploadInput"
        accept="image/*"
        multiple
        type="file"
        :style="{ width: 0, height: 0 }"
        name="file"
        class="el-upload__input upload-input"
        @change="handleChange"
      />
      <input
        v-else
        ref="uploadInput"
        accept="image/*"
        type="file"
        :style="{ width: 0, height: 0 }"
        name="file"
        class="el-upload__input upload-input"
        @change="handleChange"
      /> -->
    </div>
  </div>
</template>

<script>
import Vue from "vue";
import Viewer from "viewerjs";
import Draggable from "vuedraggable";
import * as qiniu from "qiniu-js";
require("viewerjs/dist/viewer.css");
import { policy } from "@/api/user";
import VueI18n from "vue-i18n";
Vue.use(VueI18n);
export default {
  components: {
    Draggable,
  },
  props: {
    value: {
      type: Array,
      default: () => [],
    },
    width: {
      type: Number,
      default: 100,
    },
    height: {
      type: Number,
      default: 100,
    },
    token: {
      type: String,
      default: "",
    },
    domain: {
      type: String,
      default: "",
    },
    multiple: {
      type: Boolean,
      default: false,
    },
    length: {
      type: Number,
      default: 9,
    },
    isQiniu: {
      type: Boolean,
      default: false,
    },
    isDelete: {
      type: Boolean,
      default: true,
    },
    min: {
      type: Number,
      default: 0,
    },
    meitu: {
      type: Boolean,
      default: false,
    },
    isEdit: {
      type: Boolean,
      default: false,
    },
    action: {
      type: String,
      default: "",
    },
    disabled: {
      type: Boolean,
      default: false,
    },
    preview: {
      type: Boolean,
      default: false,
    },
  },
  data() {
    return {
      fileList: this.value.map((item) => {
        return {
          key: item.key
            ? item.key
            : new Date().getTime() + "_" + Math.ceil(Math.random() * 99999),
          url: item.url,
          percent: item.percent ? item.percent : 100,
          status: item.status ? item.status : "success",
        };
      }),
      viewer: null,
      uploadId: "upload_" + new Date().getTime(),
      editIndex: -1,
      meituIndex: -1,
      // ossUploadUrl: "https://ks3-cn-beijing.ksyuncs.com/daya",
      ossUploadUrl: "https://daya.ks3-cn-beijing.ksyuncs.com",
      dataObj: {
        policy: "",
        signature: "",
        key: "",
        KSSAccessKeyId: "",
        acl: "public-read",
        name: "",
      },
    };
  },
  computed: {
    miniWidth() {
      if (this.width > this.height) {
        return this.height;
      } else {
        return this.width;
      }
    },
  },
  watch: {
    fileList: {
      deep: true,
      handler(val) {
        // this.$emit('input', this.fileList)
      },
    },
  },
  mounted() {
    this.$emit("input", this.fileList);
  },
  methods: {
    handleExceed(files, fileList) {
      this.$message.warning(`最多允许上传 5 张图片。`);
    },
    async beforeUpload(file) {
      const isLt2M = file.size / 1024 / 1024 < 5;
      if (!isLt2M) {
        this.$message.error("上传图片大小不能超过 5MB!");
        return;
      }
      try {
        let filename = file.name.replaceAll(" ", "_");
        let key = new Date().getTime() + filename;
        let obj = {
          filename,
          bucketName: "daya",
          postData: {
            filename,
            acl: "public-read",
            key,
            unknowValueField: [],
          },
        };

        const res = await policy(obj);
        this.dataObj = {
          policy: res.data.policy,
          signature: res.data.signature,
          key,
          KSSAccessKeyId: res.data.kssAccessKeyId,
          acl: "public-read",
          name: filename,
        };

        return isLt2M;
      } catch {
        return false;
      }
    },
    handleSuccess(response, file, fileList) {
      let url = this.ossUploadUrl + "/" + this.dataObj.key;
      this.fileList.push({
        uid: file.uid,
        name: file.name,
        url,
        percent: 100,
      });
    },
    handleChange() {
      const files = this.$refs.uploadInput.files;

      for (let i = 0; i < files.length; i++) {
        const file = files[i];
        const reader = new FileReader();
        const key =
          new Date().getTime() + "_" + Math.ceil(Math.random() * 99999);
        reader.readAsDataURL(file);
        reader.onload = () => {
          if (this.editIndex >= 0) {
            this.$set(this.fileList, this.editIndex, {
              key,
              url: reader.result,
              percent: 0,
              status: "uploading",
            });

            this.editIndex = -1;
          } else {
            this.fileList.push({
              key,
              url: reader.result,
              percent: 0,
              status: "uploading",
            });
          }

          this.$nextTick(() => {
            this.uplaodAction(reader.result, file, key);
            // if (this.isQiniu) {
            //   this.uplaodAction2(reader.result, file, key)
            // } else {
            //   this.uplaodAction(reader.result, file, key)
            // }
          });
        };
      }
      this.$refs.uploadInput.value = [];
    },
    async uplaodAction(res, file, key) {
      try {
        let filename = file.name.replaceAll(" ", "_");
        let key = new Date().getTime() + filename;
        let obj = {
          filename,
          bucketName: "daya",
          postData: {
            filename,
            acl: "public-read",
            key,
            unknowValueField: [],
          },
        };
        const res = await policy(obj);
        this.dataObj = {
          policy: res.data.policy,
          signature: res.data.signature,
          key,
          KSSAccessKeyId: res.data.kssAccessKeyId,
          acl: "public-read",
          name: filename,
        };
      } catch {}
      // eslint-disable-next-line no-unused-vars
      const changeIndex = this.fileList.findIndex((item) => item.key === key);
      const xhr = new XMLHttpRequest();

      const url = this.ossUploadUrl;
      xhr.open("POST", url, true);
      // xhr.setRequestHeader('Content-Type', 'multipart/form-data')

      const formData = new FormData();
      formData.append(this.dataObj.name, file, this.dataObj.name);
      formData.append("policy", this.dataObj.policy);
      formData.append("signature", this.dataObj.signature);
      formData.append("key", this.dataObj.key);
      formData.append("KSSAccessKeyId", this.dataObj.KSSAccessKeyId);
      formData.append("acl", "public-read");
      formData.append("name", this.dataObj.name);

      xhr.send(formData);
      xhr.onreadystatechange = () => {
        if (xhr.readyState === 4) {
          console.log(xhr, "xhr");
          const tempData = JSON.parse(xhr.response);
          const resData = tempData.data;
          var uploadUrl = "";
          if (
            resData.url !== undefined &&
            resData.url !== null &&
            resData.url !== ""
          ) {
            uploadUrl = resData.url;
          } else if (
            resData.data !== undefined &&
            resData.data !== null &&
            resData.data !== ""
          ) {
            uploadUrl = resData.data;
          }
          if (resData && uploadUrl) {
            this.$set(
              this.fileList,
              this.fileList.findIndex((item) => item.key === key),
              {
                ...this.fileList[
                  this.fileList.findIndex((item) => item.key === key)
                ],
                url: uploadUrl,
                percent: 100,
              }
            );
            setTimeout(() => {
              this.$set(
                this.fileList,
                this.fileList.findIndex((item) => item.key === key),
                {
                  ...this.fileList[
                    this.fileList.findIndex((item) => item.key === key)
                  ],
                  status: "success",
                }
              );
              this.$emit("input", this.fileList);
            }, 200);
          } else {
            this.$set(
              this.fileList,
              this.fileList.findIndex((item) => item.key === key),
              {
                ...this.fileList[
                  this.fileList.findIndex((item) => item.key === key)
                ],
                status: "error",
              }
            );
            this.fileList.splice(
              this.fileList.findIndex((item) => item.key === key),
              1
            );
          }
        }
      };
      xhr.onprogress = (res) => {
        if (res.total && res.loaded) {
          this.$set(
            this.fileList[this.fileList.findIndex((item) => item.key === key)],
            "percent",
            (res.loaded / res.total) * 100
          );
        }
      };
    },
    uplaodAction2(res, file, key) {
      const _this = this;
      const observable = qiniu.upload(
        file,
        key,
        this.token,
        {
          fname: key,
          mimeType: [],
        },
        {
          useCdnDomain: true,
          region: qiniu.region.z2,
        }
      );
      observable.subscribe({
        next(res) {
          _this.$set(
            _this.fileList[
              _this.fileList.findIndex((item) => item.key === key)
            ],
            "percent",
            parseInt(res.total.percent)
          );
        },
        // eslint-disable-next-line handle-callback-err
        error(err) {
          _this.$set(
            _this.fileList,
            _this.fileList.findIndex((item) => item.key === key),
            {
              ..._this.fileList[
                _this.fileList.findIndex((item) => item.key === key)
              ],
              status: "error",
            }
          );
          _this.fileList.splice(
            _this.fileList.findIndex((item) => item.key === key),
            1
          );
        },
        complete(res) {
          _this.$set(
            _this.fileList,
            _this.fileList.findIndex((item) => item.key === key),
            {
              ..._this.fileList[
                _this.fileList.findIndex((item) => item.key === key)
              ],
              url: _this.domain + res.key,
              percent: 100,
            }
          );
          setTimeout(() => {
            _this.$set(
              _this.fileList,
              _this.fileList.findIndex((item) => item.key === key),
              {
                ..._this.fileList[
                  _this.fileList.findIndex((item) => item.key === key)
                ],
                status: "success",
              }
            );
            _this.$emit("input", _this.fileList);
          }, 200);
        },
      });
    },
    handleRemove(key) {
      this.fileList.splice(
        this.fileList.findIndex((item) => item.key === key),
        1
      );
    },
    handleEdit(key) {
      this.editIndex = this.fileList.findIndex((item) => item.key === key);

      this.$refs.uploadInput.click();
    },
    handleMeitu(key) {
      this.$emit(
        "on-meitu",
        this.fileList.findIndex((item) => item.key === key)
      );
    },
    handleAdd() {
      if (!this.disabled) {
        this.editIndex = -1;
        this.$refs.uploadInput.click();
      }
    },
    handlePreviewFile(key) {
      this.viewer && this.viewer.destroy();
      this.uploadId = "upload_" + new Date().getTime();

      this.$nextTick(() => {
        this.viewer = new Viewer(document.getElementById(this.uploadId));
        this.viewer.view(this.fileList.findIndex((item) => item.key === key));
      });
    },
  },
};
</script>

<style lang="scss">
.fm-uplaod-container {
  .is-disabled {
    position: relative;

    &::after {
      position: absolute;
      top: 0;
      bottom: 0;
      left: 0;
      right: 0;
      // background: rgba(0,0,0,.1);
      content: "";
      display: block;
      cursor: not-allowed;
    }
  }

  .upload-file {
    margin: 0 10px 10px 0;
    display: inline-flex;
    justify-content: center;
    align-items: center;
    // background: #fff;
    overflow: hidden;
    background-color: #fff;
    border: 1px solid #c0ccda;
    border-radius: 6px;
    box-sizing: border-box;
    position: relative;
    vertical-align: top;
    &:hover {
      .uplaod-action {
        display: flex;
      }
    }
    .uplaod-action {
      position: absolute;
      // top: 0;
      // height: 30px;
      bottom: 0;
      left: 0;
      right: 0;
      background: rgba(0, 0, 0, 0.6);
      display: none;
      justify-content: center;
      align-items: center;
      i {
        color: #fff;
        cursor: pointer;
        margin: 0 5px;
      }
    }
    &.is-success {
      .item-status {
        position: absolute;
        right: -15px;
        top: -6px;
        width: 40px;
        height: 24px;
        background: #13ce66;
        text-align: center;
        transform: rotate(45deg);
        box-shadow: 0 0 1pc 1px rgba(0, 0, 0, 0.2);
        & > i {
          font-size: 12px;
          margin-top: 11px;
          color: #fff;
          transform: rotate(-45deg);
        }
      }
    }
    &.uploading {
      &:before {
        display: block;
        content: "";
        position: absolute;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        background: rgba(0, 0, 0, 0.3);
      }
    }
    .upload-progress {
      position: absolute;
      .el-progress__text {
        color: #fff;
        font-size: 16px !important;
      }
    }
    img {
      max-width: 100%;
      max-height: 100%;
      vertical-align: middle;
    }
  }
  .el-upload--picture-card {
    position: relative;
    overflow: hidden;
    .el-icon-plus {
      position: absolute;
      top: 50%;
      left: 50%;
    }
  }
  .upload-input {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    display: block;
    opacity: 0;
    cursor: pointer;
  }

  .drag-img-list {
    display: inline;

    .ghost {
      position: relative;
      &::after {
        width: 100%;
        height: 100%;
        display: block;
        content: "";
        background: #fbfdff;
        position: absolute;
        top: 0;
        bottom: 0;
        left: 0;
        right: 0;
        border: 1px dashed #3bb3c2;
      }
    }

    & > div {
      cursor: move;
    }
  }
}

.viewer-container {
  z-index: 9999 !important;
}
</style>
