<template>
  <div>
    <div class="container clearfix">
      <!-- 图片显示框 -->
      <template v-if="currentImg.length">
        <div class="imgList" v-for="(item, index) in fileList" :key="item">
          <div class="imgContainer" @mouseenter="mouseEnter(index)" @mouseleave="mouseLeave(index)">
            <img :src="currentImg[index]" class="imgCover" />
            <span v-if="maskShow[index]" class="mask">
              <EyeOutlined v-if="false" @click="handlePreview(item, index)" />
              <DeleteOutlined @click="deleteImg(index)" />
            </span>
          </div>
        </div>
      </template>
      <!-- 图片显示框 /-->

      <!-- 上传图片框/内置了input -->
      <a-upload
        list-type="picture-card"
        :before-upload="beforeUpload"
        @change="handleChange"
        :multiple="count != 1"
        :customRequest="selfUpload"
        :showUploadList="false"
      >
        <!-- :disabled="count == 1 && fileUuid ? true : false" -->
        <div v-if="count === 1 ? 'true' : fileList.length < count">
          <template v-if="isLt5M && isJpgOrPngOrJpeg">
            <UploadOutlined :style="{ fontSize: '14px' }" />
            <div class="ant-upload-text">上传图片</div>
          </template>
          <template v-else>
            <LoadingOutlined />
            <div class="ant-upload-text">校验失败</div>
          </template>
        </div>
      </a-upload>
      <!-- 上传图片框/内置input /-->
    </div>

    <!-- 预览图片弹窗 -->
    <a-modal :visible="previewVisible" :footer="null" @cancel="handleCancel">
      <img alt="example" style="width: 100%" :src="'/api/ihorn/objs/pictureBack/' + previewImage" />
    </a-modal>
    <!-- 预览图片弹窗 /-->

    <!-- 错误消息提示 -->
    <div class="err-msg" v-if="!isJpgOrPngOrJpeg">
      <p>{{ fileName }} 文件上传失败</p>
      <p :style="{ color: 'red' }"> 请选择{{ fileType.join(',') }}的图片 </p>
    </div>
    <div class="err-msg" v-if="isJpgOrPngOrJpeg ? !isLt5M : ''">
      <p>{{ fileName }} 文件上传失败</p>
      <p :style="{ color: 'red' }"> 请选择{{ maxSize / 1024 / 1024 }}M内的图片 </p>
    </div>
    <!-- 错误消息提示 /-->
  </div>
