<template>
  <el-dialog
    v-model="visible"
    title="上传文件"
    width="600px"
    @close="handleClose"
  >
    <el-upload
      ref="uploadRef"
      :action="uploadAction"
      :headers="uploadHeaders"
      :data="uploadData"
      :file-list="fileList"
      :on-change="handleChange"
      :on-success="handleSuccess"
      :on-error="handleError"
      :on-progress="handleProgress"
      :on-remove="handleRemove"
      :before-upload="beforeUpload"
      :auto-upload="false"
      drag
      multiple
      class="upload-container"
    >
      <el-icon class="el-icon--upload"><UploadFilled /></el-icon>
      <div class="el-upload__text">
        将文件拖到此处，或<em>点击上传</em>
      </div>
      <template #tip>
        <div class="el-upload__tip">
          支持多文件上传，单个文件大小不超过50MB
        </div>
      </template>
    </el-upload>

    <template #footer>
      <div class="dialog-footer">
        <el-button @click="handleClose">取消</el-button>
        <el-button type="primary" @click="submitUpload" :loading="uploading">
          {{ uploading ? "上传中..." : "开始上传" }}
        </el-button>
      </div>
    </template>
  </el-dialog>
</template>

<script lang="ts" setup>
import { ref, computed } from "vue";
import { ElMessage, ElMessageBox } from "element-plus";
import { UploadFilled } from "@element-plus/icons-vue";
import { uploadFile } from "@/api/file";
import type { UploadInstance, UploadFile, UploadFiles } from "element-plus";

interface Props {
  modelValue: boolean;
  categoryId?: number;
}

interface Emits {
  (e: "update:modelValue", value: boolean): void;
  (e: "success"): void;
}

const props = withDefaults(defineProps<Props>(), {
  modelValue: false,
  categoryId: undefined,
});

const emit = defineEmits<Emits>();

const visible = computed({
  get: () => props.modelValue,
  set: (val) => emit("update:modelValue", val),
});

const uploadRef = ref<UploadInstance>();
const fileList = ref<UploadFile[]>([]);
const uploading = ref(false);
const uploadAction = ref(""); // 不使用action，手动上传

// 上传请求头
const uploadHeaders = computed(() => {
  const token = localStorage.getItem("token");
  return {
    Authorization: token ? `Bearer ${token}` : "",
  };
});

// 上传额外数据
const uploadData = computed(() => ({
  cate: props.categoryId || 0,
}));

// 文件变化监听
const handleChange = (file: UploadFile, files: UploadFiles) => {
  // 更新文件列表
  fileList.value = files;
};

// 文件上传前的验证
const beforeUpload = (file: File) => {
  const maxSize = 50 * 1024 * 1024; // 50MB
  const isValidType = true; // 可以根据需要限制文件类型

  if (file.size > maxSize) {
    ElMessage.error(`文件 ${file.name} 大小超过50MB限制`);
    return false;
  }

  return true;
};

// 移除文件
const handleRemove = (file: UploadFile) => {
  const index = fileList.value.findIndex((item) => item.uid === file.uid);
  if (index > -1) {
    fileList.value.splice(index, 1);
  }
};

// 上传进度
const handleProgress = (event: any, file: UploadFile) => {
  file.status = "uploading";
  file.percentage = Math.round(event.percent);
};

// 上传成功
const handleSuccess = (response: any, file: UploadFile) => {
  // 只要 code === 200 或 201 都视作已成功（存在或新上传）
  if (response.code === 200) {
    file.status = "success";
    ElMessage.success(`文件 ${file.name} 上传成功`);
  } else if (response.code === 201) {
    file.status = "success";
    ElMessage.info(response.msg || `文件 ${file.name} 已存在`);
  } else {
    file.status = "fail";
    ElMessage.error(response.msg || response.message || `文件 ${file.name} 上传失败`);
  }
};

// 上传失败
const handleError = (error: any, file: UploadFile) => {
  file.status = "fail";
  let msg = error?.message || error?.msg || '';
  if (!msg && error?.response && error.response.data) {
    msg = error.response.data.msg || error.response.data.message;
  }
  console.error("上传失败:", error);
  ElMessage.error(msg ? `文件 ${file.name} 上传失败：${msg}` : `文件 ${file.name} 上传失败`);
};

