<template>
  <div class="ipub-upload-cropper">
    <div :class="['ipub-upload-cropper__block', ipubClass]"
         :style="`height:${canHeight}px;width:${canWidth}px`">
      <template v-if="imgUrl&&!loading">
        <img :src="showImg"
             alt="">
        <div class="ipub-upload-cropper__block__wrap">
          <div :class="['ipub-upload-cropper__block__wrap__btns',canWidth<300?'':'flex-center']">
            <div :class="['tc',canWidth<300&&clearable?'mar-b-10':'']">
              <ipub-button icon="iconReplace"
                           v-if="canWidth>150"
                           @click="handleClick"
                           size="small"
                           type="primary">Replace</ipub-button>
              <ipub-button icon="iconReplace"
                           v-else
                           @click="handleClick"
                           size="small"
                           type="primary"></ipub-button>
            </div>
            <div v-if="clearable"
                 :class="['tc',canWidth>300?'mar-l-10':'']">
              <ipub-button icon="iconDelete"
                           @click="handleDelete"
                           size="small"
                           type="primary">Delete</ipub-button>
            </div>
          </div>
        </div>
      </template>
      <template v-else-if="loading">
        <div class="tc link-color">
          <ipub-icon class="mar-b-10"
                     style="font-size:40px"
                     type="loading" />
          <div class="ipub-p2">Image Uploading</div>
        </div>
      </template>
      <template v-else>
        <div class="tc"
             @click="handleClick">
          <template v-if="canWidth>200">
            <ipub-icon class="mar-b-10"
                       style="font-size:40px"
                       type="iconupload" />
            <div class="tc mar-b-24">
              Drag or drop your image <br />
              here or <font class="link-color">Select file</font>
            </div>
            <div class="default-color tc">
              Suggested size: {{canHeight}}px * {{canWidth}}px; Only support .png; File size should be less than {{size>=1024?`${(size*0.1/102.4).toFixed(2)}MB`:`${size}KB`}}.
            </div>
          </template>
          <template v-else>
            <ipub-tooltip>
              <div class="tc"
                   slot="title">
                <div class="default-color tc">
                  Suggested size: {{canHeight}}px * {{canWidth}}px; Only support .png; File size should be less than {{size>=1024?`${(size*0.1/102.4).toFixed(2)}MB`:`${size}KB`}}.
                </div>
              </div>
              <ipub-icon class="mar-b-10"
                         style="font-size:40px"
                         type="iconupload" />
              <div class="tc">Select file</div>
            </ipub-tooltip>
          </template>
        </div>
      </template>
    </div>
    <ipub-model :title="'Edit Image'"
                style="text-align:left"
                width="764px"
                :visable="isVisable"
                @confirm="confirm"
                @cancel="cancel">
      <div class="cropper">
        <div class="cropper-vues"
             :style="`transform: scale(${scales});width:calc(678px/${scales});height:calc(420px/${scales})`">
          <vues-cropper ref="cropper-upload"
                        :img="option.img"
                        :outputSize="option.size"
                        :outputType="option.outputType"
                        :info="true"
                        :full="option.full"
                        :canMove="option.canMove"
                        :canMoveBox="option.canMoveBox"
                        :original="option.original"
                        :autoCrop="option.autoCrop"
                        :autoCropWidth="option.autoCropWidth"
                        :autoCropHeight="option.autoCropHeight"
                        :fixed="option.fixed"
                        :fixedBox="option.fixedBox"
                        :fixedNumber="option.fixedNumber"
                        :centenBox="false"
                        @realTime="realTime">
          </vues-cropper>
        </div>
      </div>
      <div class="ipub-p1"
           style="text-align:left">
        Suggest Size: {{this.canWidth}}(width) * {{this.canHeight}}(height)px
        maxium {{size>=1024?`${(size*0.1/102.4).toFixed(2)}MB`:`${size}KB`}}. Only PNG & JPG can be uploaded
      </div>
      <div class="flex"
           slot="footer">
        <ipub-upload class="ipub-cursor-pointer"
                     @change="files => {change(files,1)}">
          <ipub-button type="primary"
                       style="width:150px">
            Upload Image
          </ipub-button>
        </ipub-upload>
        <ipub-button type="primary"
                     style="margin-left:20px;width:150px"
                     class="mar-l-20"
                     @click="confirm">
          Confirm
        </ipub-button>
        <ipub-button type="primary"
                     style="width:150px"
                     plain
                     @click="cancel">
          Cancel
        </ipub-button>
      </div>
    </ipub-model>

  </div>
