<template>
  <div class="upload-box">
    <div v-for="(item, index) in fileList" class="items">
      <img v-if="item.filePath" :src="item.filePath" class="upload-image" />
      <div class="upload-handle" @click.stop>
        <div class="handle-icon" @click="handleEdit(index)" v-if="!self_disabled">
          <n-icon size="20">
            <EditOutlined/>
          </n-icon>
        </div>
        <div class="handle-icon" @click="onPreview(index)">
          <n-icon size="20">
            <ZoomInOutlined/>
          </n-icon>
        </div>
        <div class="handle-icon" @click="handleRemove(index)" v-if="!self_disabled">
          <n-icon size="20">
            <DeleteOutlined/>
          </n-icon>
        </div>
      </div>
    </div>
    <n-upload
      action="#"
      :id="uuid"
      class="upload-demo my-upload-images"
      :multiple="multiple"
      ref="uploadRef"
      :style="{ width: width, height: height }"
      :disabled="loading ? true : self_disabled || fileList.length >= props.limit"
      @before-upload="beforeUpload"
      @change="handleUploadChange"
      :max="limit"
      v-model:file-list="fileList"
      :show-file-list="false"
      v-if="!self_disabled"
      :accept="props.fileType"
    >
      <n-icon size="40" color="#666666" v-if="!loading" >
        <PlusOutlined/>
      </n-icon>
      <n-progress type="circle" v-else :percentage="progress" />
    </n-upload>
  </div>
</template>

<script setup lang="ts">
  import { computed, ref } from 'vue';
  import { generateUUID } from '@/utils/auth';
  import type { UploadFileInfo } from 'naive-ui'
  import {
    PlusOutlined,
    EditOutlined,
    DeleteOutlined,
    ZoomInOutlined,
  } from '@vicons/antd';
import { useNotification } from 'naive-ui'

  const uploadRef = ref();
  import { upload } from '@/api/common';

  // 接受父组件参数
  const props = defineProps({
    zIndex: {
      default: -1,
    },
    multiple: {
      type: Boolean,
      default: false,
    },
    btnTip: {
      type: String,
      default: '',
    },
    limit: {
      type: Number,
      default: undefined,
    },
    width: {
      type: String,
      default: '120px',
    },
    height: {
      type: String,
      default: '120px',
    },
    borderRadius: {
      type: String,
      default: '8px',
    },
    fileLists: {
      type: Array,
      required: true,
      default: [],
    },
    disabled: {
      default: false,
    },
    fileSize: {
      default: 200,
    },
    orderNo: {
      default: '',
    },
    fileType: {
      default: '',
    },
    name: {
      default: '',
    },
  });
  // 生成组件唯一id
  const uuid = ref('id-' + generateUUID());

  const notification = useNotification()

  // 判断是否禁用上传和删除
  const self_disabled = computed(() => {
    return props.disabled;
  });

  const fileList = computed({
  get: () => {
    console.log(props.fileLists)
    return props.fileLists;
  },
  set: (val) => {
    emit('update:modelValue',  fileList.value);
  },
});
  let editIndex = '';

  const emit = defineEmits(['upload']);
  const progress = ref(0);
  const loading = ref(false);
  const handleHttpUpload = async (options) => {
    loading.value = true;
    try {
      const formData = new FormData();
      formData.append('file', options.file.file);
      formData.append('name', props.name);
      const res = await upload(formData);
      if (props.multiple) {
        let list = JSON.parse(JSON.stringify(fileList.value));
        if (editIndex !== '') {
          list.splice(editIndex, 1, {
            url: res.fileUrl,
            name: res.originalName,
            filePath: res.fileUrl,
            fileName: res.originalName,
          });
          editIndex = '';
        } else {
          list.push({
            url: res.fileUrl,
            name: res.originalName,
            filePath: res.fileUrl,
            fileName: res.originalName,
          });
        }
        emit('upload', list, props.zIndex);
      } else {
        emit('upload', res, props.zIndex);
      }
    } catch (error) {
      notification.error({
        message: '温馨提示',
        duration:2000,
        description: '上传文件失败！',
      });
      if (props.multiple) {
        emit('upload', fileList.value, props.zIndex);
      } else {
        uploadRef.value!.clear();
        emit('upload', '', props.zIndex);
      }
      options.onError(error as any);
    } finally {
      progress.value = 0;
      loading.value = false;
    }
  };
