<template>
  <div class="photo-album-container">
    <!-- 头部：环境/视频/相册 Tab和新建按钮 -->
    <div class="header-section">
      <el-tabs v-model="activeTab" @tab-click="handleTabClick">
        <el-tab-pane label="环境" name="environment" />
        <el-tab-pane label="视频" name="video" />
        <el-tab-pane v-for="album in albumList" :key="album.id" :label="album.name" :name="String(album.id)">
          <template #label>
            <span class="album-tab-label">
              {{ album.name }}
              <el-icon class="edit-icon" @click.stop="handleEditAlbum(album)">
                <Edit />
              </el-icon>
            </span>
          </template>
        </el-tab-pane>
      </el-tabs>
      <div class="header-actions">
        <el-button type="primary" @click="openCreateDialog"> 新建相册 </el-button>
      </div>
    </div>

    <!-- 内容区域 -->
    <div class="content-section">
      <!-- 环境/相册 Tab：图片上传说明 -->
      <div v-if="isImageTab" class="upload-tips">
        <span>照片宽高不小于500像素</span>
        <span>大小不超过10M</span>
        <span>可拖拽排序</span>
        <span>暂不支持上传动图</span>
        <span>不可上传手机截屏、含清晰人脸/电话/二维码/第三方水印/LOGO等图片。</span>
      </div>

      <!-- 视频 Tab：视频上传说明 -->
      <div v-if="activeTab === 'video'" class="upload-tips">
        <span>单个视频上传大小不超过500MB</span>
        <span>可拖拽排序</span>
        <span>时长建议小于1分钟</span>
      </div>

      <!-- 环境/相册 Tab：图片上传和展示区域 -->
      <div v-if="isImageTab" class="media-grid">
        <!-- 上传按钮 -->
        <div class="upload-item upload-box">
          <!-- 环境tab：直接绑定 environmentImages -->
          <UploadImgs
            v-if="activeTab === 'environment'"
            v-model:file-list="environmentImages"
            :limit="50"
            :file-size="10"
            :file-type="['image/jpeg', 'image/png', 'image/gif', 'image/webp']"
            :width="'100%'"
            :height="'200px'"
            :border-radius="'8px'"
            :api="customImageUploadApi"
          >
            <template #tip>
              <div class="upload-tip-text">上传图片 ({{ environmentImages.length }}/50)</div>
            </template>
          </UploadImgs>
          <!-- 相册tab：根据当前相册动态绑定 -->
          <UploadImgs
            v-else-if="currentAlbumRef"
            v-model:file-list="currentAlbumRef.images"
            :limit="50"
            :file-size="10"
            :file-type="['image/jpeg', 'image/png', 'image/gif', 'image/webp']"
            :width="'100%'"
            :height="'200px'"
            :border-radius="'8px'"
            :api="customImageUploadApi"
          >
            <template #tip>
              <div class="upload-tip-text">上传图片 ({{ currentAlbumRef.images?.length || 0 }}/50)</div>
            </template>
          </UploadImgs>
        </div>

        <!-- 已上传的图片 -->
        <div v-for="(image, index) in displayImages" :key="image.uid || index" class="media-item">
          <div class="media-wrapper">
            <img :src="image.url || ''" alt="相册图片" />
            <div class="media-overlay">
              <el-button type="primary" link @click="viewImage(image.url || '')"> 查看 </el-button>
              <el-button type="primary" link @click="deleteImage(index)"> 删除 </el-button>
            </div>
            <el-tag v-if="isFirstImage(index)" type="danger" class="cover-tag"> 封面 </el-tag>
          </div>
        </div>
      </div>

      <!-- 视频 Tab：视频上传和展示区域 -->
      <div v-if="activeTab === 'video'" class="media-grid">
        <!-- 上传按钮 -->
        <div class="upload-item upload-box">
          <UploadImgs
            v-model:file-list="videoList"
            :limit="10"
            :file-size="500"
            :file-type="['video/mp4', 'video/webm', 'video/ogg', 'video/quicktime'] as any"
            :width="'100%'"
            :height="'200px'"
            :border-radius="'8px'"
            :api="customVideoUploadApi"
            :on-success="handleVideoUploadSuccess"
          >
            <template #tip>
              <div class="upload-tip-text">上传视频 ({{ videoList.length }}/10)</div>
            </template>
          </UploadImgs>
        </div>

        <!-- 已上传的视频 -->
        <div v-for="(video, index) in displayVideos" :key="video.uid || index" class="media-item">
          <div class="media-wrapper">
            <video v-if="video.url" :src="video.url" class="media-preview" muted preload="metadata" playsinline />
            <div v-else class="media-placeholder">
              <el-icon><VideoPlay /></el-icon>
              <span>视频预览</span>
            </div>
            <div class="media-overlay">
              <el-button type="primary" link @click="viewVideo(video.url || '')"> 查看 </el-button>
              <el-button type="primary" link @click="deleteVideo(index)"> 删除 </el-button>
            </div>
          </div>
        </div>
      </div>
    </div>
    <!-- 分页 -->
    <div class="pagination-section">
      <el-pagination
        v-model:current-page="pageable.pageNum"
        v-model:page-size="pageable.pageSize"
        :page-sizes="[10, 20, 50, 100]"
        :total="pageable.total"
        layout="total, sizes, prev, pager, next, jumper"
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
      />
    </div>
    <!-- 新建/编辑相册弹窗 -->
    <el-dialog v-model="createDialogVisible" :title="editId ? '修改相册名称' : '新建相册'" width="500px" @close="resetCreateForm">
      <el-form :model="createForm" :rules="createRules" ref="createFormRef" label-width="0">
        <el-form-item prop="name">
          <el-input v-model="createForm.name" placeholder="请输入相册名称" maxlength="6" clearable show-word-limit />
        </el-form-item>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <div class="footer-left">
            <el-button v-if="editId" type="danger" @click="handleDeleteAlbum"> 删除相册 </el-button>
          </div>
          <div class="footer-right">
            <el-button @click="createDialogVisible = false"> 取消 </el-button>
            <el-button type="primary" @click="handleCreateAlbum"> 确定 </el-button>
          </div>
        </div>
      </template>
    </el-dialog>

    <!-- 图片/视频预览对话框 -->
    <el-dialog v-model="previewVisible" width="600px" align-center class="preview-dialog">
      <div class="preview-content">
        <img v-if="isImageTab" :src="previewImageUrl" alt="预览图片" class="preview-image" />
        <video v-else-if="activeTab === 'video'" :src="previewVideoUrl" controls class="preview-video" />
      </div>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, computed, onMounted, watch, nextTick } from "vue";
