<template>
    <div class="para-image para-item">
        <input ref="fileInput" type="file" @change="cropperFile" style="display: none">
        <div :style="{position: 'relative','width':width1, 'height': height1}">
            <img :src="image" alt="" @click="selectFile" class="show-image"
                 :style="{'width':width1, 'height': height1, 'border-radius': radius1, cursor:disabled1?'pointer':'auto', 'border': border1}">

            <Tooltip placement="top">
                <template slot="title">
                    <span>{{tips1[language]}}{{size1+'K'}}</span>
                </template>
                <Icon type="plus" v-if="!image && !disabled1" class="add" @click="selectFile"/>
            </Tooltip>
        </div>
        <Button html-type="button" @click="selectFile()" v-if="!disabled1 && showbtn1">
            {{buttonName1}}
        </Button>
        <Modal
                top="2%"
                title="剪裁图片"
                size="small"
                v-model="cutImageDialog"
                :footer="null"
                :centered="true"
                :closable="true"
                :afterClose="dialogClose">
            <div>
                <div ref="cutImageBox" style="height: 300px;overflow: hidden"></div>
                <div class="dialogButton">
                    <Button @click="cutCancel" class="para-cancel-button">{{lang[language].cancel}}</Button>
                    <Button class="para-" @click="cutFinsh">{{lang[language].cut}}</Button>
                </div>
            </div>
        </Modal>
    </div>
</template>