// 手动提交上传
const submitUpload = async () => {
  if (!uploadRef.value) return;

  // 从 upload 组件实例获取文件列表
  const uploadFiles = uploadRef.value.uploadFiles || fileList.value;
  
  const filesToUpload = uploadFiles.filter(
    (file: UploadFile) => file.status !== "success" && file.raw
  );
  
  if (filesToUpload.length === 0) {
    ElMessage.warning("请先选择要上传的文件");
    return;
  }

  uploading.value = true;

  try {
    // 逐个上传文件，显示进度
    const uploadPromises = filesToUpload.map(async (file) => {
      file.status = "uploading";
      file.percentage = 0;

      try {
        const formData = new FormData();
        formData.append("file", file.raw as File);
        if (props.categoryId) {
          formData.append("cate", props.categoryId.toString());
        }

        // 模拟上传进度
        const progressInterval = setInterval(() => {
          if (file.percentage < 90) {
            file.percentage = Math.min(file.percentage + 10, 90);
          }
        }, 200);

        const res = await uploadFile(formData, { cate: props.categoryId });
        
        clearInterval(progressInterval);
        file.percentage = 100;

        // code 200 表示新上传成功，code 201 表示文件已存在（也视为成功）
        if (res.code === 200 || res.code === 201) {
          file.status = "success";
          return { success: true, file, res };
        } else {
          file.status = "fail";
          throw new Error(res.msg || "上传失败");
        }
      } catch (error: any) {
        file.status = "fail";
        file.percentage = 0;
        throw { file, error };
      }
    });

    const results = await Promise.allSettled(uploadPromises);
    
    const successCount = results.filter((r) => r.status === "fulfilled").length;
    const failCount = results.filter((r) => r.status === "rejected").length;

    // 统计新上传和已存在的文件数量
    let newUploadCount = 0;
    let existCount = 0;
    results.forEach((result) => {
      if (result.status === "fulfilled" && result.value?.res) {
        if (result.value.res.code === 200) {
          newUploadCount++;
        } else if (result.value.res.code === 201) {
          existCount++;
        }
      }
    });

    if (successCount > 0) {
      let message = "";
      if (newUploadCount > 0 && existCount > 0) {
        message = `成功处理 ${successCount} 个文件（${newUploadCount} 个新上传，${existCount} 个已存在）`;
      } else if (newUploadCount > 0) {
        message = `成功上传 ${newUploadCount} 个文件`;
      } else if (existCount > 0) {
        message = `${existCount} 个文件已存在`;
      } else {
        message = `成功处理 ${successCount} 个文件`;
      }
      ElMessage.success(message);
    }
    if (failCount > 0) {
      ElMessage.warning(`${failCount} 个文件上传失败`);
    }

    // 如果所有文件都上传成功，关闭对话框并刷新列表
    if (failCount === 0) {
      emit("success");
      handleClose();
    }
  } catch (error: any) {
    console.error("上传失败:", error);
    ElMessage.error("上传过程中发生错误");
  } finally {
    uploading.value = false;
  }
};

// 关闭对话框
const handleClose = () => {
  fileList.value = [];
  uploading.value = false;
  visible.value = false;
};
</script>

<style lang="less" scoped>
.upload-container {
  :deep(.el-upload) {
    width: 100%;
  }

  :deep(.el-upload-dragger) {
    width: 100%;
    height: 180px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
  }

  .el-icon--upload {
    font-size: 67px;
    color: #c0c4cc;
    margin-bottom: 16px;
  }

  .el-upload__text {
    color: #606266;
    font-size: 14px;
    text-align: center;

    em {
      color: #3973ff;
      font-style: normal;
    }
  }

  .el-upload__tip {
    color: #909399;
    font-size: 12px;
    margin-top: 8px;
    text-align: center;
  }
}

.dialog-footer {
  display: flex;
  justify-content: flex-end;
  gap: 12px;
}
</style>