import { ElMessage, ElMessageBox } from "element-plus";
import type { FormInstance, FormRules } from "element-plus";
import type { UploadUserFile } from "element-plus";
import { VideoPlay, Edit } from "@element-plus/icons-vue";
import UploadImgs from "@/components/Upload/Imgs.vue";
import { localGet } from "@/utils";
import {
  getOfficialAlbumList,
  createOrUpdateOfficialAlbum,
  deleteOfficialAlbum,
  saveOfficialImg,
  getOfficialImgList,
  deleteOfficialImg
} from "@/api/modules/storeDecoration";
import { uploadFilesToOss } from "@/api/upload.js";

// 扩展图片类型
interface AlbumImage extends UploadUserFile {
  isCover?: boolean;
  businessId?: number; // 相册ID
  imgSort?: number; // 排序
  imgType?: number; // 图片类型，固定为2
  imgId?: number; // 图片ID（从服务器返回）
}

// 扩展视频类型
interface AlbumVideo extends UploadUserFile {
  businessId?: number; // 相册ID
  imgSort?: number; // 排序
  imgType?: number; // 视频类型，可能是3或其他值
  imgId?: number; // 视频ID（从服务器返回）
  videoDuration?: number; // 视频时长（秒）
}

// 相册接口
interface Album {
  id: string | number;
  name: string;
  albumName?: string; // API返回的字段名
  images: AlbumImage[];
  videos: AlbumVideo[];
  coverImageId?: string | number;
}

const createDialogVisible = ref(false);
const createFormRef = ref<FormInstance>();
const activeTab = ref("environment"); // 当前选中的tab：environment、video 或 相册ID
const previewVisible = ref(false);
const previewImageUrl = ref("");
const previewVideoUrl = ref("");
const editId = ref<string | number | null>(null);

// 正在保存的图片URL集合，防止重复保存
const savingImages = ref<Set<string>>(new Set());
// 已处理过的图片URL集合，防止重复处理
const processedImages = ref<Set<string>>(new Set());
// 是否正在加载相册图片（用于跳过watch触发）
const isLoadingAlbumImages = ref(false);

// 相册列表
const albumList = ref<Album[]>([]);

// 判断当前是否为图片tab（环境或相册）
const isImageTab = computed(() => {
  return (
    activeTab.value === "environment" ||
    (activeTab.value !== "video" && albumList.value.some(album => String(album.id) === activeTab.value))
  );
});

// 当前选中的相册或环境数据
const currentAlbum = computed(() => {
  // 如果是环境tab，返回环境数据（使用特殊ID）
  if (activeTab.value === "environment") {
    return { id: "environment", name: "环境", images: environmentImages.value, videos: [] };
  }
  // 如果是视频tab，返回视频数据（使用特殊ID）
  if (activeTab.value === "video") {
    return { id: "video", name: "视频", images: [], videos: videoList.value };
  }
  // 否则是相册tab，查找对应的相册
  const album = albumList.value.find(album => String(album.id) === activeTab.value);
  if (album) {
    // 确保 videos 数组存在（相册只有图片，没有视频）
    if (!album.videos) {
      album.videos = [];
    }
    return album;
  }
  return { id: "", name: "", images: [], videos: [] };
});

// 环境图片列表（独立的，不属于任何相册）
const environmentImages = ref<AlbumImage[]>([]);

// 视频列表（独立的，不属于任何相册）
const videoList = ref<AlbumVideo[]>([]);

// 当前相册的引用（用于直接绑定，确保响应式更新）
const currentAlbumRef = computed(() => {
  if (activeTab.value === "environment") {
    return null; // 环境tab使用单独的绑定
  }
  const album = albumList.value.find(album => String(album.id) === activeTab.value);
  if (album) {
    // 确保 images 数组存在且是响应式的
    if (!album.images) {
      album.images = reactive<AlbumImage[]>([]);
    }
    return album;
  }
  return null;
});

// 当前相册的图片列表（用于计算显示）
const currentAlbumImages = computed(() => {
  if (activeTab.value === "environment") {
    return environmentImages.value;
  }
  return currentAlbumRef.value?.images || [];
});

// 当前媒体列表（根据tab类型返回图片或视频）
const currentMediaList = computed(() => {
  if (activeTab.value === "video") {
    return videoList.value;
  }
  return currentAlbumImages.value || [];
});

// 分页数据
const pageable = reactive({
  pageNum: 1,
  pageSize: 10,
  total: 0
});

