<!-- 图片上传组件 -->
<template>
  <el-upload v-model:file-list="fileList" list-type="picture-card" :before-upload="handleBeforeUpload"
    :http-request="handleUpload" :on-success="handleSuccess" :on-progress="handleProgress" :on-error="handleError"
    :on-exceed="handleExceed" :accept="props.accept" :limit="props.limit" multiple :auto-upload="true">
    <el-icon>
      <Plus />
    </el-icon>
    <template #file="{ file }">
      <div style="width: 100%">
        <img class="el-upload-list__item-thumbnail" :src="file.url" />
        <span class="el-upload-list__item-actions">
          <!-- 预览 -->
          <span @click="handlePreviewImage(file.url!)">
            <el-icon>
              <ZoomIn />
            </el-icon>
          </span>
          <!-- 删除 -->
          <span @click="handleRemove(file.url!)">
            <el-icon>
              <Delete />
            </el-icon>
          </span>
        </span>
      </div>
    </template>
  </el-upload>

  <el-image-viewer v-if="previewVisible" :zoom-rate="1.2" :initial-index="previewImageIndex" :url-list="modelValue"
    @close="handlePreviewClose" />
</template>

<script setup lang="ts">
import { ref, watch, onMounted, PropType, computed } from "vue";
import { ElMessage } from "element-plus";
import { UploadRawFile, UploadRequestOptions, UploadUserFile } from "element-plus";
import FileAPI, { FileInfo } from "@/api/account/common";

// 定义Props
const props = defineProps({
  data: {
    type: Object,
    default: () => ({}),
  },
  name: {
    type: String,
    default: "file",
  },
  limit: {
    type: Number,
    default: 10,
  },
  maxFileSize: {
    type: Number,
    default: 10, // 单位：M
  },
  accept: {
    type: String,
    default: "image/*",
  },
});

// 定义Emits
const emit = defineEmits(['upDataEvent', 'uploadAllSuccess']); // 新增：所有图片上传完成事件

// 响应式数据
const previewVisible = ref(false);
const previewImageIndex = ref(0);
const progress = ref(0);
// 修复：defineModel 类型定义
const modelValue = defineModel<string[]>("modelValue", {
  type: Array as PropType<string[]>,
  required: true,
  default: () => [],
});

const fileList = ref<UploadUserFile[]>([]);
// 新增：批量上传计数
const pendingUploadCount = ref(0); // 待上传文件数
const completedUploadCount = ref(0); // 已完成上传数

/**
 * 删除图片
 */
function handleRemove(imageUrl: string) {
  const index = modelValue.value.indexOf(imageUrl);
  if (index !== -1) {
    modelValue.value.splice(index, 1);
    fileList.value.splice(index, 1);
  }
}

/**
 * 上传进度
 */
function handleProgress(event: any) {
  console.log("文件上传进度", Math.round(event.percent));
}

/**
 * 上传前校验 & 初始化待上传文件
 */
function handleBeforeUpload(file: UploadRawFile) {
  // 1. 文件类型校验
  const acceptTypes = props.accept.split(",").map((type) => type.trim());
  const isValidType = acceptTypes.some((type) => {
    if (type === "image/*") {
      return file.type.startsWith("image/");
    } else if (type.startsWith(".")) {
      return file.name.toLowerCase().endsWith(type);
    } else {
      return file.type === type;
    }
  });

  if (!isValidType) {
    ElMessage.warning(`上传文件的格式不正确，仅支持：${props.accept}`);
    return false;
  }

  // 2. 文件大小校验
  if (file.size > props.maxFileSize * 1024 * 1024) {
    ElMessage.warning(`上传图片不能大于${props.maxFileSize}M`);
    return false;
  }

  // 3. 新增：初始化待上传文件到fileList，确保uid匹配
  const uploadFile: UploadUserFile = {
    uid: file.uid, // 关键：复用文件原生uid
    name: file.name,
    status: "ready",
    raw: file,
  };
  fileList.value.push(uploadFile);

  // 4. 新增：增加待上传计数
  pendingUploadCount.value++;
  emit('upDataEvent', true); // 开始上传，触发loading

  return true;
}

/**
 * 自定义上传逻辑
 */
function handleUpload(options: UploadRequestOptions) {
  return new Promise((resolve, reject) => {
    const file = options.file;
    const formData = new FormData();
    formData.append(props.name, file);

    // 附加参数
    Object.keys(props.data).forEach((key) => {
      formData.append(key, props.data[key]);
    });

    FileAPI.upload(formData)
      .then((data) => {
        resolve(data);
      })
      .catch((error) => {
        reject(error);
      });
  });
}

/**
 * 超出数量限制
 */
function handleExceed(files: File[], uploadFiles: UploadUserFile[]) {
  ElMessage.warning(`最多只能上传${props.limit}张图片`);
}

/**
 * 单文件上传成功回调
 */
const handleSuccess = (fileInfo: FileInfo, uploadFile: UploadUserFile) => {
  // 1. 修复：通过uid精准匹配文件
  const index = fileList.value.findIndex((file) => file.uid === uploadFile.uid);
  if (index !== -1) {
    fileList.value[index].url = fileInfo as string; // 确保fileInfo是字符串类型
    fileList.value[index].status = "success";
    // 同步更新modelValue（若index超出当前长度，push；否则替换）
    if (index >= modelValue.value.length) {
      modelValue.value.push(fileInfo as string);
    } else {
      modelValue.value[index] = fileInfo as string;
    }
  }

  // 2. 新增：完成计数+判断所有上传完成
  completedUploadCount.value++;
  if (completedUploadCount.value === pendingUploadCount.value) {
    ElMessage.success("所有图片上传成功！");
    emit('uploadAllSuccess', modelValue.value); // 所有图片上传完成，emit成功事件
    // 重置计数
    pendingUploadCount.value = 0;
    completedUploadCount.value = 0;
    emit('upDataEvent', false); // 结束loading
  }
};

/**
 * 上传失败回调
 */
const handleError = (error: any) => {
  console.error("上传失败:", error);
  ElMessage.error("上传失败: " + (error.message || "未知错误"));
  // 重置计数+结束loading
  pendingUploadCount.value = 0;
  completedUploadCount.value = 0;
  emit('upDataEvent', false);
};

/**
 * 预览图片
 */
const handlePreviewImage = (imageUrl: string) => {
  previewImageIndex.value = modelValue.value.findIndex((url) => url === imageUrl);
  previewVisible.value = true;
};

/**
 * 关闭预览
 */
const handlePreviewClose = () => {
  previewVisible.value = false;
};

// 监听modelValue同步fileList
watch(modelValue, (newValue) => {
  fileList.value = newValue.map((url) => ({
    url,
    uid: Date.now() + Math.random(), // 为已有图片生成唯一uid
    status: "success"
  }) as UploadUserFile);
}, { immediate: true });

onMounted(() => {
  // 初始化fileList
  fileList.value = modelValue.value.map((url) => ({
    url,
    uid: Date.now() + Math.random(),
    status: "success"
  }) as UploadUserFile);
});
</script>

<style lang="scss" scoped></style>