import { defineComponent } from 'vue'
import 'vue-cropper/dist/index.css'
import { VueCropper } from 'vue-cropper'
import styles from './index.module.less'

export default defineComponent({
  name: 'o-cropper',
  components: { VueCropper },
  props: {
    hideInput: {
      type: Boolean,
      default: false
    },
    option: {
      type: Object
    },
    onCancelTailor: {
      type: Function,
      default: () => {}
    }, // 取消
    getBase64Data: {
      type: Function,
      default: () => {}
    },
    getBlob: {
      type: Function,
      default: () => {}
    },
    getFile: {
      type: Function,
      default: () => {}
    },
    imgOriginF: {
      type: Function,
      default: () => {}
    }
  },
  data() {
    return {
      img: '',
      config: {
        ceilbutton: false, //顶部按钮，默认底部
        outputSize: 1, //裁剪生成图片的质量
        outputType: 'png', //裁剪生成图片的格式,默认png
        info: false, //裁剪框的大小信息
        canScale: true, //图片是否允许滚轮缩放
        autoCrop: false, //是否默认生成截图框
        autoCropWidth: 0, //默认生成截图框宽度
        autoCropHeight: 0, //默认生成截图框高度
        fixed: true, //是否开启截图框宽高固定比例
        fixedNumber: [1, 1], //截图框的宽高比例
        full: false, //是否输出原图比例的截图
        fixedBox: true, //固定截图框大小 不允许改变
        canMove: true, //上传图片是否可以移动
        canMoveBox: false, //截图框能否拖动
        original: false, //上传图片按照原始比例渲染
        centerBox: true, //截图框是否被限制在图片里面
        high: true, //是否按照设备的dpr 输出等比例图片
        infoTrue: false, //true 为展示真实输出图片宽高 false 展示看到的截图框宽高
        maxImgSize: 2000, //限制图片最大宽度和高度
        enlarge: 1, //图片根据截图框输出比例倍数
        mode: '100%', //图片默认渲染方式
        cancelButtonText: '取消', //取消按钮文本
        confirmButtonText: '确定', //确定按钮文本
        cancelButtonBackgroundColor: '#606266', //取消按钮背景色
        confirmButtonBackgroundColor: '#ed594c', //确定按钮背景色
        cancelButtonTextColor: '#ffffff', //取消按钮字体色
        confirmButtonTextColor: '#ffffff' //确定按钮字体色
      }
    }
  },
  mounted() {
    this.config = Object.assign(this.config, this.option)
  },
  methods: {
    //添加网格线
    addSlide() {
      if (document.getElementById('vertical') == null) {
        const box = document.getElementsByClassName('cropper-crop-box')[0]
        //左网格线
        const verticalLeft = document.createElement('div')
        verticalLeft.id = 'vertical'
        verticalLeft.style.width = '1px'
        verticalLeft.style.height = '100%'
        verticalLeft.style.top = '0px'
        verticalLeft.style.left = '33%'
        verticalLeft.style.position = 'absolute'
        verticalLeft.style.backgroundColor = '#fff'
        verticalLeft.style.zIndex = '522'
        verticalLeft.style.opacity = '0.5'
        //右网格线
        const verticalRight = document.createElement('div')
        verticalRight.style.width = '1px'
        verticalRight.style.height = '100%'
        verticalRight.style.top = '0px'
        verticalRight.style.right = '33%'
        verticalRight.style.position = 'absolute'
        verticalRight.style.backgroundColor = '#fff'
        verticalRight.style.zIndex = '522'
        verticalRight.style.opacity = '0.5'
        //上网格线
        const verticalTop = document.createElement('div')
        verticalTop.style.width = '100%'
        verticalTop.style.height = '1px'
        verticalTop.style.top = '33%'
        verticalTop.style.left = '0px'
        verticalTop.style.position = 'absolute'
        verticalTop.style.backgroundColor = '#fff'
        verticalTop.style.zIndex = '522'
        verticalTop.style.opacity = '0.5'
        //下网格线
        const verticalBottom = document.createElement('div')
        verticalBottom.style.width = '100%'
        verticalBottom.style.height = '1px'
        verticalBottom.style.bottom = '33%'
        verticalBottom.style.left = '0px'
        verticalBottom.style.position = 'absolute'
        verticalBottom.style.backgroundColor = '#fff'
        verticalBottom.style.zIndex = '522'
        verticalBottom.style.opacity = '0.5'
        //左上边线
        const LeftTopSide = document.createElement('div')
        LeftTopSide.style.width = '30px'
        LeftTopSide.style.height = '4px'
        LeftTopSide.style.top = '-4px'
        LeftTopSide.style.left = '-4px'
        LeftTopSide.style.position = 'absolute'
        LeftTopSide.style.backgroundColor = '#fff'
        LeftTopSide.style.zIndex = '522'
        LeftTopSide.style.opacity = '1'
        //上左边线
        const TopListSide = document.createElement('div')
        TopListSide.style.width = '4px'
        TopListSide.style.height = '30px'
        TopListSide.style.top = '-4px'
        TopListSide.style.left = '-4px'
        TopListSide.style.position = 'absolute'
        TopListSide.style.backgroundColor = '#fff'
        TopListSide.style.zIndex = '522'
        TopListSide.style.opacity = '1'
        //右上边线
        const RightTopSide = document.createElement('div')
        RightTopSide.style.width = '30px'
        RightTopSide.style.height = '4px'
        RightTopSide.style.top = '-4px'
        RightTopSide.style.right = '-4px'
        RightTopSide.style.position = 'absolute'
        RightTopSide.style.backgroundColor = '#fff'
        RightTopSide.style.zIndex = '522'
        RightTopSide.style.opacity = '1'
        //上右边线
        const TopRightSide = document.createElement('div')
        TopRightSide.style.width = '4px'
        TopRightSide.style.height = '30px'
        TopRightSide.style.top = '-4px'
        TopRightSide.style.right = '-4px'
        TopRightSide.style.position = 'absolute'
        TopRightSide.style.backgroundColor = '#fff'
        TopRightSide.style.zIndex = '522'
        TopRightSide.style.opacity = '1'
        //左下边线
        const LeftBottomSide = document.createElement('div')
        LeftBottomSide.style.width = '30px'
        LeftBottomSide.style.height = '4px'
        LeftBottomSide.style.bottom = '-4px'
        LeftBottomSide.style.left = '-4px'
        LeftBottomSide.style.position = 'absolute'
        LeftBottomSide.style.backgroundColor = '#fff'
        LeftBottomSide.style.zIndex = '522'
        LeftBottomSide.style.opacity = '1'
        //下左边线
        const BottomListSide = document.createElement('div')
        BottomListSide.style.width = '4px'
        BottomListSide.style.height = '30px'
        BottomListSide.style.bottom = '-4px'
        BottomListSide.style.left = '-4px'
        BottomListSide.style.position = 'absolute'
        BottomListSide.style.backgroundColor = '#fff'
        BottomListSide.style.zIndex = '522'
        BottomListSide.style.opacity = '1'
        //右下边线
        const RightBottomSide = document.createElement('div')
        RightBottomSide.style.width = '30px'
        RightBottomSide.style.height = '4px'
        RightBottomSide.style.bottom = '-4px'
        RightBottomSide.style.right = '-4px'
        RightBottomSide.style.position = 'absolute'
        RightBottomSide.style.backgroundColor = '#fff'
        RightBottomSide.style.zIndex = '522'
        RightBottomSide.style.opacity = '1'
        //下右边线
        const BottomRightSide = document.createElement('div')
        BottomRightSide.style.width = '4px'
        BottomRightSide.style.height = '30px'
        BottomRightSide.style.bottom = '-4px'
        BottomRightSide.style.right = '-4px'
        BottomRightSide.style.position = 'absolute'
        BottomRightSide.style.backgroundColor = '#fff'
        BottomRightSide.style.zIndex = '522'
        BottomRightSide.style.opacity = '1'
        //一起生成
        box.appendChild(verticalLeft)
        box.appendChild(verticalRight)
        box.appendChild(verticalTop)
        box.appendChild(verticalBottom)
        box.appendChild(LeftTopSide)
        box.appendChild(TopListSide)
        box.appendChild(RightTopSide)
        box.appendChild(TopRightSide)
        box.appendChild(LeftBottomSide)
        box.appendChild(BottomListSide)
        box.appendChild(RightBottomSide)
        box.appendChild(BottomRightSide)
      }
    },
    //异步onload图片
    onLoadImg(photoUrl: any) {
      return new Promise(function (resolve, reject) {
        const reader = new FileReader()
        reader.readAsDataURL(photoUrl)
        reader.onload = (e: any) => {
          resolve(e.target['result'])
        }
      })
    },
    /**
     * 载入文件
     * template:
     *    <h5-cropper hide-input ref="cropper">
     *
     * javascript:
     *    this.$refs.cropper.loadFile()
     *
     * @param file
     */
    loadFile(file: any) {
      if (file instanceof File) {
        this.onLoadImg(file).then((base64: any) => {
          this.img = base64
          setTimeout(() => {
            this.config.autoCrop = true
            this.addSlide()
          }, 10)
        })
      } else {
        throw new Error('Arguments file is not File')
      }
    },
    /**
     *
     * @param base64
     */
    loadBase64(base64: string) {
      if (typeof base64 !== 'string') {
        throw new Error('Arguments base64 is not string')
      }
      const base = base64.split(',')
      if (!/^data:image\/(.*?);base64$/.test(base[0])) {
        throw new Error('Arguments base64 MIME is not image/*')
      }
      // Base64 Regex @see https://learnku.com/articles/42295
      if (!/^[\/]?([\da-zA-Z]+[\/+]+)*[\da-zA-Z]+([+=]{1,2}|[\/])?$/.test(base[1])) {
        throw new Error('Not standard base64')
      }
      this.img = base64
      setTimeout(() => {
        this.config.autoCrop = true
        this.addSlide()
      }, 10)
    },
    rotating(e: any) {
      ;(this as any).$refs.cropper.rotateRight()
      // document.getElementsByClassName("cropper-modal")[0].style = "background-color: rgba(0,0,0,0.5);transition: 0.88s";
    },
    canceltailor() {
      this.img = ''
      this.onCancelTailor()
    },
    tailoring() {
      // 获取截图的base64数据
      ;(this as any).$refs.cropper.getCropData((data: any) => {
        this.getBase64Data(data)
        this.getBlob(data)
        this.img = ''
        this.config.autoCrop = false
      })
      // 获取截图的blob数据
      ;(this as any).$refs.cropper.getCropBlob((data: BlobPart) => {
        this.getBase64Data(data)
        this.getBlob(data)
        // Blob 转 File
        const suffix = {
          jpeg: 'jpg',
          png: 'png',
          webp: 'webp'
        }[this.config.outputType]
        const time = new Date().getTime()
        const file = new File([data], `${time}.${suffix}`, {
          type: `image/${this.config.outputType}`
        })
        this.getFile(file)
        this.img = ''
        this.config.autoCrop = false
      })
    },
    async upPhoto(e: any) {
      let photoUrl = e.target.files[0]
      ;(this as any).$refs.headInput.value = null
      if (photoUrl != undefined) {
        this.imgOriginF(photoUrl)
        this.img = (await this.onLoadImg(photoUrl)) as string
        this.config.autoCrop = true
        setTimeout(() => {
          this.addSlide()
        }, 20)
      }
    },
    onCropMoving(e: any) {
      // console.log('onCropMoving')
    },
    onImgMoving(e: any) {
      // console.log('onCropMoving')
    }
  },
  render() {
    return (
      <div class={[styles.upbtn, styles.uploadWarper]}>
        {this.hideInput}
        {!this.hideInput ? (
          <input
            style="opacity: 0;"
            class={styles.upbtn}
            type="file"
            accept="image/*"
            onChange={this.upPhoto}
            ref="headInput"
          />
        ) : null}
        {this.img != '' ? (
          <div class={styles.bg}>
            {this.config.ceilbutton ? (
              <div class={styles.btndiv}>
                <div
                  class={styles.btn}
                  onClick={this.canceltailor}
                  style={{
                    backgroundColor: this.config.cancelButtonBackgroundColor,
                    color: this.config.cancelButtonTextColor
                  }}
                >
                  {this.config.cancelButtonText}
                </div>
                <div class={styles.img} onClick={this.rotating}></div>
                <div
                  class={styles.btn}
                  onClick={this.tailoring}
                  style={{
                    backgroundColor: this.config.confirmButtonBackgroundColor,
                    color: this.config.confirmButtonTextColor
                  }}
                >
                  {this.config.confirmButtonText}
                </div>
              </div>
            ) : null}

            <div class={styles.wrapper}>
              <VueCropper
                ref="cropper"
                img={this.img}
                outputSize={this.config.outputSize}
                outputType={this.config.outputType}
                info={this.config.info}
                canScale={this.config.canScale}
                autoCrop={this.config.autoCrop}
                autoCropWidth={this.config.autoCropWidth}
                autoCropHeight={this.config.autoCropHeight}
                fixedBox={this.config.fixedBox}
                fixed={this.config.fixed}
                fixedNumber={this.config.fixedNumber}
                full={this.config.full}
                canMove={this.config.canMove}
                canMoveBox={this.config.canMoveBox}
                original={this.config.original}
                centerBox={this.config.centerBox}
                high={this.config.high}
                infoTrue={this.config.infoTrue}
                maxImgSize={this.config.maxImgSize}
                enlarge={this.config.enlarge}
                mode={this.config.mode}
                onCropMoving={this.onCropMoving}
                onImgMoving={this.onImgMoving}
              ></VueCropper>
            </div>

            {!this.config.ceilbutton ? (
              <div class={styles.btndiv}>
                <div
                  class={styles.btn}
                  onClick={this.canceltailor}
                  style={{
                    backgroundColor: this.config.cancelButtonBackgroundColor,
                    color: this.config.cancelButtonTextColor
                  }}
                >
                  {this.config.cancelButtonText}
                </div>
                <div class={styles.img} onClick={this.rotating}></div>
                <div
                  class={styles.btn}
                  onClick={this.tailoring}
                  style={{
                    backgroundColor: this.config.confirmButtonBackgroundColor,
                    color: this.config.confirmButtonTextColor
                  }}
                >
                  {this.config.confirmButtonText}
                </div>
              </div>
            ) : null}
          </div>
        ) : null}
      </div>
    )
  }
})