// 显示图片列表（分页后）
const displayImages = computed(() => {
  // 如果不在图片tab，返回空数组
  if (!isImageTab.value) {
    return [];
  }

  let images: AlbumImage[] = [];
  if (activeTab.value === "environment") {
    images = environmentImages.value || [];
  } else if (activeTab.value !== "video") {
    images = currentAlbumRef.value?.images || [];
  }

  // 如果没有图片，直接返回空数组
  if (images.length === 0) {
    return [];
  }

  const start = (pageable.pageNum - 1) * pageable.pageSize;
  const end = start + pageable.pageSize;
  return images.slice(start, end);
});

// 显示视频列表（分页后）
const displayVideos = computed(() => {
  if (activeTab.value !== "video") {
    return [];
  }
  const videos = videoList.value || [];

  // 如果没有视频，直接返回空数组
  if (videos.length === 0) {
    return [];
  }

  const start = (pageable.pageNum - 1) * pageable.pageSize;
  const end = start + pageable.pageSize;
  return videos.slice(start, end);
});

// 新建相册表单
const createForm = reactive({
  name: ""
});

// 新建相册表单校验规则
const createRules = reactive<FormRules>({
  name: [
    { required: true, message: "请输入相册名称", trigger: "blur" },
    { min: 1, max: 6, message: "相册名称长度在1到6个字符", trigger: "blur" }
  ]
});

// 图片尺寸校验函数（不小于500像素）
const validateImageDimensions = (file: File): Promise<boolean> => {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.onload = (e: ProgressEvent<FileReader>) => {
      const img = new Image();
      img.onload = () => {
        const width = img.width;
        const height = img.height;

        // 检查尺寸：不小于500像素
        if (width < 500 || height < 500) {
          ElMessage.warning("照片宽高不小于500像素");
          reject(new Error("图片尺寸不符合要求"));
          return;
        }

        resolve(true);
      };
      img.onerror = () => {
        reject(new Error("图片加载失败"));
      };
      if (e.target?.result) {
        img.src = e.target.result as string;
      }
    };
    reader.onerror = () => {
      reject(new Error("文件读取失败"));
    };
    reader.readAsDataURL(file);
  });
};

// 自定义图片上传 API（OSS 直传）
const customImageUploadApi = async (formData: FormData): Promise<any> => {
  const raw = formData.get("file");
  const file = raw instanceof File ? raw : null;
  if (!file) {
    throw new Error("请选择文件");
  }

  try {
    await validateImageDimensions(file);
  } catch (error) {
    throw error;
  }

  const urls = await uploadFilesToOss(file, "image");
  const fileUrl = urls[0];
  if (!fileUrl) {
    throw new Error("上传失败，未返回地址");
  }

  const response = {
    data: { fileUrl },
    fileUrl
  };
  await nextTick();
  return response;
};

// 检测视频时长的辅助函数
const getVideoDuration = (file: File): Promise<number> => {
  return new Promise(resolve => {
    if (!file.type.startsWith("video/")) {
      resolve(0);
      return;
    }

    const video = document.createElement("video");
    video.preload = "metadata";

    video.onloadedmetadata = () => {
      window.URL.revokeObjectURL(video.src);
      const duration = Math.floor(video.duration);
      resolve(duration);
    };

    video.onerror = () => {
      window.URL.revokeObjectURL(video.src);
      resolve(0);
    };

    video.src = URL.createObjectURL(file);
  });
};

// 视频上传成功回调，用于保存视频时长
const handleVideoUploadSuccess = async (url: string) => {
  // 找到对应的视频文件
  const video = videoList.value.find((v: AlbumVideo) => v.url === url && !v.videoDuration);
  if (!video || !video.raw) {
    return;
  }

  // 检测视频时长
  try {
    const duration = await getVideoDuration(video.raw as File);
    if (duration > 0) {
      video.videoDuration = duration;
    }
  } catch (error) {
    console.error("获取视频时长失败:", error);
  }
};

// 自定义视频上传 API（OSS 直传）
const customVideoUploadApi = async (formData: FormData): Promise<any> => {
  const raw = formData.get("file");
  const file = raw instanceof File ? raw : null;
  if (!file) {
    throw new Error("请选择文件");
  }

  const fileSizeMB = file.size / 1024 / 1024;
  if (fileSizeMB > 500) {
    ElMessage.warning(`视频大小不能超过 500MB，当前为 ${fileSizeMB.toFixed(2)}MB`);
    throw new Error("视频大小超过限制");
  }

  const urls = await uploadFilesToOss(file, "video");
  const fileUrl = urls[0];
  if (!fileUrl) {
    throw new Error("上传失败，未返回地址");
  }

  const response = {
    data: { fileUrl },
    fileUrl
  };
  await nextTick();
  return response;
};

