<template>
  <div
    class="book-reader"
    @touchstart="handleTouchStart"
    @touchend="handleTouchEnd"
  >
    <!-- <div v-if="loading" class="loading-overlay">
      <div class="loader"></div>
      <p>正在加载图片...</p>
    </div> -->

    <div class="magazine-viewport">
      <div ref="magazine" class="magazine">
        <div
          v-for="(page, index) in processedPages"
          :key="index"
          :class="[
            'page',
            `p${index + 1}`,
            {
              hard: !page.isWide && index % 2 === 0,
              odd: !page.isWide && index % 2 !== 0,
              even: !page.isWide && index % 2 === 1,
              mobile: isMobile,
            },
          ]"
        >
          <img
            :data-page-index="index"
            :src="page.src"
            :alt="`第 ${page.page_num} 页`"
            @error="handleImageError(index)"
            :class="['page-image', { 'wide-image': page.isWide }]"
          />

          <!-- 添加小图叠加层 -->
          <div
            v-if="page.images && page.images.length > 0"
            class="small-images-overlay"
          >
            <div
              v-for="(smallImage, imgIndex) in page.images"
              :key="imgIndex"
              class="small-image-container"
              :style="{
                left: `${smallImage.position.x1 * 100}%`,
                top: `${smallImage.position.y1 * 100}%`,
                width: `${
                  (smallImage.position.x2 - smallImage.position.x1) * 100
                }%`,
                height: `${
                  (smallImage.position.y2 - smallImage.position.y1) * 100
                }%`,
              }"
              @click="handleSmallImageClick(smallImage, page.page_num)"
            >
              <!-- <img :src="smallImage.url" :alt="`小图 ${imgIndex + 1}`" class="small-image" /> -->
            </div>
          </div>
        </div>
      </div>
    </div>

    <div class="controls" :class="{ 'mobile-controls': isMobile }">
      <el-button class="control-button" @click="previous" circle>
        <el-icon>
          <ArrowLeft />
        </el-icon>
      </el-button>
      <el-button class="control-button" @click="next" circle>
        <el-icon>
          <ArrowRight />
        </el-icon>
      </el-button>
      <el-button class="control-button" @click="zoomIn" circle>
        <el-icon>
          <ZoomIn />
        </el-icon>
      </el-button>
      <el-button class="control-button" @click="zoomOut" circle>
        <el-icon>
          <ZoomOut />
        </el-icon>
      </el-button>
      <el-button class="control-button" @click="showGuide" circle>
        <el-icon>
          <Menu />
        </el-icon>
      </el-button>
    </div>

    <div v-if="showExitMessage" class="exit-message">按 ESC 键退出阅读</div>

    <!-- 替换为 vue-easy-lightbox 预览组件 -->
    <vue-easy-lightbox
      :visible="showViewer"
      :imgs="previewImages"
      :index="currentImageIndex"
      @hide="showViewer = false"
    />

    <div class="mobile-gesture-hint" v-if="isMobile">左右滑动切换页面</div>

    <!-- Replace directory modal with Element Plus dialog -->
    <Guide ref="guideRef" :bookmarks="bookmarks" @goToPage="goToPage"></Guide>
  </div>
</template>

<script setup>
import $ from "jquery";
import "turn.js";
import { ref, onMounted, onUnmounted, watch, nextTick, computed } from "vue";
import {
  ArrowLeft,
  ArrowRight,
  ZoomIn,
  ZoomOut,
  Menu,
} from "@element-plus/icons-vue";
import VueEasyLightbox from "vue-easy-lightbox";
import Guide from "./Guide.vue";

const props = defineProps({
  pages: {
    type: Array,
    default: () => [],
    required: true,
  },
  bookmarks: {
    type: Array,
    default: () => [],
  },
});

