<!-- @format -->

<template>
  <div>
    <div class="container clearfix">
      <!-- 图片显示框 -->
      <template v-if="fileList.length">
        <div class="imgList" v-for="(item, index) in fileList" :key="item">
          <div class="imgContainer" @mouseenter="mouseEnter(index)" @mouseleave="mouseLeave(index)">
            <img :src="baseImageUrl + item" 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
        v-if="fileList.length < count"
        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="fileList.length < count">
          <template v-if="isLt5M && isJpgOrPngOrJpeg && !loading">
            <UploadOutlined :style="{ fontSize: '14px' }" />
            <div class="ant-upload-text">上传图片</div>
          </template>
          <template v-else-if="loading">
            <LoadingOutlined />
            <div class="ant-upload-text">上传中...</div>
          </template>
          <template v-else>
            <LoadingOutlined />
            <div class="ant-upload-text">校验失败</div>
          </template>
        </div>
      </a-upload>
      <!-- 上传图片框/内置input /-->
    </div>

    <!-- 预览图片弹窗 -->
    <ns-modal :visible="previewVisible" :footer="null" @cancel="handleCancel">
      <img alt="example" style="width: 100%" :src="baseImageUrl + previewImage" />
    </ns-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, reactive, watch } from 'vue';
  import { http } from '/nerv-lib/util/http';
  import { NsMessage } from '/nerv-lib/component/message';
  import { get } from 'lodash-es';
  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: 'NsUploadV2.1',
    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,
      },
      // 图片归类所需
      params: {
        type: [Object],
      },
      // 请求头配置
      config: {
        type: Object,
      },
      // 上传文件类型,0-证书,1-图片,2-身份证件
      uploadType: {
        type: Number,
        default: 1,
      },
      baseImageUrl: {
        type: String,
        default: '',
      },
      value: {
        type: String || Array,
      },
      valueField: {
        type: String,
        default: 'data.picUuid',
      },
    },
    emits: ['change'],
    setup(props, { emit, attrs }) {
      console.log(props.config);
      const previewVisible = ref<boolean>(false);
      const isLt5M = ref<boolean>(true);
      const isJpgOrPngOrJpeg = ref<boolean>(true);
      const previewImage = ref<string | undefined>('');
      const fileList = ref<string[]>([]);
      const currentImg = ref<string[]>([]);
      const isIntImg = ref(false);
      const baseImageUrl = props.baseImageUrl || '';

      const fileName = ref<string | undefined>('');

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

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

      watch(
        () => props.value,
        (e) => {
          if (e && !fileList.value.length) {
            isIntImg.value = true;
            if (typeof e == 'array') {
              e.map((item: string) => {
                item = baseImageUrl + item;
                fileList.value.push(item);
                currentImg.value.push(item);
              });
            } else {
              fileList.value.push(e);
              currentImg.value.unshift(e);
              previewImage.value = e;
            }
            let fileValue: Array<any> | string = '';
            if (props.count === 1) {
              fileValue = fileList.value[0];
            } else {
              fileValue = fileList.value;
            }
            emit('change', fileValue);
          }
        },
        {
          deep: true,
          immediate: true,
        },
      );

      const beforeUpload = (file: FileItem) => {
        // 上传出错后,下次上传图片前,重置为true,让图片可以上传
        isLt5M.value = true;
        isJpgOrPngOrJpeg.value = true;

        // 限制图片格式,服务器不支持gif图片
        if (file.type === 'image/gif') {
          NsMessage.warn('不支持gif图片');
          return false;
        }
        // console.log(file);
        if (file.name?.split('.')[file.name?.split('.').length - 1] === 'jfif') {
          NsMessage.warn('不支持jfif图片');
          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 = (info: FileInfo) => {
        // 单图上传
        if (info.file.status === 'uploading') {
          console.log(loading.value);

          loading.value = true;
        }
      };
      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));
        // }
        const params = {
          uploadType: props.uploadType,
        };
        const formData = new FormData();
        formData.append('file', file);
        formData.append('uploadType', props.uploadType);
        Object.keys(props.params).map((item) => {
          formData.append(item, props.params[item]);
        });
        let config;
        if (!props.config) {
          config = {
            headers: {
              'Content-Type': 'multipart/form-data',
            },
            // params: params,
          };
        } else {
          config = props.config;
        }
        http
          .post(props.url, formData, config)
          .then((res) => {
            if (props.count > 1) {
              fileList.value.push(get(res, props.valueField));
              emit('change', fill(fileList.value), res);
            } else {
              fileUuid.value = get(res, props.valueField);
              fileList.value = [fileUuid.value];
              loading.value = false;
              emit('change', fileUuid.value, res);
            }
          })
          .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,
        loading,
      };
    },
  });
</script>
<style lang="less" scoped>
  :deep(.ant-upload-picture-card-wrapper) {
    width: unset !important;
  }
  :deep(.ant-upload-picture-card-wrapper .ant-upload.ant-upload-select-picture-card) {
    margin: 0;
    width: 64px !important;
    height: 64px !important;
    border: 1px solid #d9d9d9;
  }
  :deep(.ant-upload-picture-card-wrapper .ant-upload.ant-upload-select-picture-card:hover) {
    border-color: #d9d9d9;
  }
  :deep(.ant-upload-select-picture-card i) {
    font-size: 32px;
    color: #999;
  }
  :deep(.ant-upload-select-picture-card .ant-upload-text) {
    color: #666;
    font-size: 12px;
  }
  :deep(.ant-upload-picture-card-wrapper .ant-upload-list-picture-card-container) {
    width: 88px;
    height: 64px !important;
  }
  :deep(.ant-upload-picture-card-wrapper .ant-upload-list-picture-card .ant-upload-list-item) {
    margin: 0;
    padding: 0;
    width: 64px !important;
    height: 64px !important;
  }
  .title,
  .err-msg {
    text-align: left;
  }
  .err-msg p {
    margin: 0;
  }
  .container {
    display: flex;
    justify-content: flex-start;
    flex-wrap: wrap;
  }
  .imgList {
    display: flex;
  }
  .imgContainer {
    margin-right: 16px;
    border: 1px solid #d9d9d9;
    position: relative;
    margin-bottom: 8px;
  }
  .imgCover {
    width: 64px;
    height: 64px;
    object-fit: contain;
  }
  .imgContainer .mask {
    position: absolute;
    top: 0;
    left: 0;
    width: 64px !important;
    height: 64px !important;
    background: rgba(0, 0, 0, 0.5);
    text-align: center;
    line-height: 64px !important;
  }
  .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>