import { useNamespace } from '@ibiz-template/vue-util';
import { defineComponent, ref } from 'vue';

export type UploadFile = {
  name: string;
  status: 'uploading' | 'finished' | 'fail';
  percentage: number;
  url?: string;
  id: string;
};

export const IBizUpload = defineComponent({
  name: 'IBizUpload',
  props: {
    uploadUrl: {
      type: String,
      required: true,
    },
    downloadUrl: {
      type: String,
    },
    accept: String,
    multiple: {
      type: Boolean,
      default: false,
    },
  },
  emits: {
    finish: (_resultFiles: UploadFile[]) => true,
  },
  setup(props, { emit }) {
    const ns = useNamespace('upload');
    const upload = ref();

    const selectFile = () => {
      upload.value.click();
    };

    const uploadFiles = async (files: FileList) => {
      const resultFiles: UploadFile[] = [];
      await Promise.allSettled(
        Array.from({ length: files.length }).map(async (_value, i) => {
          const file = files[i];
          // 上传前处理
          const resultFile: UploadFile = {
            status: 'uploading',
            name: file.name,
            percentage: 0,
            id: '',
          };
          resultFiles.push(resultFile);

          const data = new FormData();
          console.log(file);
          data.append('file', file);
          try {
            const res = await ibiz.net.request(props.uploadUrl, {
              method: 'post',
              baseURL: '',
              data,
              headers: { 'Content-Type': 'multipart/form-data' },
            });
            if (res.ok && res.data) {
              console.log(res.data);
              Object.assign(resultFile, {
                id: res.data.id,
                url: props.downloadUrl
                  ? props.downloadUrl.replace('%fileId%', res.data.id)
                  : undefined,
              });
            }
          } catch (error) {
            ibiz.log.error(error);
            ibiz.message.error(`${file.name}上传失败`);
          }
        }),
      );

      emit('finish', resultFiles);
    };

    const handleChange = (e: Event) => {
      const inputEl = e.target as HTMLInputElement;
      const files = inputEl.files;
      if (!files) {
        return;
      }
      uploadFiles(files);
      inputEl.value = ''; // 如果不置空，相同的文件不会触发change事件
    };

    return { ns, upload, selectFile, handleChange };
  },
  render() {
    return (
      <input
        accept={this.accept}
        multiple={this.multiple}
        onChange={this.handleChange}
        ref='upload'
        type='file'
        style='display: none'
      />
    );
  },
});