</template>

<script>
// import VuesCropper from 'vue-cropper'
import IpubIcon from '../../icon'
import IpubModel from '../../model'
let VuesCropper = require('vue-cropper').VueCropper
export default {
  name: 'IpubUploadCropper',
  components: {
    VuesCropper, IpubIcon, IpubModel
  },
  props: {
    domain: {
      type: String,
      default: '',
    },
    imgUrl: {
      type: String,
      default: '',
    },
    canHeight: {
      type: Number,
      default: 320,
    },
    canWidth: {
      type: Number,
      default: 240,
    },
    scales: {
      type: Number,
      default: 0.5
    },
    size: {
      type: Number,
      default: 500,
    },
    loading: Boolean,
    clearable: Boolean,
  },
  inject: {
    ipubFormItem: {
      default: false
    }
  },
  data () {
    return {
      files: [],
      previews: {},
      isVisable: false,
      showImg: '',
      option: {
        img: '',
        outputSize: 1, //剪切后的图片质量（0.1-1）
        full: false,//输出原图比例截图 props名full
        outputType: 'png',
        canMove: true,
        original: false,
        canMoveBox: false,
        autoCrop: true,
        autoCropWidth: 678,
        autoCropHeight: 480,
        fixedBox: false,
        fixed: true,
        fixedNumber: [this.canWidth, this.canHeight]
        // fixed: true
        // center: true
      },
      currentImg: ''
    }
  },
  watch: {
    isVisable (val) {
      if (val) {
        this.option.autoCropHeight = this.canHeight
        this.option.autoCropWidth = this.canWidth
        this.setAvatarBase64(this.showImg, (base64) => {
          this.option.img = base64
        });
      } else {
        this.option.img = ''
      }
    },
    imgUrl: {
      handler (val) {
        this.showImg = this.domain ? `${this.domain}/${val}` : val
      },
      immediate: true
    }
  },
  computed: {
    ipubClass () {
      let newClass = ''
      if (this.loading) {
        newClass += 'ipub-upload-cropper__block--loading '
      }
      if (this.ipubFormItem && this.ipubFormItem.validateStatus) {
        newClass += 'ipub--validateStatus '
      }
      return newClass
    }
  },
  methods: {
    handleClick () {
      this.isVisable = true
    },
    change (files, num) {
      this.files = files
      var selft = this;
      //上传图片
      const file = files[0]
      const types = ['image/jpeg', 'image/png']
      const rightType = types.includes(file.type)
      if (!rightType) {
        this.$message.error({
          title: 'Error',
          content: `Only PNG & JPG can be uploaded`
        })
        return false
      }
      if (file.size > this.size * 1024) {
        this.$message.error({
          title: 'Error',
          content: `File must not exceed ${this.size >= 1024 ? (this.size * 0.1 / 102.4).toFixed(2) + 'MB' : this.size + 'KB'}`
        })
        return false
      }
      selft.fileName = file.name;
      var reader = new FileReader();
      reader.onload = e => {
        let data;
        if (typeof e.target.result === "object") {
          // 把Array Buffer转化为blob 如果是base64不需要
          data = window.URL.createObjectURL(new Blob([e.target.result]));
        } else {
          data = e.target.result;
        }
        if (num === 1) {
          selft.option.img = data;
        } else if (num === 2) {
          selft.example2.img = data;
        }
      };
      // 转化为base64
      // reader.readAsDataURL(file)
      // 转化为blob
      reader.readAsArrayBuffer(file);
      // this.$emit('change', files)
    },
    realTime (data) {
      this.previews = data
    },
    async confirm () {
      await this.$refs['cropper-upload'].getCropBlob((data) => {
        let img = window.URL.createObjectURL(data)
        this.httpRequest(img).then(res => {
          let files = []
          files[0] = res
          this.$emit('change', files, 'close')
          this.isVisable = false
        })
      })
    },
    httpRequest (src) {
      return new Promise((resolve, reject) => {
        let fileName = ''
        if (this.files[0] && this.files[0].name) {
          fileName = Date.parse(new Date()) + this.files[0].name
        } else {
          fileName = Date.parse(new Date()) + 'image'
        }
        let xhr = new XMLHttpRequest()
        xhr.open('GET', src, true)
        xhr.responseType = 'blob'
        xhr.onload = function () {
          if (this.status == 200) {
            let myBlob = this.response;
            let files = new window.File([myBlob], fileName, { type: myBlob.type }) // myBlob.type 自定义文件名
            resolve(files)
          } else {
            reject(false)
          }
        };
        xhr.send();
      })
    },
    // 转化base64
    setAvatarBase64 (src, callback) {
      let _this = this;
      let image = new Image();
      // 处理缓存
      image.src = src + '?v=' + Math.random();
      // 支持跨域图片
      image.crossOrigin = "*";
      image.onload = function () {
        let base64 = _this.transBase64FromImage(image);
        callback && callback(base64);
      }
    },
    transBase64FromImage (image) {
      let canvas = document.createElement("canvas");
      canvas.width = image.width;
      canvas.height = image.height;
      let ctx = canvas.getContext("2d");
      ctx.drawImage(image, 0, 0, image.width, image.height);
      // 可选其他值 image/jpeg
      return canvas.toDataURL("image/png");
    },

    cancel () {
      this.isVisable = false
    },

    // 将网络图片转换成base64格式
    transBase64FromImage (image) {
      let canvas = document.createElement("canvas");
      canvas.width = image.width;
      canvas.height = image.height;
      let ctx = canvas.getContext("2d");
      ctx.drawImage(image, 0, 0, image.width, image.height);
      // 可选其他值 image/jpeg
      return canvas.toDataURL("image/png");
    },
    handleDelete (e) {
      this.$emit('delete')
    }
  }
}
</script>