// 保存图片到服务器
const saveImageToServer = async (imgUrl: string) => {
  // 如果正在保存，直接返回，防止重复保存
  if (savingImages.value.has(imgUrl)) {
    return;
  }

  try {
    const userInfo: any = localGet("geeker-user")?.userInfo || {};
    const storeId = userInfo.storeId;
    if (!storeId) {
      return;
    }

    // 判断是环境图片还是相册图片
    let businessId: number;
    let currentImages: AlbumImage[];

    if (activeTab.value === "environment") {
      // 环境图片：使用 storeId 作为 businessId（需要根据实际API调整）
      businessId = Number(storeId);
      currentImages = environmentImages.value || [];
    } else {
      // 相册图片：使用相册ID作为 businessId
      if (!currentAlbumRef.value) {
        return;
      }
      businessId = Number(currentAlbumRef.value.id);
      currentImages = currentAlbumRef.value.images || [];
    }

    // 找到对应的图片（通过URL匹配）
    const targetImage = currentImages.find((img: AlbumImage) => img.url === imgUrl && !img.imgId);
    if (!targetImage) {
      return; // 如果图片已经有ID或找不到，不重复保存
    }

    // 标记为正在保存
    savingImages.value.add(imgUrl);

    const imgSort = currentImages.filter((img: AlbumImage) => img.imgId).length + 1; // 排序为已保存图片数量+1

    const params = [
      {
        businessId: businessId,
        imgSort: imgSort,
        imgType: 2, // 图片类型为2
        imgUrl: imgUrl,
        storeId: Number(storeId)
      }
    ];

    const res: any = await saveOfficialImg(params);
    if (res && (res.code === 200 || res.code === "200") && res.data && res.data[0]) {
      // 保存成功后，更新图片的ID和其他信息
      targetImage.imgId = res.data[0].id;
      targetImage.businessId = res.data[0].businessId;
      targetImage.imgSort = res.data[0].imgSort;
      // 保存成功后，从已处理集合中移除，允许后续更新
      processedImages.value.delete(imgUrl);
    }
  } catch (error) {
    console.error("保存图片信息失败:", error);
    // 保存失败时，也从已处理集合中移除，允许重试
    processedImages.value.delete(imgUrl);
  } finally {
    // 无论成功或失败，都移除保存标记
    savingImages.value.delete(imgUrl);
  }
};

// 保存视频到服务器
const saveVideoToServer = async (videoUrl: string) => {
  // 如果正在保存，直接返回，防止重复保存
  if (savingImages.value.has(videoUrl)) {
    return;
  }

  try {
    const userInfo: any = localGet("geeker-user")?.userInfo || {};
    const storeId = userInfo.storeId;
    if (!storeId || activeTab.value !== "video") {
      return;
    }

    const currentVideos = videoList.value || [];
    // 找到对应的视频（通过URL匹配）
    const targetVideo = currentVideos.find((video: AlbumVideo) => video.url === videoUrl && !video.imgId);
    if (!targetVideo) {
      return; // 如果视频已经有ID或找不到，不重复保存
    }

    // 标记为正在保存
    savingImages.value.add(videoUrl);

    const imgSort = currentVideos.filter((video: AlbumVideo) => video.imgId).length + 1; // 排序为已保存视频数量+1

    // 视频：使用 storeId 作为 businessId（需要根据实际API调整）
    const params = [
      {
        businessId: Number(storeId), // 视频使用 storeId 作为 businessId
        imgSort: imgSort,
        imgType: 3, // 视频类型为3
        imgUrl: videoUrl,
        storeId: Number(storeId),
        videoDuration: targetVideo.videoDuration || 0
      }
    ];

    const res: any = await saveOfficialImg(params);
    if (res && (res.code === 200 || res.code === "200") && res.data && res.data[0]) {
      // 保存成功后，更新视频的ID和其他信息
      targetVideo.imgId = res.data[0].id;
      targetVideo.businessId = res.data[0].businessId;
      targetVideo.imgSort = res.data[0].imgSort;
      // 保存成功后，从已处理集合中移除，允许后续更新
      processedImages.value.delete(videoUrl);
    }
  } catch (error) {
    console.error("保存视频信息失败:", error);
    // 保存失败时，也从已处理集合中移除，允许重试
    processedImages.value.delete(videoUrl);
  } finally {
    // 无论成功或失败，都移除保存标记
    savingImages.value.delete(videoUrl);
  }
};

// 打开新建相册弹窗
const openCreateDialog = () => {
  editId.value = null;
  createDialogVisible.value = true;
  resetCreateForm();
};

// 重置新建表单
const resetCreateForm = () => {
  createForm.name = "";
  editId.value = null;
  createFormRef.value?.clearValidate();
};

// 创建/更新相册
const handleCreateAlbum = async () => {
  if (!createFormRef.value) return;

  try {
    await createFormRef.value.validate();
  } catch (error) {
    return;
  }

  if (!createForm.name.trim()) {
    ElMessage.warning("请输入相册名称");
    return;
  }

  try {
    const userInfo: any = localGet("geeker-user")?.userInfo || {};
    const storeId = userInfo.storeId;
    if (!storeId) {
      ElMessage.error("未找到店铺ID");
      return;
    }

    const params: any = {
      albumName: createForm.name.trim(),
      storeId: Number(storeId)
    };

    if (editId.value) {
      params.id = editId.value;
    }

    const res: any = await createOrUpdateOfficialAlbum(params);
    if (res && (res.code === 200 || res.code === "200")) {
      ElMessage.success(editId.value ? "修改相册成功" : "新建相册成功");
      createDialogVisible.value = false;

      // 保存当前选中的相册ID
      const currentAlbumId = activeTab.value;

      resetCreateForm();
      await getAlbumList();

      // 如果是编辑相册，重新加载当前相册的图片
      if (editId.value && currentAlbumId) {
        activeTab.value = currentAlbumId;
        await loadAlbumImages(currentAlbumId);
      } else if (!editId.value && albumList.value.length > 0) {
        // 如果是新建相册，切换到新创建的相册并加载图片
        const newAlbum = albumList.value[albumList.value.length - 1];
        activeTab.value = String(newAlbum.id);
        await loadAlbumImages(String(newAlbum.id));
      }
    } else {
      ElMessage.error(res?.msg || (editId.value ? "修改相册失败" : "新建相册失败"));
    }
  } catch (error: any) {
    console.error("保存相册失败:", error);
    ElMessage.error(error?.msg || "操作失败，请重试");
  }
};

// Tab 切换（环境/视频/相册）
const handleTabClick = async (tab: any) => {
  const tabName = tab.props.name;
  // 如果已经是当前tab，不重复加载
  if (activeTab.value === tabName) {
    return;
  }
  activeTab.value = tabName;
  pageable.pageNum = 1;

  // 根据tab类型加载数据（watch 会处理加载，这里只更新分页）
  await nextTick();
  updatePagination();
};