const magazine = ref(null);
const loading = ref(true);
const showExitMessage = ref(false);
const zoomLevel = ref(1);
const isInitialized = ref(false);
const imageMetadata = ref([]);
const imageObserver = ref(null);
const loadingQueue = ref(new Set());
const maxConcurrentLoads = 5;
const imageCache = ref(new Map());
const loadingTimeouts = ref(new Map());
const isMobile = ref(false);
const touchStartX = ref(0);
const touchStartY = ref(0);

// 修改预览相关的状态
const showViewer = ref(false);
const currentImageIndex = ref(0);
const previewImages = ref([]);

// 将 processedPages 改为普通数据属性
const processedPages = ref([]);

// Add new refs for sound and directory
const pageTurnSound = ref(null);
const directoryImages = ref([]);
const guideRef = ref(null);

const currentPage = ref(0);

// 检测是否为移动设备
const checkMobile = () => {
  isMobile.value =
    /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(
      navigator.userAgent
    );
};

// 处理触摸事件
const handleTouchStart = (e) => {
  if (!isMobile.value) return;
  touchStartX.value = e.touches[0].clientX;
  touchStartY.value = e.touches[0].clientY;
};

const handleTouchEnd = (e) => {
  if (!isMobile.value) return;
  const touchEndX = e.changedTouches[0].clientX;
  const touchEndY = e.changedTouches[0].clientY;
  const deltaX = touchEndX - touchStartX.value;
  const deltaY = touchEndY - touchStartY.value;

  // 如果水平滑动距离大于垂直滑动距离，且大于50px，则触发翻页
  if (Math.abs(deltaX) > Math.abs(deltaY) && Math.abs(deltaX) > 50) {
    if (deltaX > 0) {
      previous();
    } else {
      next();
    }
  }
};

// 修改处理页面的函数，只处理必要的属性
const processPages = (pages) => {
  return pages.map((item, index) => ({
    src: "", // 初始不设置src
    originalIndex: index,
    page_num: item.page_num,
    images: item.images || [],
    isWide: false, // 初始设置为false
    isLoaded: false,
    url: item.page_url, // 保存原始URL
  }));
};

// 修改图片加载函数
const loadImage = async (pageIndex) => {
  const page = processedPages.value[pageIndex];
  if (!page || page.isLoaded) return true;

  const src = page.url;
  if (imageCache.value.has(src)) {
    page.isLoaded = true;
    page.src = src;
    return true;
  }

  if (loadingQueue.value.size >= maxConcurrentLoads) {
    await new Promise((resolve) => setTimeout(resolve, 50));
    return loadImage(pageIndex);
  }

  loadingQueue.value.add(pageIndex);
  const timeoutId = setTimeout(() => {
    loadingQueue.value.delete(pageIndex);
    loadingTimeouts.value.delete(pageIndex);
  }, 5000);
  loadingTimeouts.value.set(pageIndex, timeoutId);

  try {
    const img = new Image();
    await new Promise((resolve, reject) => {
      img.onload = () => {
        clearTimeout(timeoutId);
        loadingTimeouts.value.delete(pageIndex);
        imageCache.value.set(src, true);
        page.isLoaded = true;
        page.src = src;
        resolve();
      };
      img.onerror = () => {
        clearTimeout(timeoutId);
        loadingTimeouts.value.delete(pageIndex);
        reject(new Error("Image load failed"));
      };
      img.src = src;
    });
    return true;
  } catch (error) {
    return false;
  } finally {
    loadingQueue.value.delete(pageIndex);
  }
};

// 修改加载可见页面的函数
const loadVisiblePages = async (currentPage) => {
  if (!magazine.value) return;

  const $magazine = $(magazine.value);
  const totalPages = $magazine.turn("pages");

  // 只加载当前页和下一页
  const startPage = currentPage;
  const endPage = Math.min(totalPages, currentPage + 1);

  const loadTasks = [];
  for (let i = startPage; i <= endPage; i++) {
    const pageIndex = i - 1;
    if (
      pageIndex >= 0 &&
      pageIndex < processedPages.value.length &&
      !processedPages.value[pageIndex].isLoaded
    ) {
      loadTasks.push(loadImage(pageIndex));
    }
  }

  try {
    await Promise.all(loadTasks);
  } catch (error) {
    console.error("加载页面失败:", error);
  }
};

