<template>
  <!-- 更换合同弹窗 -->
  <el-dialog
    v-model="replaceDialogVisible"
    title="更换合同"
    width="860px"
    :before-close="handleReplaceDialogClose"
    :close-on-click-modal="false"
    :close-on-press-escape="false"
  >
    <el-scrollbar height="400px" class="replace-upload-scrollbar">
      <div class="replace-upload-area" :class="{ 'upload-full': uploadedImageCount >= uploadMaxCount }">
        <el-upload
          v-model:file-list="fileList"
          list-type="picture-card"
          :accept="'.jpg,.png'"
          :limit="uploadMaxCount"
          :auto-upload="false"
          :disabled="hasUnuploadedImages"
          multiple
          :on-change="handleUploadChange"
          :on-exceed="handleUploadExceed"
          :on-preview="handlePictureCardPreview"
          :before-remove="handleBeforeRemove"
          :on-remove="handleRemove"
          :show-file-list="true"
        >
          <template #trigger>
            <div v-if="uploadedImageCount < uploadMaxCount" class="upload-trigger-card el-upload--picture-card">
              <el-icon>
                <Plus />
              </el-icon>
              <div class="upload-tip">({{ uploadedImageCount }}/{{ uploadMaxCount }})</div>
            </div>
          </template>
        </el-upload>
      </div>
    </el-scrollbar>
    <template #footer>
      <div class="dialog-footer">
        <el-button @click="handleCancelReplace" :disabled="hasUnuploadedImages"> 取消 </el-button>
        <el-button type="primary" @click="handleSubmitReplace" :disabled="hasUnuploadedImages"> 去审核 </el-button>
      </div>
    </template>
  </el-dialog>

  <!-- 图片预览 -->
  <el-image-viewer
    v-if="imageViewerVisible"
    :url-list="imageViewerUrlList"
    :initial-index="imageViewerInitialIndex"
    @close="imageViewerVisible = false"
  />
</template>

<script setup lang="ts" name="contractManagementwindow">
import { ref, computed } from "vue";
import { ElMessage, ElMessageBox } from "element-plus";
import { Plus } from "@element-plus/icons-vue";
import type { UploadProps, UploadFile } from "element-plus";
import { localGet } from "@/utils";
import { uploadContractImage, submitContractReview, getStoreContractStatus } from "@/api/modules/licenseManagement";

const replaceDialogVisible = ref(false);
const fileList = ref<UploadFile[]>([]);

// ==================== 图片上传相关变量 ====================
const uploadMaxCount = 20;
const uploading = ref(false);
const pendingUploadFiles = ref<UploadFile[]>([]);
const imageUrlList = ref<string[]>([]); // 存储图片URL列表

// 图片预览相关
const imageViewerVisible = ref(false);
const imageViewerUrlList = ref<string[]>([]);
const imageViewerInitialIndex = ref(0);

// 计算属性：获取已成功上传的图片数量
const uploadedImageCount = computed(() => {
  return fileList.value.filter((file: any) => file.status === "success" && file.url).length;
});

// 计算属性：检查是否有未上传完成的图片
const hasUnuploadedImages = computed(() => {
  // 检查是否有正在上传的文件
  if (uploading.value || pendingUploadFiles.value.length > 0) {
    return true;
  }
  // 检查文件列表中是否有状态为 "ready"（待上传）或 "uploading"（上传中）的图片
  if (fileList.value && fileList.value.length > 0) {
    return fileList.value.some((file: any) => {
      return file.status === "ready" || file.status === "uploading";
    });
  }
  return false;
});

const handleReplace = async () => {
  fileList.value = [];
  imageUrlList.value = [];
  pendingUploadFiles.value = [];
  uploading.value = false;
  const params = {
    id: localGet("createdId")
  };
  const res: any = await getStoreContractStatus(params);
  if (res.data.renewContractStatus === 2) {
    ElMessage.warning("合同审核中，请耐心等待");
  } else {
    replaceDialogVisible.value = true;
  }
};

/**
 * 检查文件是否在排队中（未上传）
 * @param file 文件对象
 * @returns 是否在排队中
 */
