<template>
  <a-flex justify="space-between" align="center">
    <a-alert message="单个文件不超过5MB，最多只能上传10个文件" type="info" show-icon />
    <a-upload :multiple="true" :before-upload="beforeUpload" :show-upload-list="false">
      <a-button type="primary"> 选择文件 </a-button>
    </a-upload>
  </a-flex>

  <DynamicTable :search="false" :data-source="fileList" :columns="columns" />

  <a-flex justify="flex-end" gap="10">
    <Button @click="onCancel">关闭</Button>
    <Button :type="'primary'" @click="onOk" :disabled="disabledUpload">上传</Button></a-flex
  >
</template>

<script setup lang="tsx">
  import { ref, computed } from 'vue';
  import { message, type UploadProps } from 'ant-design-vue';
  import { UploadResultStatus, fileListColumns, type FileItem } from './columns';
  import { useTable, type TableColumn } from '@/components/core/dynamic-table';
  import Button from '@/components/basic/button';
  import Api from '@/api/';

  defineOptions({
    name: 'AttachmentUpload',
  });
  const emit = defineEmits(['close']);
  const { afterUploadCallback, bussinessModule, bussinessRecordId } = defineProps({
    afterUploadCallback: {
      type: Function,
      default: () => ({}),
    },
    bussinessModule: {
      type: String,
      default: '',
    },
    bussinessRecordId: {
      type: Number,
    },
  });
  const [DynamicTable] = useTable();

  const fileList = ref<FileItem[]>([]);

  const disabledUpload = computed(() => {
    return !fileList.value.some((n) => n.status !== UploadResultStatus.SUCCESS);
  });

  const fileToBase64 = (file: File): Promise<string> => {
    const { promise, resolve, reject } = Promise.withResolvers<string>();

    const reader = new FileReader();

    reader.onload = () => {
      resolve(reader.result as string);
    };
    reader.onerror = (error) => {
      reject(error);
    };

    reader.readAsDataURL(file);
    return promise;
  };

  const onCancel = () => {
    const hasSuccess = fileList.value.some((n) => n.status === UploadResultStatus.SUCCESS);
    emit('close', hasSuccess);
    fileList.value = [];
  };

  const onOk = async () => {
    const uploadFileList = fileList.value.filter((n) => n.status !== UploadResultStatus.SUCCESS);
    const res = await Promise.all(
      uploadFileList.map(async (item) => {
        try {
          const itemRes = await Api.toolsUpload.uploadUpload(
            { file: item.file, bussinessModule, bussinessRecordId },
            undefined,
            {
              onUploadProgress(progressEvent) {
                const complete = ((progressEvent.loaded / progressEvent.total!) * 100) | 0;
                item.percent = complete;
                item.status = UploadResultStatus.UPLOADING;
              },
            },
          );
          item.status = UploadResultStatus.SUCCESS;
          return itemRes;
        } catch (error) {
          console.log(error);
          item.status = UploadResultStatus.ERROR;
        }
      }),
    );
    message.success({ content: '上传完成', key: '上传完成' });
    afterUploadCallback && afterUploadCallback(res.filter((item) => !!item));
  };

  const beforeUpload: UploadProps['beforeUpload'] = async (file) => {
    if (file.size / 1024 / 1024 > 5) {
      message.error('单个文件不超过5MB');
    } else {
      const item: FileItem = {
        file,
        uid: file.uid,
        name: file.name,
        size: file.size,
        status: '',
        percent: 0,
        thumbUrl: await fileToBase64(file),
      };
      fileList.value.push(item);
    }

    return false;
  };

  const handleRemove = (record: FileItem) => {
    fileList.value = fileList.value.filter((n) => n.uid !== record.uid);
  };

  const columns: TableColumn<FileItem>[] = [
    ...fileListColumns,
    {
      width: 120,
      title: '操作',
      dataIndex: 'ACTION',
      fixed: false,
      actions: ({ record }) => [
        {
          label: '删除',
          color: 'red',
          onClick: () => handleRemove(record),
        },
      ],
    },
  ];
</script>

<style scoped></style>