// 编辑相册
const handleEditAlbum = (album?: Album) => {
  const targetAlbum = album || albumList.value.find(album => String(album.id) === activeTab.value);
  if (!targetAlbum) {
    ElMessage.warning("请先选择要编辑的相册");
    return;
  }
  editId.value = targetAlbum.id;
  createForm.name = targetAlbum.name || targetAlbum.albumName || "";
  createDialogVisible.value = true;
  createFormRef.value?.clearValidate();
};

// 删除相册
const handleDeleteAlbum = async () => {
  if (!editId.value) {
    return;
  }

  try {
    await ElMessageBox.confirm("确认删除该相册吗？删除后相册内的所有图片也将被删除。", "提示", {
      confirmButtonText: "确定",
      cancelButtonText: "取消",
      type: "warning"
    });

    // 找到要删除的相册
    const albumToDelete = albumList.value.find(album => album.id === editId.value);
    if (!albumToDelete) {
      ElMessage.error("未找到要删除的相册");
      return;
    }

    // 调用删除接口
    const res: any = await deleteOfficialAlbum([albumToDelete]);
    if (res && (res.code === 200 || res.code === "200")) {
      ElMessage.success("删除相册成功");
      createDialogVisible.value = false;
      resetCreateForm();

      // 重新获取相册列表
      await getAlbumList();

      // 如果删除的是当前选中的相册，切换到环境tab
      if (String(editId.value) === activeTab.value) {
        activeTab.value = "environment";
        await loadEnvironmentImages();
      }
    } else {
      ElMessage.error(res?.msg || "删除相册失败");
    }
  } catch (error: any) {
    if (error !== "cancel") {
      console.error("删除相册失败:", error);
      ElMessage.error(error?.msg || "删除失败，请重试");
    }
  }
};

// 查看图片
const viewImage = (url: string) => {
  previewImageUrl.value = url;
  previewVisible.value = true;
};

// 查看视频
const viewVideo = (url: string) => {
  previewVideoUrl.value = url;
  previewVisible.value = true;
};

// 删除图片
const deleteImage = async (index: number) => {
  const actualIndex = (pageable.pageNum - 1) * pageable.pageSize + index;

  // 根据当前tab获取对应的图片列表
  let imageList: AlbumImage[];
  if (activeTab.value === "environment") {
    imageList = environmentImages.value;
  } else {
    imageList = currentAlbumRef.value?.images || [];
  }

  const image = imageList[actualIndex] as AlbumImage;
  if (!image) {
    return;
  }

  try {
    // 如果图片有ID，说明已保存到服务器，需要调用删除接口
    if (image.imgId) {
      // 调用删除接口，参数是图片ID数组
      const params = [image.imgId];

      const res: any = await deleteOfficialImg(params);
      if (res && (res.code === 200 || res.code === "200")) {
        imageList.splice(actualIndex, 1);
        updatePagination();
        ElMessage.success("删除成功");
      } else {
        ElMessage.error(res?.msg || "删除失败");
      }
    } else {
      // 如果图片还没有保存到服务器，直接删除本地数据
      imageList.splice(actualIndex, 1);
      updatePagination();
      ElMessage.success("删除成功");
    }
  } catch (error: any) {
    console.error("删除图片失败:", error);
    ElMessage.error(error?.msg || "删除失败，请重试");
  }
};

// 删除视频
const deleteVideo = async (index: number) => {
  const actualIndex = (pageable.pageNum - 1) * pageable.pageSize + index;
  const video = videoList.value[actualIndex] as AlbumVideo;
  if (!video) {
    return;
  }

  try {
    // 如果视频有ID，说明已保存到服务器，需要调用删除接口
    if (video.imgId) {
      // 调用删除接口，参数是视频ID数组
      const params = [video.imgId];

      const res: any = await deleteOfficialImg(params);
      if (res && (res.code === 200 || res.code === "200")) {
        videoList.value.splice(actualIndex, 1);
        updatePagination();
        ElMessage.success("删除成功");
      } else {
        ElMessage.error(res?.msg || "删除失败");
      }
    } else {
      // 如果视频还没有保存到服务器，直接删除本地数据
      videoList.value.splice(actualIndex, 1);
      updatePagination();
      ElMessage.success("删除成功");
    }
  } catch (error: any) {
    console.error("删除视频失败:", error);
    ElMessage.error(error?.msg || "删除失败，请重试");
  }
};

// 判断是否是第一张图片（封面）
const isFirstImage = (displayIndex: number): boolean => {
  // 计算在整个图片列表中的实际索引
  const actualIndex = (pageable.pageNum - 1) * pageable.pageSize + displayIndex;
  // 第一张图片（索引为0）是封面
  return actualIndex === 0;
};

// 更新分页总数
const updatePagination = () => {
  if (activeTab.value === "video") {
    pageable.total = videoList.value?.length || 0;
  } else if (activeTab.value === "environment") {
    pageable.total = environmentImages.value?.length || 0;
  } else {
    const album = albumList.value.find(album => String(album.id) === activeTab.value);
    pageable.total = album?.images?.length || 0;
  }
};

// 分页大小改变
const handleSizeChange = (size: number) => {
  pageable.pageSize = size;
  pageable.pageNum = 1;
};

// 当前页改变
const handleCurrentChange = (page: number) => {
  pageable.pageNum = page;
};