const isFilePending = (file: any): boolean => {
  // 只检查 ready 状态（排队中），不包括 uploading（正在上传）
  if (file.status === "ready") {
    return true;
  }
  // 检查是否在待上传队列中
  if (pendingUploadFiles.value.some(item => item.uid === file.uid)) {
    return true;
  }
  return false;
};

/**
 * 图片上传 - 删除前确认
 * @param uploadFile 要删除的文件对象
 * @param uploadFiles 当前文件列表
 * @returns Promise<boolean>，true 允许删除，false 阻止删除
 */
const handleBeforeRemove = async (uploadFile: any, uploadFiles: any[]): Promise<boolean> => {
  // 如果文件在排队中（未上传），禁止删除
  if (isFilePending(uploadFile)) {
    ElMessage.warning("图片尚未上传，请等待上传完成后再删除");
    return false;
  }
  try {
    await ElMessageBox.confirm("确定要删除这张图片吗？", "提示", {
      confirmButtonText: "确定",
      cancelButtonText: "取消",
      type: "warning"
    });
    // 用户确认删除，返回 true 允许删除
    return true;
  } catch {
    // 用户取消删除，返回 false 阻止删除
    return false;
  }
};

/**
 * 图片上传 - 移除图片回调（删除成功后调用）
 * @param uploadFile 已删除的文件对象
 * @param uploadFiles 删除后的文件列表
 */
const handleRemove: UploadProps["onRemove"] = (uploadFile, uploadFiles) => {
  // 从被删除的文件对象中获取 url
  const file = uploadFile as any;
  const imageUrl = file.url;

  if (imageUrl) {
    // 从 imageUrl 数组中删除对应的 URL
    const urlIndex = imageUrlList.value.indexOf(imageUrl);
    if (urlIndex > -1) {
      imageUrlList.value.splice(urlIndex, 1);
    }
  }

  if (file.url && file.url.startsWith("blob:")) {
    URL.revokeObjectURL(file.url);
  }
  // 同步文件列表
  fileList.value = [...uploadFiles];
  // 删除成功后提示
  ElMessage.success("图片已删除");
};

/**
 * 上传文件超出限制提示
 */
const handleUploadExceed: UploadProps["onExceed"] = () => {
  ElMessage.warning(`最多只能上传${uploadMaxCount}张图片`);
};

/**
 * el-upload 文件变更（选中或移除）
 */
const handleUploadChange: UploadProps["onChange"] = async (uploadFile, uploadFiles) => {
  // 检查文件类型，只允许 jpg 和 png
  if (uploadFile.raw) {
    const fileType = uploadFile.raw.type.toLowerCase();
    const fileName = uploadFile.name.toLowerCase();
    const validTypes = ["image/jpeg", "image/jpg", "image/png"];
    const validExtensions = [".jpg", ".jpeg", ".png"];

    // 检查 MIME 类型或文件扩展名
    const isValidType = validTypes.includes(fileType) || validExtensions.some(ext => fileName.endsWith(ext));

    if (!isValidType) {
      // 从文件列表中移除不符合类型的文件
      const index = fileList.value.findIndex((f: any) => f.uid === uploadFile.uid);
      if (index > -1) {
        fileList.value.splice(index, 1);
      }
      // 从 uploadFiles 中移除
      const uploadIndex = uploadFiles.findIndex((f: any) => f.uid === uploadFile.uid);
      if (uploadIndex > -1) {
        uploadFiles.splice(uploadIndex, 1);
      }
      // 如果文件有 blob URL，释放它
      if (uploadFile.url && uploadFile.url.startsWith("blob:")) {
        URL.revokeObjectURL(uploadFile.url);
      }
      ElMessage.warning("只支持上传 JPG 和 PNG 格式的图片");
      return;
    }
  }

  // 同步文件列表到表单数据（只添加通过验证的文件）
  const existingIndex = fileList.value.findIndex((f: any) => f.uid === uploadFile.uid);
  if (existingIndex === -1) {
    fileList.value.push(uploadFile);
  }

  const readyFiles = fileList.value.filter(file => file.status === "ready");
  if (readyFiles.length) {
    readyFiles.forEach(file => {
      if (!pendingUploadFiles.value.some(item => item.uid === file.uid)) {
        pendingUploadFiles.value.push(file);
      }
    });
  }
  processUploadQueue();
};