// 修改初始化函数
const initBook = async () => {
  if (!magazine.value || !processedPages.value.length) return;

  destroyTurn();
  checkMobile();

  const viewportWidth = window.innerWidth;
  const viewportHeight = window.innerHeight;

  // 移动端使用不同的尺寸计算
  let pageWidth, pageHeight;
  if (isMobile.value) {
    // 移动端：宽度等于设备宽度减去边距
    pageWidth = viewportWidth - 20; // 左右各留10px边距
    // 高度按比例计算（假设标准比例为 4:3）
    pageHeight = (pageWidth * 4) / 3;
    // 确保高度不超过视口高度
    if (pageHeight > viewportHeight - 100) {
      // 上下各留50px边距
      pageHeight = viewportHeight - 100;
      // 重新计算宽度以保持比例
      pageWidth = (pageHeight * 3) / 4;
    }
  } else {
    // 桌面端保持原有逻辑
    pageWidth = Math.min(600, viewportWidth / 2 - 50);
    pageHeight = Math.min(800, viewportHeight - 100);
  }

  await nextTick();

  try {
    const $magazine = $(magazine.value);
    const $viewport = $(".magazine-viewport");

    $viewport.css({
      overflow: "hidden",
      position: "relative",
      width: "100%",
      height: "100%",
    });

    $magazine.children().each(function () {
      const $page = $(this);
      $page.css({
        position: "absolute",
        overflow: "hidden",
        width: pageWidth,
        height: pageHeight,
      });

      const $img = $page.find("img");
      if ($img.length) {
        $img.css({
          width: "100%",
          height: "100%",
          objectFit: "contain",
        });
      }
    });

    // 移动端使用单页显示
    $magazine.turn({
      width: isMobile.value ? pageWidth : pageWidth * 2,
      height: pageHeight,
      display: isMobile.value ? "single" : "double",
      acceleration: false,
      gradients: true,
      elevation: 50,
      duration: 800,
      autoCenter: true,
      page: 1,
      when: {
        turning: async (event, page, view) => {
          loading.value = true;
          await loadVisiblePages(page);
        },
        turned: async (event, page, view) => {
          currentPage.value = page; // 更新当前页码
          await loadVisiblePages(page);
          loading.value = false;
        },
      },
    });

    isInitialized.value = true;
    await loadVisiblePages(1);
  } catch (error) {
    console.error("Turn.js initialization error:", error);
  }
};
// 修改加载图片函数
const loadImages = async () => {
  loading.value = true;
  try {
    await initBook();
  } catch (error) {
    console.error("加载图片失败:", error);
  } finally {
    loading.value = false;
  }
};

// 监听 props.pages 的变化
watch(
  () => props.pages,
  (newPages) => {
    if (newPages && newPages.length > 0) {
      processedPages.value = processPages(newPages);
      loadImages();
    }
  },
  { immediate: true }
);

const checkImageDimensions = async (src) => {
  return new Promise((resolve) => {
    const img = new Image();
    img.onload = () => {
      // 如果宽高比大于 1.8，认为是宽图
      const isWide = img.width / img.height > 1.8;
      resolve({
        width: img.width,
        height: img.height,
        isWide,
      });
    };
    img.onerror = () => {
      resolve({ width: 0, height: 0, isWide: false });
    };
    img.src = src;
  });
};

const destroyTurn = () => {
  if (magazine.value && isInitialized.value) {
    try {
      const $magazine = $(magazine.value);
      // 移除所有 turn.js 相关的事件和数据
      $magazine.off(".turn");
      $magazine.removeData("turn");
      isInitialized.value = false;
    } catch (error) {
      console.error("Error destroying turn.js:", error);
    }
  }
};

