<script setup lang="ts">
import { UploadFile } from 'element-plus/es/components/upload/src/upload';
import { IconLoad } from '@computing/opendesign-icons';
import { ref } from 'vue';

const props = defineProps({
  target: {
    type: String,
    required: true,
    default: '',
  },
  uploadConfig: {
    type: Object,
    required: true,
    default: () => {
      return {
        accept: '.jpg',
        maxSize: 0,
      };
    },
  },
});

const emits = defineEmits(['fileError', 'fileSuccess']);

const state = ref(false);
defineExpose({
  show: () => {
    state.value = true;
  },
  hide: () => {
    state.value = false;
  },
});

// 图片转为base64的格式
function translateImage(uploadFile: UploadFile) {
  const fileType = uploadFile.name.split('.').reverse()[0];
  const isSupprted = props.uploadConfig.accept.indexOf(fileType) > -1;
  const isNotOutOfLimit = (uploadFile.raw as any).size < props.uploadConfig.maxSize;

  // 文件格式错误
  if (!isSupprted) {
    emits('fileError', { target: props.target, errorMsg: '文件格式错误。' });
    state.value = false;
    return;
  }

  // 文件大小超出限制
  if (!isNotOutOfLimit) {
    emits('fileError', { target: props.target, errorMsg: '文件超出大小限制。' });
    state.value = false;
    return;
  }

  // 正常验证通过
  translateImgToBase64(uploadFile.raw as any).then(data => {
    emits('fileSuccess', { target: props.target, base64: data });
  });
}

// 图片转为base64的方法
function translateImgToBase64(file: File): Promise<any> {
  return new Promise((resolve, reject) => {
    const fileReader = new FileReader();
    fileReader.readAsDataURL(file);
    fileReader.onload = function (e) {
      const img = new Image();
      img.src = e.target?.result as string;
      img.onload = function (ev: Event) {
        const cavas = document.createElement('canvas');
        const cavContxt = cavas.getContext('2d');
        let width;
        if (ev.target) {
          width = ev.target['naturalWidth'];
        } else {
          width = ev['path'] ? ev['path'][0].naturalWidth : 178;
        }
        let height;
        if (ev.target) {
          height = ev.target['naturalHeight'];
        } else {
          height = ev['path'] ? ev['path'][0].naturalHeight : 32;
        }
        cavas.width = width;
        cavas.height = height;
        cavContxt?.drawImage(img, 0, 0);
        const data = cavas.toDataURL(file.type);
        resolve(data);
      };
      img.onerror = function (error) {
        reject(error);
      };
    };
    fileReader.onerror = function (error) {
      reject(error);
    };
  });
}
</script>

<template>
  <el-upload :accept="props.uploadConfig.accept" :auto-upload="false" :on-change="translateImage">
    <div v-if="state" id="imgMask" class="mask">
      <el-icon :size="16">
        <IconLoad />
      </el-icon>
      <p class="text">图片替换</p>
    </div>
  </el-upload>
</template>

<style scoped lang="scss">
.mask {
  display: flex;
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.4);
  border-radius: 2px;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  color: #fff;
  p {
    margin-top: 5px;
  }
}
:deep(.el-upload-list) {
  display: none;
}
</style>