/**
 * 处理上传队列 - 逐个上传文件
 */
const processUploadQueue = async () => {
  if (uploading.value || pendingUploadFiles.value.length === 0) {
    return;
  }
  // 每次只取一个文件进行上传
  const file = pendingUploadFiles.value.shift();
  if (file) {
    await uploadSingleFile(file);
    // 继续处理队列中的下一个文件
    processUploadQueue();
  }
};

/**
 * 单文件上传图片
 * @param file 待上传的文件
 */
const uploadSingleFile = async (file: UploadFile) => {
  if (!file.raw) {
    return;
  }
  const rawFile = file.raw as File;
  const formData = new FormData();
  formData.append("file", rawFile);
  formData.append("user", "text");
  file.status = "uploading";
  file.percentage = 0;
  uploading.value = true;

  try {
    // 上传过程中先保持进度为 0，避免接口异常时进度条误显示 100%
    const result: any = await uploadContractImage(formData);
    if (result?.code === 200 && result.data) {
      // 处理单个文件的上传结果
      let imageUrl = result.data[0];
      if (!imageUrl) {
        throw new Error("上传成功但未获取到图片URL");
      }

      file.status = "success";
      file.percentage = 100;
      // 保存图片URL到文件对象
      file.url = imageUrl;
      file.response = { url: imageUrl };

      // 保存图片URL
      if (!Array.isArray(imageUrlList.value)) {
        imageUrlList.value = [];
      }
      if (!imageUrlList.value.includes(imageUrl)) {
        imageUrlList.value.push(imageUrl);
      }
    } else {
      throw new Error(result?.msg || "图片上传失败");
    }
  } catch (error: any) {
    // 上传失败时保持进度条为 0
    file.percentage = 0;
    file.status = "fail";
    if (file.url && file.url.startsWith("blob:")) {
      URL.revokeObjectURL(file.url);
    }
    // 从文件列表中移除失败的文件
    const index = fileList.value.findIndex((f: any) => f.uid === file.uid);
    if (index > -1) {
      fileList.value.splice(index, 1);
    }
  } finally {
    uploading.value = false;
    // 触发视图更新
    fileList.value = [...fileList.value];
  }
};

/**
 * 图片预览 - 使用 el-image-viewer 预览功能
 * @param file 上传文件对象
 */
const handlePictureCardPreview = (file: any) => {
  // 如果文件在排队中（未上传），禁止预览
  if (isFilePending(file)) {
    ElMessage.warning("图片尚未上传，请等待上传完成后再预览");
    return;
  }
  // 如果文件正在上传中，允许预览（使用本地预览）
  if (file.status === "uploading" && file.url) {
    imageViewerUrlList.value = [file.url];
    imageViewerInitialIndex.value = 0;
    imageViewerVisible.value = true;
    return;
  }
  // 获取所有图片的 URL 列表（只包含已上传成功的图片）
  const urlList = fileList.value
    .filter((item: any) => item.status === "success" && (item.url || item.response?.data))
    .map((item: any) => item.url || item.response?.data);
  // 找到当前点击的图片索引
  const currentIndex = urlList.findIndex((url: string) => url === (file.url || file.response?.data));
  if (currentIndex < 0) {
    ElMessage.warning("图片尚未上传完成，无法预览");
    return;
  }
  imageViewerUrlList.value = urlList;
  imageViewerInitialIndex.value = currentIndex;
  imageViewerVisible.value = true;
};

const handleCancelReplace = async () => {
  // 如果有图片正在上传，阻止关闭
  if (hasUnuploadedImages.value) {
    ElMessage.warning("请等待图片上传完成后再关闭");
    return;
  }
  if (fileList.value.length > 0) {
    try {
      await ElMessageBox.confirm("确定要取消本次图片上传吗?已上传的图片将不保存", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning"
      });
      // 用户确认取消
      fileList.value = [];
      imageUrlList.value = [];
      pendingUploadFiles.value = [];
      uploading.value = false;
      replaceDialogVisible.value = false;
    } catch {
      // 用户取消操作，不做任何处理
    }
  } else {
    replaceDialogVisible.value = false;
  }
};