// 初始化 Intersection Observer
const initImageObserver = () => {
  imageObserver.value = new IntersectionObserver(
    (entries) => {
      entries.forEach((entry) => {
        if (entry.isIntersecting) {
          const img = entry.target;
          const pageIndex = parseInt(img.dataset.pageIndex);
          if (!processedPages.value[pageIndex].isLoaded) {
            img.src = processedPages.value[pageIndex].src;
            processedPages.value[pageIndex].isLoaded = true;
          }
        }
      });
    },
    {
      root: null,
      rootMargin: "50px",
      threshold: 0.1,
    }
  );
};

// 修改图片错误处理函数
const handleImageError = async (index) => {
  const src = processedPages.value[index].src;

  // 清除超时
  if (loadingTimeouts.value.has(index)) {
    clearTimeout(loadingTimeouts.value.get(index));
    loadingTimeouts.value.delete(index);
  }

  // 尝试重新加载
  const retryCount = 3;
  for (let i = 0; i < retryCount; i++) {
    try {
      const success = await loadImage(index);
      if (success) {
        return;
      }
    } catch (error) {
      // 忽略错误
    }
    // 递增重试延迟
    const delay = 1000 * (i + 1);
    await new Promise((resolve) => setTimeout(resolve, delay));
  }

  // 如果所有重试都失败，使用占位图
  const $img = $(magazine.value).find(`.p${index + 1} img`);
  if ($img.length) {
    $img[0].src =
      "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAwIiBoZWlnaHQ9IjIwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cmVjdCB3aWR0aD0iMjAwIiBoZWlnaHQ9IjIwMCIgZmlsbD0iI2YwZjBmMCIvPjx0ZXh0IHg9IjUwJSIgeT0iNTAlIiBmb250LWZhbWlseT0iQXJpYWwiIGZvbnQtc2l6ZT0iMTYiIGZpbGw9IiM5OTkiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGR5PSIuM2VtIj7lvIDlp4vmlbDmja7lupM8L3RleHQ+PC9zdmc+";
  }
};

const next = () => {
  if (magazine.value && isInitialized.value) {
    const $magazine = $(magazine.value);
    const currentPage = $magazine.turn("page");
    const nextPage = currentPage + 1;

    // 预加载下一页
    loadVisiblePages(nextPage);

    // 延迟执行翻页，确保图片已加载
    setTimeout(() => {
      $magazine.turn("next", { duration: 1500 });
      playPageTurnSound();
    }, 100);
  }
};

const previous = () => {
  if (magazine.value && isInitialized.value) {
    const $magazine = $(magazine.value);
    const currentPage = $magazine.turn("page");
    const prevPage = currentPage - 1;

    // 预加载上一页
    loadVisiblePages(prevPage);

    // 延迟执行翻页，确保图片已加载
    setTimeout(() => {
      $magazine.turn("previous", { duration: 1500 });
      playPageTurnSound();
    }, 100);
  }
};

const zoomIn = () => {
  zoomLevel.value = Math.min(zoomLevel.value + 0.2, 2);
  updateZoom();
};

const zoomOut = () => {
  zoomLevel.value = Math.max(zoomLevel.value - 0.2, 0.5);
  updateZoom();
};