<script>
  import {Button, Modal, Icon, Tooltip, message} from 'ant-design-vue';
  import Cropper from 'cropperjs';
  import 'cropperjs/dist/cropper.css';

  function $isNull(e) {
    if (e === '') return true;
    if (e === null) return true;
    if (e === undefined) return true;
    return false;
  }

  function dataURLtoBlob(dataurl) {
    //将base64转换为文件Blob
    var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1],
      bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
    while (n--) {
      u8arr[n] = bstr.charCodeAt(n);
    }
    return new Blob([u8arr], {type: mime});
  }

  function dataURLtoFile(dataurl, filename) {
    //将base64转换为文件
    var arr = dataurl.split(','),
      mime = arr[0].match(/:(.*?);/)[1],
      bstr = atob(arr[1]),
      n = bstr.length,
      u8arr = new Uint8Array(n);
    while (n--) {
      u8arr[n] = bstr.charCodeAt(n);
    }
    return new File([u8arr], filename, {
      type: mime
    });
  }

  const lang = {
    zh_CN: {
      'cancel': '取 消',
      'cutImg': '剪裁图片',
      'cut': '裁 切',
      'select': '选择图像',
      'msg': [
        '图片格式错误',
        [
          '图片过大,请选择小于',
          'K的图片文件'
        ]
      ]
    },
    en_GB: {
      'cancel': 'Cancel',
      'cutImg': 'Cut images',
      'cut': 'Cut',
      'select': 'Select the image',
      'msg': [
        'Picture format error',
        [
          'The picture is too big, please select less than',
          'K picture file'
        ]
      ]
    }
  };
  export default {
    name: 'paraImage',
    components: {Button, Modal, Icon, Tooltip},
    props: [
      'value', // 图像值
      'disabled', // 禁用
      'width', // 图片框宽度
      'height', // 图片框高度
      'radius', // 圆角
      'buttonName', // 按钮文字
      'size', // 图片大小限制
      'border',
      'tips',
      'showbtn',
      'isFile'
    ],
    data() {
      return {
        lang,
        loading: true,
        image: '',
        cutImageDialog: false,
        disabled1: this.disabled || false,
        width1: '0px',
        height1: '0px',
        radius1: '8',
        border1: '1px dashed #DCDFE6',
        tips1: {
          zh_CN: '照片大小限制',
          en_GB: 'Photo size limit'
        },
        size1: 1024,
        showbtn1: false,
        buttonName1: this.buttonName
      };
    },
    mounted() {
      this.buttonName1 = this.lang[this.language].select;
      this.setW(this.width || 150);
      this.setH(this.height || 150);
      this.setR(this.radius || 8);
      this.setB(this.border || 0);
      // this.setTips(this.tips || '');
      this.setSize(this.size || 1024);
      this.setShowBtn(this.showbtn || false);
      this.setFile(this.isFile || false);
      this.setValue(this.value || '');
    },
    methods: {
      setTips(val) {
        if (val) this.tips1 = val;
      },
      setFile(val) {
        this.isFile1 = val;
      },
      setShowBtn(val) {
        this.showbtn1 = val;
      },
      setSize(val) {
        if (val) this.size1 = val;
      },
      setW(val) {
        if (!Number.isNaN(val)) this.width1 = val + 'px';
      },
      setH(val) {
        if (!Number.isNaN(val)) this.height1 = val + 'px';
      },
      setR(val) {
        if (!Number.isNaN(val)) this.radius1 = val + '%';
      },
      setB(val) {
        if (typeof val !== 'string') return val;
        this.border1 = val;
      },
      setValue(val) {
        if (typeof val !== 'string' && !(val instanceof File)) return val;
        // eslint-disable-next-line no-useless-escape
        // base64
        // file 对象
        if (val instanceof File) {
          val = URL.createObjectURL(val);
        } else if (!/^data\:image\/.*?;base64/.test(val)) {
          // 拼接base64的头
          if ($isNull(val)) {
            val = '';
          } else {
            if (!/^http.*?:\/\/.*/.test(val)) {
              val = 'data:image/png;base64,' + val;
            }
          }
        }
        this.image = val;
      },
      // 选择文件
      selectFile() {
        if (this.disabled1) return;
        this.loadNum = 0;
        //this.$refs.fileInput.click();
        this.$refs.fileInput.dispatchEvent(new MouseEvent('click'));
      },
      cropperFile() {
        const input = this.$refs.fileInput;
        // 通过DOM取文件数据
        this.file = input.files[0];
        if (!this.file) return;
        // 判断文件格式
        if (!/^image\//.test(this.file.type)) {
          // $msg(lang.msg[0], 2);
          message.warning(lang[this.language].msg[0]);
          return;
        }
        // 判断文件大小限制
        if (this.file.size > Number(this.size1) * 1024) {
          message.warning(lang[this.language].msg[1][0] + this.size1 + lang[this.language].msg[1][1]);
          // $msg(lang.msg[1][0] + this.size + lang.msg[1][1], 2);
          return;
        }
        this.loading = true;
        const reader = new FileReader();
        // 将图片将转成 base64 格式
        reader.readAsDataURL(this.file);
        this.loadNum = 0;
        // this.imageData = reader.result;
        reader.onload = () => {
          this.imageData = reader.result;
          this.loadNum++;
          this.loadComplete();
        };
        this.cutImageDialog = true;
      },
      dialogOpen() {
        clearTimeout(this.closeTimeout);
        this.loadNum++;
        this.loadComplete();
      },
      loadComplete() {
        if (this.loadNum !== 2) return;
        this.cropperInit(this.imageData);
        this.loading = false;
      },
      dialogClose() {
        clearTimeout(this.closeTimeout);
        this.closeTimeout = setTimeout(
          () => {
            // eslint-disable-next-line no-console
            this.$refs.cutImageBox.getElementsByClassName('cut-img')[0].style.display = 'none';
            this.$refs.fileInput.value = '';
            if (this.cropper) {
              this.cropper.destroy();
              this.cropper = null;
            }
          },
          200
        );
      },
      cropperInit(image) {
        setTimeout(
          () => {
            const box = this.$refs.cutImageBox;
            box.innerHTML = `<img class="cut-img" src="${image}" style="display: none">`;
            this.cropper = new Cropper(box.getElementsByClassName('cut-img')[0], {
              aspectRatio: parseInt(this.width1, 10) / parseInt(this.height1, 10),
              crop: () => {
                box.getElementsByClassName('cropper-view-box')[0].style.borderRadius = this.radius1;
                box.getElementsByClassName('cut-img')[0].style.display = 'block';
              }
            });
          },
          0
        );
      },
      // 裁剪完成
      cutFinsh() {
        const img = this.cropper.getCroppedCanvas();
        this.image = img.toDataURL('image/png');
        if (this.isFile1) {
          let filePng = dataURLtoFile(this.image, new Date().getTime() + '.png');
          // 转成file对象
          this.$emit('input', filePng);
          this.$emit('change', filePng);
        } else {
          this.$emit('input', this.image);
          this.$emit('change', this.image);
        }
        /* let formData = new FormData();
         formData.append('file', dataURLtoFile(this.image)); */
        this.cutImageDialog = false;

        this.$refs.fileInput.value = '';
      },
      cutCancel() {
        this.cutImageDialog = false;
      }
    },
    watch: {
      cutImageDialog(val) {
        // eslint-disable-next-line no-console
        if (val) {
          this.dialogOpen();
        }
      },
      width(val) {
        if (Number.isNaN(val)) {
          // eslint-disable-next-line no-console
          console.warn('para-image width is number');
          return;
        }
        this.setW(val);
      },
      height(val) {
        if (Number.isNaN(val)) {
          // eslint-disable-next-line no-console
          console.warn('para-image height is number');
          return;
        }
        this.setH(val);
      },
      radius(val) {
        if (Number.isNaN(val)) {
          // eslint-disable-next-line no-console
          console.warn('para-image radius is number');
          return;
        }
        this.setR(Number(val));
      },
      buttonName(val) {
        if (typeof val !== 'string') {
          // eslint-disable-next-line no-console
          console.warn('para-image Button-name is string');
          return;
        }
        this.buttonName1 = val;
      },
      disabled(val) {
        if (typeof val !== 'boolean') {
          // eslint-disable-next-line no-console
          console.warn('para-image disabled is boolean');
          return;
        }
        this.disabled1 = val;
      },
      showbtn(val) {
        if (typeof val !== 'boolean') {
          // eslint-disable-next-line no-console
          console.warn('para-image showbtn is boolean');
          return;
        }
        this.showbtn1 = val;
      },
      value(val, old) {
        if (val === old) return;
        this.setValue(val);
      }
    },
    computed: {
      language() {
        return JSON.parse(window.localStorage[window.$project]).setting.language || 'zh_CN';
      }
    }
  };
</script>
