import { ElMessage } from "element-plus";
import { computed, ref, watchEffect } from "vue";
import mime from "mime";

export type UploadProps<T> = {
  maxSize: number;
  formats: string[];
  upload?: (
    file: File,
    onPercentage: (percentage: number) => void
  ) => Promise<T>;
};

const defaultUpload = (
  file: File,
  onPercentage: (percentage: number) => void
) => {
  onPercentage(100);
};

export const useUpload = <T>(props: UploadProps<T>) => {
  const percentage = ref<number>();
  const size = computed(() => Math.floor(props.maxSize / 1024 / 1024) + "M");
  const format = computed(
    () =>
      `${props.formats.join("、")}${
        props.formats.length > 1 ? "等" : ""
      }格式的文件`
  );
  const accept = computed(() =>
    props.formats
      .map((format) => {
        const index = format.indexOf(".");
        const ext = ~index ? format.substring(index + 1) : format;
        return mime.getType(ext) as string;
      })
      .join(", ")
  );
  const fileRef = ref<File>();

  (window as any).fileRef = fileRef;
  const removeFile = () => {
    fileRef.value = undefined;
    return true;
  };
  const previewFile = () => {
    fileRef.value && window.open(URL.createObjectURL(fileRef.value));
  };

  const upload = async (file: File) => {
    const fileType = file.name
      .substring(file.name.lastIndexOf("."))
      .toUpperCase();

    if (!props.formats.some((type) => type.toUpperCase() === fileType)) {
      ElMessage.error(`请上传${format.value}`);
      return false;
    } else if (file.size > props.maxSize) {
      ElMessage.error(`请上传${size.value}以内的文件`);
      return false;
    } else {
      fileRef.value = file;
      await (props.upload || defaultUpload)(
        file,
        (val) => (percentage.value = val)
      );
      percentage.value = undefined;
      return true;
    }
  };

  return {
    file: fileRef,
    fileList: computed(() => (fileRef.value ? [fileRef.value] : [])),
    previewFile,
    removeFile,
    percentage,
    size,
    format,
    accept,
    upload,
  };
};