</template>
<script lang="ts">
  import {
    UploadOutlined,
    LoadingOutlined,
    EyeOutlined,
    DeleteOutlined,
  } from '@ant-design/icons-vue';
  import { defineComponent, ref, computed } from 'vue';
  import { http } from '/nerv-lib/util/http';
  import { NsMessage } from '/nerv-lib/component/message';

  interface FileItem {
    uid: string;
    type: string;
    size: number;
    name?: string;
    status?: string;
    response?: string;
    percent?: number;
    url?: string;
    preview?: string;
    originFileObj?: any;
  }

  interface FileInfo {
    file: FileItem;
    fileList: FileItem[];
  }

  // 转base64
  function getBase64(file: File) {
    return new Promise((resolve, reject) => {
      console.log(file);

      const reader = new FileReader();
      reader.readAsDataURL(file);
      reader.onload = () => resolve(reader.result);
      reader.onerror = (error) => reject(error);
    });
  }

  export default defineComponent({
    name: 'NsUpload',
    components: {
      UploadOutlined,
      LoadingOutlined,
      DeleteOutlined,
      EyeOutlined,
    },
    props: {
      // 上传的地址
      url: {
        type: String,
        require: true,
      },
      // 上传的图片大小
      maxSize: {
        type: Number,
        default: 5242880,
      },
      // 上传的图片类型
      fileType: {
        type: Array,
        default: () => {
          return ['jpg', 'png', 'jpeg'];
        },
      },
      // 展示图片数量
      count: {
        type: Number,
        default: 1,
      },
      // 上传文件类型，0-证书，1-图片，2-身份证件
      uploadType: {
        type: Number,
        default: 1,
      },
      baseImageUrl: {
        type: [String, Object],
      },
    },
    emits: ['change'],
    setup(props, { emit }) {
      const previewVisible = ref<boolean>(false);
      const isLt5M = ref<boolean>(true);
      const isJpgOrPngOrJpeg = ref<boolean>(true);
      const previewImage = ref<string | undefined>('');
      const fileList = ref<FileItem[]>([]);
      const currentImg = ref<string[]>([]);
      const isIntImg = ref(false);
      if (props.baseImageUrl) {
        isIntImg.value = true;
        if (typeof props.baseImageUrl == 'object') {
          // currentImg.value.concat(props.baseImageUrl);
          props.baseImageUrl.map((item, index) => {
            fileList.value.push(item);

            currentImg.value.push(item);
            // previewImage.value = props.baseImageUrl[index];
          });

          // currentImg.value.unshift(...props.baseImageUrl);
        } else {
          fileList.value.push({});

          currentImg.value.unshift(props.baseImageUrl);
          previewImage.value = props.baseImageUrl;
        }
      }
      const fileName = ref<string | undefined>('');

      const maskShow = ref<boolean[]>([]);
      const fileUuid = ref<string>('');

      const acceptType = computed(() =>
        props.fileType.map((item: String) => {
          return 'image/' + item;
        })
      );

      const beforeUpload = (file: FileItem) => {
        // 上传出错后，下次上传图片前，重置为true，让图片可以上传
        isLt5M.value = true;
        isJpgOrPngOrJpeg.value = true;
        // 限制图片格式,服务器不支持gif图片
        if (file.type === 'image/gif') {
          NsMessage.warn('不支持gif图片');
          return false;
        }
        isJpgOrPngOrJpeg.value = acceptType.value.includes(file.type);
        // 如果大于指定的大小，显示错误信息
        if (file.size > props.maxSize) {
          isLt5M.value = false;
        }
        fileName.value = file.name;
        return isLt5M.value && isJpgOrPngOrJpeg.value;
      };

      const handleChange = ({ fileList: newFileList }: FileInfo) => {
        // 单图上传
        if (props.count === 1) {
          // 删除图片时，newFileList.length = 0
          // 图片大小不符合规范时，!isLt5M.value为true
          if (!isLt5M.value || !isJpgOrPngOrJpeg.value || newFileList.length - 1 < 0) {
            // 让图片不显示，也不上传
            fileList.value = [];
          } else {
            // 添加\更换图片
            // newFileList[newFileList.length - 1]的目的是为了只显示最新一张图片

            fileList.value = [newFileList[newFileList.length - 1]];
          }
        } else {
          // 多图上传
          // if (typeof props.baseImageUrl == 'object') {
          //   props.baseImageUrl.map((item, index) => {
          //     console.log(item);
          //     fileList.value.push(item);

          //     // currentImg.value.unshift(item);
          //     // previewImage.value = props.baseImageUrl[index];
          //   });
          // }

          if (!isLt5M.value || !isJpgOrPngOrJpeg.value) {
            // fileList.value = newFileList.slice(0, newFileList.length - 1);
            // fileList.value = fileList.slice(0, fileList.length - 1);
            // console.log(123444, fileList.value, newFileList);
          } else {
            fileList.value.push(newFileList);
            emit('change', fill(fileList.value));

            // fileList.value = newFileList;
          }
        }
      };
      const fill = (data) => {
        let arr = [];
        if (props.count == 1) return;
        data.map((item) => {
          if (item.indexOf('ParkPic') !== -1) {
            arr.push(item.split('ParkPic/')[1]);
          }
        });
        return arr;
      };
      const selfUpload = async ({ file }) => {
        if (props.count !== 1) {
          emit('change', fill(fileList.value));
        }

        currentImg.value.push(await getBase64(file));
        const params = {
          uploadType: props.uploadType,
        };
        const formData = new FormData();
        formData.append('file', file);
        formData.append('uploadType', props.uploadType);
        //formData.append('uploadType', 1);
        const config = {
          headers: {
            'Content-Type': 'multipart/form-data',
          },

          // params: params,
        };
        console.log(formData);
        if (props.count == 1) {
          fileUuid.value = 'ceshi';
        }
        http
          .post(props.url, formData, config)
          .then((res) => {
            if (props.count > 1) {
              // let imgBox = ref([]);
              console.log(fileList.value);

              fileList.value.push('/api/ihorn/objs/pictureBack/' + res.data.fileUuid);
              fileList.value.forEach((item, index) => {
                if (typeof item == 'object') {
                  fileList.value.splice(index, 1);
                }
              });
              emit('change', fill(fileList.value));
            } else {
              fileUuid.value = res.data.picUuid || res.data.fileUuid;
              emit('change', fileUuid.value);
            }
          })
          .catch(() => {
            fileList.value.forEach((item, index) => {
              if (typeof item == 'object') {
                fileList.value.splice(fileList.value.length - 1, 1);
              }
            });
            NsMessage.error('上传失败，请重试');
          });
      };

      const handlePreview = async (item, index: number) => {
        // emit('change', fill(fileList.value));
        console.log(item, index);

        if (props.count > 1) {
          previewImage.value = fileList.value[index];
        } else {
          previewImage.value = fileUuid.value;
        }
        // if (!isIntImg.value) {
        //   previewImage.value = (await getBase64(fileList.value[index])) as string;
        //   // previewImage.value = (await getBase64(fileList.value[index].originFileObj)) as string;
        // }
        previewVisible.value = true;
      };

      const deleteImg = (index: number) => {
        currentImg.value.splice(index, 1);
        fileList.value.splice(index, 1);
        fileUuid.value = '';
        isIntImg.value = false;
        if (props.count == 1) {
          emit('change', fileUuid.value);
        } else {
          emit('change', fill(fileList.value));
        }
      };

      const handleCancel = () => {
        previewVisible.value = false;
      };

      const mouseEnter = (index: number) => {
        maskShow.value[index] = true;
      };

      const mouseLeave = (index: number) => {
        maskShow.value[index] = false;
      };

      return {
        previewVisible,
        previewImage,
        fileList,
        isLt5M,
        isJpgOrPngOrJpeg,
        fileName,
        currentImg,
        maskShow,
        fileUuid,
        selfUpload,
        handleCancel,
        handlePreview,
        handleChange,
        beforeUpload,
        mouseEnter,
        mouseLeave,
        deleteImg,
      };
    },
  });