const handleReplaceDialogClose = async (done: () => void) => {
  // 如果有图片正在上传，阻止关闭
  if (hasUnuploadedImages.value) {
    ElMessage.warning("请等待图片上传完成后再关闭");
    return; // 不调用 done()，阻止关闭弹窗
  }
  if (fileList.value.length > 0) {
    try {
      await ElMessageBox.confirm("确定要取消本次图片上传吗?已上传的图片将不保存", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning"
      });
      // 用户确认取消，清空数据并关闭弹窗
      fileList.value = [];
      imageUrlList.value = [];
      pendingUploadFiles.value = [];
      uploading.value = false;
      done(); // 调用 done() 允许关闭弹窗
    } catch {
      // 用户取消操作，不调用 done()，阻止关闭弹窗
    }
  } else {
    // 没有文件，直接关闭
    done();
  }
};

const handleSubmitReplace = async () => {
  // 检查是否有未上传完成的图片
  if (hasUnuploadedImages.value) {
    ElMessage.warning("请等待图片上传完成后再提交");
    return;
  }
  if (fileList.value.length === 0) {
    ElMessage.warning("请至少上传一张图片");
    return;
  }
  const uploadedFiles = fileList.value.filter(file => file.status === "success");
  if (uploadedFiles.length === 0) {
    ElMessage.warning("请先上传图片");
    return;
  }
  try {
    // 根据文件列表顺序，生成带排序的图片数据（排序从0开始）
    const imageDataWithSort = uploadedFiles.map((file, index) => ({
      imgUrl: file.url,
      imgSort: index,
      storeId: localGet("createdId")
    }));
    await submitContractReview(imageDataWithSort);
    ElMessage.success("提交审核成功");
    replaceDialogVisible.value = false;
    fileList.value = [];
    imageUrlList.value = [];
    pendingUploadFiles.value = [];
    uploading.value = false;
  } catch (error) {
    ElMessage.error("提交审核失败");
  }
};
</script>

<style lang="scss" scoped>
.replace-upload-scrollbar {
  :deep(.el-scrollbar__wrap) {
    overflow-x: hidden;
  }
}
.replace-upload-area {
  min-height: 300px;
  padding: 20px;
  :deep(.el-upload-list--picture-card .el-upload-list__item:hover .el-upload-list__item-status-label) {
    display: inline-flex !important;
    opacity: 1 !important;
  }
  :deep(.el-upload-list__item.is-success:focus .el-upload-list__item-status-label) {
    display: inline-flex !important;
    opacity: 1 !important;
  }
  :deep(.el-upload-list--picture-card .el-icon--close-tip) {
    display: none !important;
  }
  &.upload-full {
    :deep(.el-upload--picture-card) {
      display: none !important;
    }
  }
}
.dialog-footer {
  display: flex;
  gap: 10px;
  justify-content: center;
}

/* el-upload 图片预览铺满容器 */
:deep(.el-upload-list--picture-card) {
  .el-upload-list__item {
    overflow: hidden;
    .el-upload-list__item-thumbnail {
      width: 100%;
      height: 100%;
      object-fit: fill;
    }
  }

  /* 排队中（未上传）的图片禁用样式 */
  .el-upload-list__item[data-status="ready"],
  .el-upload-list__item.is-ready {
    position: relative;
    pointer-events: none;
    cursor: not-allowed;
    opacity: 0.6;
    &::after {
      position: absolute;
      inset: 0;
      z-index: 1;
      content: "";
      background-color: rgb(0 0 0 / 30%);
    }
    .el-upload-list__item-actions {
      pointer-events: none;
      opacity: 0.5;
    }
  }
}
.upload-trigger-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  font-size: 28px;
  color: #8c939d;
  .upload-tip {
    margin-top: 8px;
    font-size: 14px;
    color: #8c939d;
  }
}
</style>
