<script lang="ts" setup>
import { ref, watch } from 'vue';
import { type UploadCustomRequestOptions, type UploadFileInfo } from 'naive-ui';
import dayjs from 'dayjs';
import { fetchUpload } from '@/service/api/common';
import type { zuploadProps } from '.';
const props = defineProps<zuploadProps>();
const emit = defineEmits<{
  (e: 'update:value', fileList: string): void;
}>();
const fileListData = ref<UploadFileInfo[]>([]);
const viewUrl = import.meta.env.VITE_OSS_BASE_URL;
function handleBeforeUpload(data: { file: UploadFileInfo; fileList: UploadFileInfo[] }): Promise<boolean> {
  if (props.aspectRatioW && props.aspectRatioH) {
    return new Promise((resolve, reject) => {
      const img = new Image();
      img.src = URL.createObjectURL(data.file.file as File);
      img.onload = () => {
        const { width, height } = img;
        const ratio = width / height;
        const targetRatio = Number(props.aspectRatioW) / Number(props.aspectRatioH);
        const ratioDescription = `${props.aspectRatioW}:${props.aspectRatioH}`;
        if (Math.abs(ratio - targetRatio) > 0.01) {
          const msg = `请上传${Number(props.aspectRatioW) > 1 ? '宽高' : ''}比为 ${ratioDescription} 的图片`;
          window.$message?.error(msg);
          reject(new Error(msg));
        }
        resolve(true);
      };
    });
  }
  if (props.FileSize && data.file.file) {
    if (data.file?.file.size > props.FileSize * 1024 * 1024) {
      window.$message?.error(`请上传小于${props.FileSize}M的图片`);
      return Promise.resolve(false);
    }
  }
  // 扩展 beforeUpload 验证
  if (typeof props.onBeforeUpload === 'function') {
    return Promise.resolve(props.onBeforeUpload(data as any)).then(res => res ?? true);
  }
  return Promise.resolve(true);
}
async function customRequest({ file, onFinish, onError, onProgress }: UploadCustomRequestOptions) {
  const config = {
    onUploadProgress: ({ percent }: any) => {
      onProgress({ percent: Math.ceil(percent) });
    }
  };
  const { error, response, data: res } = await fetchUpload(file.file as File, config);
  if (!error) {
    file.url = viewUrl + res;
    window.$message?.success(response.data.msg || '上传成功');
    onFinish();
  } else {
    window.$message?.error(error.message);
    onError();
  }
}
function handleFileList() {
  const fileJoin = fileListData.value.map(it => it.url).join(',');
  emit('update:value', fileJoin);
}

watch(
  () => props,
  () => {
    if (props.value) {
      console.log('props.value', props.value);

      fileListData.value = props.value
        .split(',')
        .map(it => ({ url: it, status: 'finished', id: dayjs().valueOf() + it, name: it }));
    }
  },
  { immediate: true, deep: true }
);
defineOptions({
  inheritAttrs: false
});
</script>

<template>
  <div>
    <NUpload
      v-bind="$attrs"
      v-model:file-list="fileListData"
      list-type="image-card"
      accept="image/*"
      :custom-request="customRequest"
      @before-upload="handleBeforeUpload"
      @update-file-list="handleFileList"
    ></NUpload>

    <div v-if="tipText" class="mt3 text-gray">{{ tipText }}</div>
  </div>
</template>

<style scoped></style>