const updateZoom = () => {
  if (magazine.value && isInitialized.value) {
    const $magazine = $(magazine.value);
    const currentPage = $magazine.turn("page");

    // 保存当前可见页面的图片状态
    const visiblePages = [];
    const totalPages = $magazine.turn("pages");
    const startPage = Math.max(1, currentPage - 2);
    const endPage = Math.min(totalPages, currentPage + 2);

    for (let i = startPage; i <= endPage; i++) {
      const $page = $magazine.find(`.p${i}`);
      const $img = $page.find("img");
      if ($img.length) {
        visiblePages.push({
          page: i,
          src: $img[0].src,
          isLoaded: $img[0].complete,
        });
      }
    }

    // 计算新的尺寸
    const viewportWidth = window.innerWidth;
    const viewportHeight = window.innerHeight;
    const baseWidth = Math.min(600, viewportWidth / 2 - 50);
    const baseHeight = Math.min(800, viewportHeight - 100);

    // 应用缩放
    const scaledWidth = baseWidth * zoomLevel.value;
    const scaledHeight = baseHeight * zoomLevel.value;

    // 直接更新 turn.js 尺寸
    $magazine.turn("size", scaledWidth * 2, scaledHeight);

    // 更新页面尺寸
    $magazine.children().each(function () {
      const $page = $(this);
      $page.css({
        width: scaledWidth,
        height: scaledHeight,
      });
    });

    // 恢复已加载的图片
    visiblePages.forEach((page) => {
      const $page = $magazine.find(`.p${page.page}`);
      const $img = $page.find("img");
      if ($img.length && page.isLoaded) {
        $img[0].src = page.src;
      }
    });

    // 更新视口样式
    const $viewport = $(".magazine-viewport");
    $viewport.css({
      width: "100%",
      height: "100%",
      overflow: "auto",
    });
  }
};

const handleKeyDown = (e) => {
  switch (e.key) {
    case "ArrowRight":
      next();
      break;
    case "ArrowLeft":
      previous();
      break;
    case "Escape":
      showExitMessage.value = true;
      setTimeout(() => {
        showExitMessage.value = false;
      }, 2000);
      break;
  }
};

const handleResize = async () => {
  if (magazine.value && isInitialized.value) {
    try {
      const $magazine = $(magazine.value);
      const currentPage = $magazine.turn("page");
      const currentZoom = zoomLevel.value;

      // 保存当前可见页面的图片状态
      const visiblePages = [];
      const totalPages = $magazine.turn("pages");
      const startPage = Math.max(1, currentPage - 2);
      const endPage = Math.min(totalPages, currentPage + 2);

      for (let i = startPage; i <= endPage; i++) {
        const $page = $magazine.find(`.p${i}`);
        const $img = $page.find("img");
        if ($img.length) {
          visiblePages.push({
            page: i,
            src: $img[0].src,
            isLoaded: $img[0].complete,
          });
        }
      }

      // 计算新的尺寸
      const viewportWidth = window.innerWidth;
      const viewportHeight = window.innerHeight;
      const baseWidth = Math.min(600, viewportWidth / 2 - 50);
      const baseHeight = Math.min(800, viewportHeight - 100);

      // 应用缩放
      const scaledWidth = baseWidth * currentZoom;
      const scaledHeight = baseHeight * currentZoom;

      // 直接更新 turn.js 尺寸
      $magazine.turn("size", scaledWidth * 2, scaledHeight);

      // 更新页面尺寸
      $magazine.children().each(function () {
        const $page = $(this);
        $page.css({
          width: scaledWidth,
          height: scaledHeight,
        });
      });

      // 恢复已加载的图片
      visiblePages.forEach((page) => {
        const $page = $magazine.find(`.p${page.page}`);
        const $img = $page.find("img");
        if ($img.length && page.isLoaded) {
          $img[0].src = page.src;
        }
      });

      // 更新视口样式
      const $viewport = $(".magazine-viewport");
      $viewport.css({
        width: "100%",
        height: "100%",
        overflow: "auto",
      });
    } catch (error) {
      console.error("Error handling resize:", error);
    }
  }
};

// 添加防抖处理
let resizeTimeout;
window.addEventListener("resize", () => {
  clearTimeout(resizeTimeout);
  resizeTimeout = setTimeout(() => {
    handleResize();
  }, 250);
});