const handleUploadChange= (data: { fileList: UploadFileInfo[] })=> {
  handleHttpUpload(data)
};
  const onPreview = (index: any) => {
    window.open(fileList.value[index].filePath);
  };

  const handleEdit = (index: any) => {
    editIndex = index;
    const dom = document.querySelector(`#${uuid.value} .n-upload-file-input`);
    dom && dom.dispatchEvent(new MouseEvent('click'));
  };
  const handleRemove = (index: any) => {
    editIndex = index;
    if (props.multiple) {
      emit(
        'upload',
        fileList.value.filter((f, i) => !(editIndex == i)),
        props.zIndex,
      );
    } else {
      uploadRef.value!.clear();
      emit('upload', '', props.zIndex);
    }
  };

  const onExceed = () => {
    if (props.limit) {
      notification.warning({
        message: '温馨提示',
        duration:2000,
        description: `最多支持上传${props.limit}张`,
      });
    }
  };

  /**
   * @description 文件上传之前判断
   * @param rawFile 选择的文件
   * */
  const beforeUpload = (rawFile) => {
    console.log(rawFile)
    const imgSize = rawFile.file.file.size / 1024 / 1024 < props.fileSize;
    if (!imgSize) {
      notification.warning({
        message: '温馨提示',
        duration:2000,
        description: `上传文件大小不能超过 ${props.fileSize}M！`,
      });
      return false;
    }
    if (props.fileType) {
      let fileType = props.fileType.replace(/\s/g, '');
      fileType.split('.').join('|');
      let fileIndex = rawFile.file.file.name.lastIndexOf('.');
      let substrName = rawFile.file.file.name.substr(fileIndex);
      if (fileType.indexOf(substrName) == -1) {
        notification.warning({
          message: '温馨提示',
          duration:2000,
          description: '上传文件不符合所需的格式！',
        });
        return false;
      }
    }
    return true;
  };
</script>
<style scoped lang="less">
  .upload-box {
    position: relative;
    display: flex;
    flex-wrap: wrap;
    > div {
      margin-right: 10px;
      margin-bottom: 10px;
      position: relative;

      &.items {
        width: v-bind(width);
        height: v-bind(height);
        border: 1px dashed #d9d9d9;
        border-radius: 4px;
        padding: 5px;
      }

      &:hover {
        .upload-handle {
          opacity: 1;
        }
      }
    }
    :deep(.n-upload) {
      position: relative;
      display: flex;
      align-items: center;
      justify-content: center;
      width: v-bind(width);
      height: v-bind(height);
      overflow: hidden;
      border-radius: 4px;
      border:1px dashed #d9d9d9;
      cursor: pointer;
      .n-upload-trigger {
        width:100%;
        height: 100%;
        display: flex;
        align-items: center;
        justify-content: center;
      }
    }
    .upload-image {
      width: 100%;
      height: 100%;
      object-fit: contain;
    }

    .upload-handle {
      position: absolute;
      top: 0;
      right: 0;
      box-sizing: border-box;
      display: flex;
      align-items: center;
      justify-content: center;
      width: 100%;
      height: 100%;
      cursor: pointer;
      background: rgb(0 0 0 / 60%);
      opacity: 0;

      .handle-icon {
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        padding: 0 6%;
        color: aliceblue;
        span {
          font-size: 85%;
          line-height: 85%;
        }
      }
    }
  }
</style>