</script>
<style>
  .ant-upload-picture-card-wrapper .ant-upload.ant-upload-select-picture-card {
    margin: 0;
    width: 80px;
    height: 80px;
    border: 1px solid #d9d9d9;
  }

  .ant-upload-picture-card-wrapper .ant-upload.ant-upload-select-picture-card:hover {
    border-color: #d9d9d9;
  }

  .ant-upload-select-picture-card i {
    font-size: 32px;
    color: #999;
  }

  .ant-upload-select-picture-card .ant-upload-text {
    color: #666;
    font-size: 12px;
  }

  .ant-upload-picture-card-wrapper .ant-upload-list-picture-card-container {
    width: 88px;
    height: 80px;
  }

  .ant-upload-picture-card-wrapper .ant-upload-list-picture-card .ant-upload-list-item {
    margin: 0;
    padding: 0;
    width: 80px;
    height: 80px;
  }

  .title,
  .err-msg {
    text-align: left;
  }

  .err-msg p {
    margin: 0;
  }

  .container {
    display: flex;
  }

  .imgList {
    display: flex;
  }

  .imgContainer {
    margin-right: 16px;
    border: 1px solid #d9d9d9;
    position: relative;
  }

  .imgCover {
    width: 80px;
    height: 80px;
    object-fit: contain;
  }

  .imgContainer .mask {
    position: absolute;
    top: 0;
    left: 0;
    width: 80px;
    height: 80px;
    background: rgba(0, 0, 0, 0.5);
    text-align: center;
    line-height: 80px;
  }

  .mask .anticon-eye {
    color: white;
    margin-right: 18px;
  }

  .mask .anticon-eye:hover {
    color: #00acff;
    margin-right: 18px;
  }

  .mask .anticon-delete {
    color: white;
  }

  .mask .anticon-delete:hover {
    color: #00acff;
  }
</style>