// 监听图片列表变化，更新分页并保存新上传的图片
watch(
  () => {
    // 根据当前tab返回对应的图片列表
    if (activeTab.value === "environment") {
      return environmentImages.value || [];
    } else if (activeTab.value !== "video") {
      // 相册tab
      return currentAlbumRef.value?.images || [];
    }
    return [];
  },
  async (newImages, oldImages) => {
    // 如果不在图片 tab，不处理
    if (!isImageTab.value) {
      return;
    }

    updatePagination();

    // 如果正在加载图片（从服务器加载），跳过处理，避免重复保存
    if (isLoadingAlbumImages.value) {
      return;
    }

    // 找出真正新增的图片（通过对比URL）
    const oldUrls = new Set((oldImages || []).map((img: AlbumImage) => img.url).filter((url): url is string => Boolean(url)));
    const newUrls = new Set((newImages || []).map((img: AlbumImage) => img.url).filter((url): url is string => Boolean(url)));

    // 找出新增的URL（在新列表中存在，但在旧列表中不存在）
    const addedUrls = Array.from(newUrls).filter(url => !oldUrls.has(url));

    // 处理新增的图片：没有imgId、有url、且未处理过、且不在保存中的图片
    // 批量处理所有新增的图片
    const imagesToSave = addedUrls
      .map(url => newImages.find((img: AlbumImage) => img.url === url))
      .filter((image): image is AlbumImage => {
        return (
          image !== undefined &&
          !image.imgId &&
          image.url !== undefined &&
          image.url !== null &&
          image.url !== "" &&
          !savingImages.value.has(image.url) &&
          !processedImages.value.has(image.url)
        );
      });

    // 并发保存所有新上传的图片
    for (const image of imagesToSave) {
      const imageUrl = image.url;
      if (imageUrl) {
        // 标记为已处理，防止重复处理
        processedImages.value.add(imageUrl);
        // 不等待，让所有图片并发上传
        saveImageToServer(imageUrl).catch(error => {
          console.error("保存图片失败:", error);
          // 保存失败时，从已处理集合中移除，允许重试
          processedImages.value.delete(imageUrl);
        });
      }
    }
  },
  { deep: true }
);

// 监听视频列表变化，更新分页并保存新上传的视频
watch(
  () => videoList.value || [],
  async (newVideos, oldVideos) => {
    // 如果不在视频 tab，不处理
    if (activeTab.value !== "video") {
      return;
    }

    updatePagination();

    // 如果正在加载视频（从服务器加载），跳过处理，避免重复保存
    if (isLoadingAlbumImages.value) {
      return;
    }

    // 找出真正新增的视频（通过对比URL）
    const oldUrls = new Set((oldVideos || []).map((video: AlbumVideo) => video.url).filter((url): url is string => Boolean(url)));
    const newUrls = new Set((newVideos || []).map((video: AlbumVideo) => video.url).filter((url): url is string => Boolean(url)));

    // 找出新增的URL（在新列表中存在，但在旧列表中不存在）
    const addedUrls = Array.from(newUrls).filter(url => !oldUrls.has(url));

    // 处理新增的视频：没有imgId、有url、且未处理过、且不在保存中的视频
    const videosToSave = addedUrls
      .map(url => newVideos.find((video: AlbumVideo) => video.url === url))
      .filter((video): video is AlbumVideo => {
        return (
          video !== undefined &&
          !video.imgId &&
          video.url !== undefined &&
          video.url !== null &&
          video.url !== "" &&
          !savingImages.value.has(video.url) &&
          !processedImages.value.has(video.url)
        );
      });

    // 并发保存所有新上传的视频
    for (const video of videosToSave) {
      const videoUrl = video.url;
      if (videoUrl) {
        // 如果视频还没有时长，尝试获取
        if (!video.videoDuration && video.raw) {
          try {
            const duration = await getVideoDuration(video.raw as File);
            if (duration > 0) {
              video.videoDuration = duration;
            }
          } catch (error) {
            console.error("获取视频时长失败:", error);
          }
        }

        // 标记为已处理，防止重复处理
        processedImages.value.add(videoUrl);
        // 不等待，让所有视频并发上传
        saveVideoToServer(videoUrl).catch(error => {
          console.error("保存视频失败:", error);
          // 保存失败时，从已处理集合中移除，允许重试
          processedImages.value.delete(videoUrl);
        });
      }
    }
  },
  { deep: true }
);

// 监听tab切换，加载对应的数据
watch(
  () => activeTab.value,
  async (newVal, oldVal) => {
    // 如果tab没有变化，不重复加载
    if (newVal === oldVal) {
      return;
    }
    // 重置分页到第一页
    pageable.pageNum = 1;

    // 根据tab类型加载数据
    if (newVal === "environment") {
      await loadEnvironmentImages();
    } else if (newVal === "video") {
      await loadVideoList();
    } else if (newVal) {
      // 相册tab
      await loadAlbumImages(newVal);
    }
    // 注意：updatePagination 在各自的 load 函数中已调用
  }
);

// 获取相册列表
const getAlbumList = async () => {
  try {
    const userInfo: any = localGet("geeker-user")?.userInfo || {};
    const storeId = userInfo.storeId;
    if (!storeId) {
      console.warn("未找到店铺ID");
      return;
    }

    const params = {
      storeId: Number(storeId)
    };
    const res: any = await getOfficialAlbumList(params);
    if (res && (res.code === 200 || res.code === "200") && res.data) {
      const dataList = Array.isArray(res.data) ? res.data : [];
      albumList.value = dataList.map((album: any) => ({
        id: album.id,
        name: album.albumName || album.name,
        albumName: album.albumName,
        images: reactive<AlbumImage[]>([]), // 使用 reactive 确保响应式
        videos: reactive<AlbumVideo[]>([]),
        coverImageId: album.coverImageId
      }));
      // 默认选中"环境"tab
      if (!activeTab.value || activeTab.value === "") {
        activeTab.value = "environment";
        await loadEnvironmentImages();
      }
    }
  } catch (error) {
    console.error("获取相册列表失败:", error);
  }
};