<style lang="scss" scoped>
.ipub-upload-cropper {
  &__block {
    position: relative;
    display: flex;
    justify-content: center;
    align-items: center;
    flex-direction: column;
    border: 1px solid $border_color;
    box-sizing: border-box;
    border-radius: 2px;
    transition: 0.3s all;
    background: $content_color;
    cursor: pointer;
    > div {
      padding: 22px;
    }
    &:hover {
      border-color: $link_color;
    }
    > img {
      width: 100%;
      height: 100%;
      object-fit: cover;
    }
    &--loading {
      border-color: $link_color;
    }
    &__wrap {
      position: absolute;
      left: 0;
      top: 0;
      bottom: 0;
      right: 0;
      background: #00000040;
      opacity: 0;
      transition: 0.3s all;
      &__btns {
        position: absolute;
        bottom: 10px;
        width: calc(100% - 44px);
        box-sizing: border-box;
      }
    }
    &:hover {
      .ipub-upload-cropper__block__wrap {
        opacity: 1;
      }
    }
  }
  .cropper {
    height: 450px;
    display: flex;
    justify-content: space-between;
    &-vues {
      width: 1356px;
      height: 840px;
      // transform: scale(0.5);
      transform-origin: left top;
      position: absolute;
    }
  }
}
</style>