onMounted(async () => {
  await loadImages();
  window.addEventListener("keydown", handleKeyDown);
  window.addEventListener("resize", handleResize);

  // Initialize page turn sound
  pageTurnSound.value = new Audio("/src/assets/sounds/page-turn.mp3");
  pageTurnSound.value.load();

  // Load directory images
  loadDirectoryImages();
});

onUnmounted(() => {
  // 清除所有超时
  loadingTimeouts.value.forEach((timeoutId) => clearTimeout(timeoutId));
  loadingTimeouts.value.clear();
  imageCache.value.clear();
  loadingQueue.value.clear();

  if (imageObserver.value) {
    imageObserver.value.disconnect();
  }
  destroyTurn();
  window.removeEventListener("keydown", handleKeyDown);
  window.removeEventListener("resize", handleResize);
});

// 修改小图点击事件处理函数
const handleSmallImageClick = (smallImage, pageNum) => {
  // 获取当前页面所有小图的URL
  const currentPage = props.pages.find((page) => page.page_num === pageNum);
  if (currentPage && currentPage.images) {
    previewImages.value = currentPage.images.map((img) => ({
      src: img.url,
      title: `第 ${pageNum} 页`,
    }));

    // 设置当前点击的图片索引
    currentImageIndex.value = currentPage.images.findIndex(
      (img) => img.url === smallImage.url
    );

    // 显示预览组件
    showViewer.value = true;
  }
};

// Add new methods for sound and directory
const playPageTurnSound = () => {
  if (pageTurnSound.value) {
    pageTurnSound.value.currentTime = 0;
    pageTurnSound.value
      .play()
      .catch((e) => console.log("Audio play failed:", e));
  }
};

const generateThumbnailUrl = (url) => {
  return url.replace(/(\.[^.]+)$/, "_low$1");
};

const loadDirectoryImages = () => {
  directoryImages.value = props.pages.map((page) => ({
    src: generateThumbnailUrl(page.page_url),
    pageNum: page.page_num,
  }));
};

const goToPage = (pageNum) => {
  if (magazine.value && isInitialized.value) {
    const $magazine = $(magazine.value);
    $magazine.turn("page", pageNum);
  }
};

const showGuide = () => {
  guideRef.value.show();
};
</script>

<style scoped>
.book-reader {
  width: 100vw;
  height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
  background-color: #333;
  position: relative;
  background-image: url("../assets/images/2.jpg");
  background-size: 100% 100%;
  touch-action: pan-y pinch-zoom;
}

.magazine-viewport {
  width: 100%;
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  position: relative;
  overflow: hidden !important;
  -webkit-overflow-scrolling: touch;
}

.magazine {
  position: relative;
  transform-origin: center center;
  background-color: #fff;
  box-shadow: 0 0 20px rgba(0, 0, 0, 0.2);
  will-change: transform;
  visibility: visible !important;
  backface-visibility: hidden;
  transform-style: preserve-3d;
}

.magazine::after {
  content: "";
  position: absolute;
  top: 0;
  left: 50%;
  width: 1px;
  height: 100%;
  background: linear-gradient(
    to bottom,
    rgba(0, 0, 0, 0.1) 0%,
    rgba(0, 0, 0, 0.2) 50%,
    rgba(0, 0, 0, 0.1) 100%
  );
  z-index: 10;
  pointer-events: none;
}

.page {
  background-color: white;
  position: absolute;
  width: 100%;
  height: 100%;
  overflow: hidden;
  user-select: none;
  visibility: visible !important;
  backface-visibility: hidden;
  transform-style: preserve-3d;
  transform: translate3d(0, 0, 0);
  box-shadow: inset 0 0 20px rgba(0, 0, 0, 0.05);
}

.page:before {
  content: "";
  position: absolute;
  width: 100px;
  height: 100px;
  bottom: 0;
  z-index: 10;
}

.page.odd:before {
  right: 0;
  background: linear-gradient(315deg, rgba(0, 0, 0, 0.1) 0%, transparent 50%);
}