// 加载环境图片列表
const loadEnvironmentImages = async () => {
  try {
    isLoadingAlbumImages.value = true;
    const userInfo: any = localGet("geeker-user")?.userInfo || {};
    const storeId = userInfo.storeId;
    if (!storeId) {
      return;
    }

    // 环境图片：使用 storeId 作为 businessId（需要根据实际API调整）
    // 或者如果环境图片不需要 businessId，可能需要使用其他API
    // 这里先使用 storeId 作为 businessId
    const imageRes: any = await getOfficialImgList(Number(storeId), Number(storeId), 2);

    if (imageRes && (imageRes.code === 200 || imageRes.code === "200") && imageRes.data) {
      const imageList = Array.isArray(imageRes.data) ? imageRes.data : [];
      const images: AlbumImage[] = imageList
        .filter((img: any) => img.deleteFlag !== 1)
        .map((img: any) => ({
          uid: img.id || Date.now() + Math.random(),
          name: img.imgUrl?.split("/").pop() || "image",
          url: img.imgUrl,
          status: "success",
          imgId: img.id,
          businessId: img.businessId,
          imgSort: img.imgSort,
          imgType: img.imgType,
          isCover: false
        }))
        .sort((a: AlbumImage, b: AlbumImage) => (a.imgSort || 0) - (b.imgSort || 0));
      // 使用数组替换确保响应式更新
      environmentImages.value.splice(0, environmentImages.value.length, ...images);
    } else {
      environmentImages.value.splice(0, environmentImages.value.length);
    }

    processedImages.value.clear();
  } catch (error) {
    console.error("获取环境图片列表失败:", error);
    environmentImages.value.splice(0, environmentImages.value.length);
  } finally {
    isLoadingAlbumImages.value = false;
    await nextTick();
    updatePagination();
  }
};

// 加载视频列表
const loadVideoList = async () => {
  try {
    isLoadingAlbumImages.value = true;
    const userInfo: any = localGet("geeker-user")?.userInfo || {};
    const storeId = userInfo.storeId;
    if (!storeId) {
      return;
    }

    // 视频：使用 storeId 作为 businessId（需要根据实际API调整）
    // 或者如果视频不需要 businessId，可能需要使用其他API
    // 这里先使用 storeId 作为 businessId
    const videoRes: any = await getOfficialImgList(Number(storeId), Number(storeId), 3);

    if (videoRes && (videoRes.code === 200 || videoRes.code === "200") && videoRes.data) {
      const videoListData = Array.isArray(videoRes.data) ? videoRes.data : [];
      const videos: AlbumVideo[] = videoListData
        .filter((video: any) => video.deleteFlag !== 1)
        .map((video: any) => ({
          uid: video.id || Date.now() + Math.random(),
          name: video.imgUrl?.split("/").pop() || "video",
          url: video.imgUrl,
          status: "success",
          imgId: video.id,
          businessId: video.businessId,
          imgSort: video.imgSort,
          imgType: video.imgType,
          videoDuration: video.videoDuration || 0
        }))
        .sort((a: AlbumVideo, b: AlbumVideo) => (a.imgSort || 0) - (b.imgSort || 0));
      // 使用数组替换确保响应式更新
      videoList.value.splice(0, videoList.value.length, ...videos);
    } else {
      videoList.value.splice(0, videoList.value.length);
    }

    processedImages.value.clear();
  } catch (error) {
    console.error("获取视频列表失败:", error);
    videoList.value.splice(0, videoList.value.length);
  } finally {
    isLoadingAlbumImages.value = false;
    await nextTick();
    updatePagination();
  }
};

// 加载相册图片列表（相册只有图片，没有视频）
const loadAlbumImages = async (albumId: string) => {
  try {
    isLoadingAlbumImages.value = true;

    const userInfo: any = localGet("geeker-user")?.userInfo || {};
    const storeId = userInfo.storeId;
    if (!storeId || !albumId) {
      return;
    }

    // 加载图片（imgType = 2）
    const imageRes: any = await getOfficialImgList(Number(albumId), Number(storeId), 2);

    const current = albumList.value.find(album => String(album.id) === albumId);
    if (!current) {
      return;
    }

    // 处理图片列表
    if (imageRes && (imageRes.code === 200 || imageRes.code === "200") && imageRes.data) {
      const imageList = Array.isArray(imageRes.data) ? imageRes.data : [];
      const images: AlbumImage[] = imageList
        .filter((img: any) => img.deleteFlag !== 1)
        .map((img: any) => ({
          uid: img.id || Date.now() + Math.random(),
          name: img.imgUrl?.split("/").pop() || "image",
          url: img.imgUrl,
          status: "success",
          imgId: img.id,
          businessId: img.businessId,
          imgSort: img.imgSort,
          imgType: img.imgType,
          isCover: false
        }))
        .sort((a: AlbumImage, b: AlbumImage) => (a.imgSort || 0) - (b.imgSort || 0));
      // 使用 splice 方法替换数组内容，确保响应式更新
      if (!current.images) {
        current.images = reactive<AlbumImage[]>([]);
      }
      current.images.splice(0, current.images.length, ...images);
    } else {
      if (!current.images) {
        current.images = reactive<AlbumImage[]>([]);
      } else {
        current.images.splice(0, current.images.length);
      }
    }

    // 清空已处理图片集合，因为加载的是服务器数据，不需要再保存
    processedImages.value.clear();
  } catch (error) {
    console.error("获取相册图片列表失败:", error);
    const current = albumList.value.find(album => String(album.id) === albumId);
    if (current) {
      processedImages.value.clear();
      if (!current.images) {
        current.images = reactive<AlbumImage[]>([]);
      } else {
        current.images.splice(0, current.images.length);
      }
    }
  } finally {
    isLoadingAlbumImages.value = false;
    await nextTick();
    // 更新分页信息，确保视图刷新
    updatePagination();
  }
};

