<template>
  <div>
    <el-upload
      action="#"
      list-type="picture-card"
      :auto-upload="false"
      :limit="1"
      :file-list="fileList"
      :on-change="change"
    >
      <i slot="default" class="el-icon-plus"></i>
      <div slot="file" slot-scope="{ file }">
        <img class="el-upload-list__item-thumbnail" :src="file.url" alt="" />
        <span class="el-upload-list__item-actions">
          <span class="el-upload-list__item-delete" @click="handleRemove(file)">
            <i class="el-icon-delete"></i>
          </span>
        </span>
      </div>
    </el-upload>

    <r-dialog
      title="图片裁剪"
      :visible.sync="visible"
      @confirm="confirm"
      width="600px"
      append-to-body
    >
      <div class="flex" v-if="visible">
        <cropper-canvas style="width: 100%;flex:1" cover image>
          <cropper-image
            :src="file.url"
            alt="Picture"
            rotatable
            scalable
            skewable
            translatable
          ></cropper-image>
          <cropper-shade hidden></cropper-shade>
          <cropper-handle action="select" plain></cropper-handle>
          <cropper-selection
            id="cropperSelection"
            movable
            resizable
            x="150"
            y="100"
            width="275"
            height="275"
            ref="selection"
          >
            <cropper-handle
              action="move"
              theme-color="rgba(255, 255, 255, 0.35)"
            ></cropper-handle>
            <cropper-handle action="n-resize"></cropper-handle>
            <cropper-handle action="e-resize"></cropper-handle>
            <cropper-handle action="s-resize"></cropper-handle>
            <cropper-handle action="w-resize"></cropper-handle>
            <cropper-handle action="ne-resize"></cropper-handle>
            <cropper-handle action="nw-resize"></cropper-handle>
            <cropper-handle action="se-resize"></cropper-handle>
            <cropper-handle action="sw-resize"></cropper-handle>
          </cropper-selection>
        </cropper-canvas>

        <div
          class="cropperSelection"
          style="flex:0;border-radius: 8px; border: 1px solid #ccc;overflow: hidden"
        >
          <!-- 修改: 添加 selection 属性并绑定到 file.url -->
          <cropper-viewer
            style="width: 100%;height: 100%"
            selection="#cropperSelection"
            initial-aspect-ratio="1.5"
            initial-coverage="0.5"
          ></cropper-viewer>
        </div>
      </div>
    </r-dialog>
  </div>
</template>
<script>
import Cropper from 'cropperjs'
// import {
//   CropperCanvas,
//   CropperImage,
//   CropperShade,
//   CropperHandle,
//   CropperSelection,
//   CropperViewer
// } from 'vue-cropper'
export default {
  name: 'index',
  data() {
    return {
      fileList: [],
      cropper: null,
      imageUrl: '',
      visible: false,
      file: {
        url: ''
      }
    }
  },
  props: {
    list: {
      type: Array,
      default: () => []
    },
    url: {
      type: String,
      default: ''
    }
  },
  watch: {
    url: {
      handler(val) {
        this.fileList = []
        if (val) {
          this.fileList.push({
            url: val
          })
        }
      },
      immediate: true,
      deep: true
    }
  },
  components: {
    // CropperCanvas,
    // CropperImage,
    // CropperShade,
    // CropperHandle,
    // CropperSelection,
    // CropperViewer
  },
  filters: {},
  methods: {
    handleRemove() {
      this.fileList = []
    },
    change(file) {
      this.file = file
      this.fileList = []
      this.visible = true
      setTimeout(() => {
        this.cropper = new Cropper('#image', {})
      }, 300)
    },
    confirm() {
      this.$refs.selection.$toCanvas().then(canvas => {
        // 根据canvas 生成一个图片  并转换成file
        const image = canvas.toDataURL()
        this.dataURLtoFile(image, this.file.name).then(res => {
          // 文件生成 bolburl
          const blobUrl = URL.createObjectURL(res)
          res.url = blobUrl
          this.fileList = []
          this.fileList.push(res)
          this.$emit('getFiles', [res])
          this.visible = false
        })
        //   根据canvas 生成一个图片
      })
    },
    // 修改: 优化 base64 转文件的逻辑，增加压缩功能
    dataURLtoFile(dataurl, filename) {
      let 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)
      }

      // 创建临时 canvas 元素用于压缩图片
      const canvas = document.createElement('canvas')
      const ctx = canvas.getContext('2d')
      const img = new Image()
      // 返回一个 Promise，确保异步操作完成后再返回文件
      return new Promise(resolve => {
        img.src = dataurl

        img.onload = () => {
          // 限制最大宽度或高度为 800px（可根据需求调整）
          const maxWidthOrHeight = 800
          let width = img.width
          let height = img.height

          if (width > height) {
            if (width > maxWidthOrHeight) {
              height *= maxWidthOrHeight / width
              width = maxWidthOrHeight
            }
          } else {
            if (height > maxWidthOrHeight) {
              width *= maxWidthOrHeight / height
              height = maxWidthOrHeight
            }
          }

          canvas.width = width
          canvas.height = height
          ctx.drawImage(img, 0, 0, width, height)

          // 将 canvas 转换为 base64，质量设置为 0.8（可根据需求调整）
          const compressedDataUrl = canvas.toDataURL(mime, 0.8)

          // 将压缩后的 base64 转换为文件
          const compressedArr = compressedDataUrl.split(',')
          const compressedBstr = atob(compressedArr[1])
          const compressedN = compressedBstr.length
          const compressedU8arr = new Uint8Array(compressedN)

          for (let i = 0; i < compressedN; i++) {
            compressedU8arr[i] = compressedBstr.charCodeAt(i)
          }
          resolve(new File([compressedU8arr], filename, { type: mime }))
        }
      })
    }
  },
  created() {},
  mounted() {},
  computed: {}
}
</script>
<style lang="scss">
cropper-canvas {
  height: 50vh;
}

.cropperSelection {
  //width: 20vw;
  max-height: 30vw !important;
}
</style>