.page.even:before {
  left: 0;
  background: linear-gradient(45deg, rgba(0, 0, 0, 0.1) 0%, transparent 50%);
}

.page-image {
  width: 100%;
  height: 100%;
  object-fit: contain;
  pointer-events: none;
  visibility: visible !important;
  backface-visibility: hidden;
  transform-style: preserve-3d;
  transform: translate3d(0, 0, 0);
}

.controls {
  position: fixed;
  bottom: 20px;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  gap: 15px;
  z-index: 1000;
  background: rgba(255, 255, 255, 0.8);
  padding: 8px 15px;
  border-radius: 15px;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);
}

.control-button {
  width: 35px;
  height: 35px;
  border: none;
  background-color: rgba(255, 255, 255, 0.7);
  border-radius: 50%;
  cursor: pointer;
  display: flex;
  justify-content: center;
  align-items: center;
  transition: all 0.3s ease;
  box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
  color: #333;
}

.control-button:hover {
  background-color: rgba(255, 255, 255, 0.9);
  transform: translateY(-2px);
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);
}

.control-button::before {
  display: none;
}

.control-button svg {
  width: 20px;
  height: 20px;
}

.loading-overlay {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: rgba(0, 0, 0, 0.7);
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  color: white;
  z-index: 1000;
}

.loader {
  border: 4px solid #f3f3f3;
  border-top: 4px solid #3498db;
  border-radius: 50%;
  width: 40px;
  height: 40px;
  animation: spin 1s linear infinite;
  margin-bottom: 1rem;
}

@keyframes spin {
  0% {
    transform: rotate(0deg);
  }

  100% {
    transform: rotate(360deg);
  }
}

.exit-message {
  position: fixed;
  top: 20px;
  left: 50%;
  transform: translateX(-50%);
  background: rgba(0, 0, 0, 0.5);
  color: white;
  padding: 10px 20px;
  border-radius: 4px;
  z-index: 1000;
}

.page.wide-page {
  width: 200% !important;
  left: 0 !important;
  z-index: 5 !important;
}

.page.wide-page.isHidden {
  display: none !important;
}