// 页面初始化
onMounted(async () => {
  await getAlbumList();
  // 默认加载环境图片
  if (activeTab.value === "environment") {
    await loadEnvironmentImages();
  }
});
</script>

<style scoped lang="scss">
.photo-album-container {
  position: relative;
  min-height: 100%;
  padding: 20px;
  background-color: white;
  .header-section {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 24px;
    :deep(.el-tabs) {
      flex: 1;
      .el-tabs__header {
        margin: 0;
      }
    }
    .header-actions {
      display: flex;
      gap: 12px;
      align-items: center;
    }
    .album-tab-label {
      display: inline-flex;
      gap: 8px;
      align-items: center;
      .edit-icon {
        font-size: 14px;
        color: #909399;
        cursor: pointer;
        transition: color 0.3s;
        &:hover {
          color: #409eff;
        }
      }
    }
  }
  .content-section {
    .upload-tips {
      display: flex;
      flex-wrap: wrap;
      gap: 16px;
      margin-bottom: 20px;
      font-size: 14px;
      color: #606266;
    }
    .media-grid {
      display: grid;
      grid-template-columns: repeat(5, 1fr);
      gap: 16px;
      margin-bottom: 20px;
      .upload-item {
        position: relative;
        width: 100%;
        min-height: 200px;

        // 只隐藏已上传的列表项，保留上传按钮
        :deep(.el-upload-list__item) {
          display: none !important;
        }

        // 确保上传按钮容器正常
        :deep(.upload-box) {
          display: block !important;
          width: 100% !important;
        }

        // 确保上传组件容器正常
        :deep(.upload) {
          display: block !important;
          width: 100% !important;
        }

        // 确保上传列表容器宽度正确
        :deep(.el-upload-list--picture-card) {
          display: block !important;
          width: 100% !important;
        }

        // 确保上传按钮正常显示和可点击，覆盖组件内部的固定宽度
        :deep(.el-upload--picture-card) {
          position: relative !important;
          box-sizing: border-box !important;
          display: inline-block !important;
          width: 100% !important;
          max-width: 100% !important;
          height: 200px !important;
          pointer-events: auto !important;
          cursor: pointer !important;
        }

        // 确保上传输入框覆盖整个按钮区域
        :deep(.el-upload--picture-card .el-upload__input) {
          position: absolute !important;
          top: 0 !important;
          left: 0 !important;
          z-index: 10 !important;
          width: 100% !important;
          height: 100% !important;
          cursor: pointer !important;
          opacity: 0 !important;
        }

        // 确保上传按钮内容不阻挡点击
        :deep(.el-upload--picture-card .upload-empty) {
          position: relative !important;
          z-index: 1 !important;
          pointer-events: none !important;
        }
      }
      .media-item {
        position: relative;
        min-height: 200px;
        .media-wrapper {
          position: relative;
          width: 100%;
          height: 200px;
          overflow: hidden;
          background-color: #f0f0f0;
          border-radius: 8px;
          img,
          .media-preview {
            width: 100%;
            height: 100%;
            object-fit: cover;
          }
          .media-placeholder {
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            width: 100%;
            height: 100%;
            color: #909399;
            .el-icon {
              margin-bottom: 8px;
              font-size: 48px;
            }
          }
          .media-overlay {
            position: absolute;
            inset: 0;
            display: flex;
            gap: 12px;
            align-items: center;
            justify-content: center;
            background-color: rgb(0 0 0 / 60%);
            opacity: 0;
            transition: opacity 0.3s;
            .el-button {
              color: white;
            }
          }
          &:hover .media-overlay {
            opacity: 1;
          }
          .cover-tag {
            position: absolute;
            top: 8px;
            right: 8px;
          }
        }
      }
    }
  }
  .empty-state {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 400px;
    .empty-text {
      font-size: 16px;
      color: #909399;
    }
  }
  .upload-tip-text {
    margin-top: 8px;
    font-size: 12px;
    color: #909399;
    text-align: center;
  }
  .dialog-footer {
    display: flex;
    gap: 12px;
    align-items: center;
    justify-content: space-between;
    .footer-left {
      display: flex;
      gap: 12px;
    }
    .footer-right {
      display: flex;
      gap: 12px;
    }
  }
}
.pagination-section {
  position: absolute;
  right: 40px;
  bottom: 20px;
  z-index: 1000;
  display: flex;
  justify-content: flex-end;
}

// 预览弹窗样式
:deep(.preview-dialog) {
  .el-dialog {
    max-width: 90vw;
    margin: 5vh auto;
  }
  .el-dialog__body {
    max-height: 80vh;
    padding: 20px;
    overflow: auto;
  }
  .preview-content {
    display: flex;
    align-items: center;
    justify-content: center;
    max-width: 100%;
    max-height: 70vh;
    overflow: hidden;
  }
  .preview-image {
    width: auto;
    max-width: 100%;
    height: auto;
    max-height: 70vh;
    object-fit: contain;
  }
  .preview-video {
    width: auto;
    max-width: 100%;
    height: auto;
    max-height: 70vh;
  }
}
</style>