.wide-image {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

/* 确保宽图页面的阴影效果 */
.page.wide-page::after {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  box-shadow: inset 0 0 30px rgba(0, 0, 0, 0.1);
  pointer-events: none;
  z-index: 1;
}

/* 角落悬停效果 */
.page.hover::before {
  content: "";
  position: absolute;
  width: 100px;
  height: 100px;
  pointer-events: none;
  z-index: 10;
  transition: all 0.3s ease;
}

.page.hover:nth-child(odd)::before {
  right: 0;
  bottom: 0;
  background: linear-gradient(315deg, rgba(0, 0, 0, 0.2) 0%, transparent 80%);
}

.page.hover:nth-child(even)::before {
  left: 0;
  bottom: 0;
  background: linear-gradient(45deg, rgba(0, 0, 0, 0.2) 0%, transparent 80%);
}

/* 缩放状态样式 */
.magazine.zoomed {
  cursor: move;
}

.magazine.zoomed .page {
  pointer-events: none;
}

/* 确保 turn.js 不会修改视口样式 */
.magazine-viewport.turn-page-wrapper {
  overflow: hidden !important;
}

.magazine-viewport.turn-page-wrapper .turn-page {
  overflow: hidden !important;
}

.small-images-overlay {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  /* 允许点击穿透到下层 */
}

.small-image-container {
  position: absolute;
  cursor: pointer;
  pointer-events: auto;
  transition: all 0.3s ease;
  border: 2px solid transparent;
}

.small-image-container:hover {
  border-color: rgba(255, 255, 255, 0.5);
  box-shadow: 0 0 10px rgba(255, 255, 255, 0.3);
}

.small-image {
  width: 100%;
  height: 100%;
  object-fit: contain;
  pointer-events: none;
  /* 防止图片本身接收点击事件 */
}

.debug-info {
  position: absolute;
  top: 0;
  left: 0;
  background: rgba(0, 0, 0, 0.7);
  color: white;
  padding: 2px 4px;
  font-size: 10px;
  pointer-events: none;
  z-index: 1000;
}

/* 添加预览组件样式 */
:deep(.vel-modal) {
  background-color: rgba(0, 0, 0, 0.9);
}

:deep(.vel-img) {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
}

:deep(.vel-btn) {
  color: #fff;
  background-color: rgba(0, 0, 0, 0.5);
  border-radius: 50%;
  width: 40px;
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.3s ease;
}

:deep(.vel-btn:hover) {
  background-color: rgba(0, 0, 0, 0.7);
}

:deep(.vel-title) {
  color: #fff;
  background-color: rgba(0, 0, 0, 0.5);
  padding: 8px 16px;
  border-radius: 4px;
}

.mobile-gesture-hint {
  position: fixed;
  top: 20px;
  left: 50%;
  transform: translateX(-50%);
  background: rgba(0, 0, 0, 0.7);
  color: white;
  padding: 8px 16px;
  border-radius: 20px;
  font-size: 14px;
  z-index: 1000;
  opacity: 0;
  transition: opacity 0.3s ease;
}

.mobile-gesture-hint.show {
  opacity: 1;
}

@media (max-width: 768px) {
  .controls {
    bottom: 10px;
    padding: 6px 14px;
    gap: 10px;
  }

  .control-button {
    width: 30px;
    height: 30px;
  }

  .control-button svg {
    width: 18px;
    height: 18px;
  }

  .magazine {
    transform: translateZ(0);
    -webkit-transform: translateZ(0);
    width: 100% !important;
    max-width: 100vw;
  }

  .page {
    transform: translateZ(0);
    -webkit-transform: translateZ(0);
    width: 100% !important;
  }

  .page-image {
    transform: translateZ(0);
    -webkit-transform: translateZ(0);
    width: 100% !important;
    height: 100% !important;
    object-fit: contain;
  }
}

/* Update mobile controls styles */
.mobile-controls {
  position: fixed;
  bottom: 0;
  /* left: 0; */
  right: 0;
  display: flex;
  justify-content: space-around;
  align-items: center;
  background: rgba(255, 255, 255, 0.95);
  padding: 15px 0;
  z-index: 1000;
  box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.1);
  width: 100vw;
}

.mobile-controls .control-button {
  width: 60px;
  height: 60px;
  margin: 0;
  padding: 0;
  display: flex;
  justify-content: center;
  align-items: center;
  background-color: rgba(255, 255, 255, 0.9);
  border: none;
  box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
  font-size: 24px;
  /* 增大字体大小 */
}

.mobile-controls .el-icon {
  font-size: 32px;
  color: #333;
}

.mobile-controls .control-button:hover {
  background-color: rgba(255, 255, 255, 1);
  transform: translateY(-2px);
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);
}

/* Update directory dialog styles */
.directory-dialog :deep(.el-dialog__body) {
  padding: 20px;
}

.directory-dialog :deep(.el-dialog) {
  margin-top: 5vh !important;
  max-height: 90vh;
}

.directory-dialog :deep(.el-dialog__header) {
  margin-right: 0;
  padding: 20px;
}

.directory-dialog :deep(.el-dialog__title) {
  font-size: 18px;
  font-weight: 600;
}

.page-number {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  background: rgba(0, 0, 0, 0.7);
  color: white;
  text-align: center;
  padding: 4px 0;
  font-size: 14px;
}

/* Media query for mobile */
@media (max-width: 768px) {
  .controls:not(.mobile-controls) {
    display: none;
  }

  .mobile-controls {
    display: flex;
  }

  .thumbnail-grid {
    grid-template-columns: repeat(auto-fill, minmax(20vw, 1fr)) !important;
  }
}
</style>
