<template>
  <div class="slides-viewer">
    <!-- 幻灯片展示 -->
    <div class="slide-container" @click="handleContainerClick">
      <!-- 图片展示 -->
      <img
        v-if="pages.length > 0 && currentSlideType === 'image'"
        :src="pages[currentPage]"
        :key="currentPage"
        class="slide-image"
        :style="{ opacity: isLoading ? 0 : 1, transition: 'opacity 0.3s' }"
        @load="onImageLoad"
        @error="onImageError"
        alt="幻灯片"
      />

      <!-- PDF展示 - 使用PDF.js组件 -->
      <PdfViewer
        v-else-if="pages.length > 0 && (currentSlideType === 'pdf' || currentSlideType === 'pdf-fallback')"
        :url="pages[currentPage]"
        :current-page="currentPage"
        @page-change="handlePdfPageChange"
        @pdfLoaded="onPdfLoad"
      />

      <!-- PPT/PPTX展示 - 无法嵌入，提供下载 -->
      <div v-else-if="pages.length > 0 && currentSlideType === 'ppt'" class="ppt-container">
        <div class="ppt-preview">
          <Presentation :size="80" stroke-width="1" />
          <p class="ppt-title">{{ currentFileName }}</p>
          <p class="ppt-hint">PowerPoint 文件无法在浏览器中直接预览</p>
          <div class="ppt-actions">
            <a :href="pages[currentPage]" target="_blank" class="ppt-btn primary">
              <ExternalLink :size="20" />
              新窗口打开
            </a>
            <a :href="pages[currentPage]" download class="ppt-btn">
              <Download :size="20" />
              下载文件
            </a>
          </div>
          <p class="ppt-tip">提示：建议将 PPT 转换为 PDF 格式后上传，以便在线预览</p>
        </div>
      </div>

      <!-- 空状态 -->
      <div v-if="pages.length === 0 || showError" class="no-slides">
        <Presentation :size="80" stroke-width="1" />
        <p>{{ showError ? '资源加载失败' : '暂无幻灯片内容' }}</p>
        <p v-if="showError && pages[currentPage]" class="error-url">{{ pages[currentPage] }}</p>
      </div>

      <!-- 加载中 - 不在PDF时显示，因为PdfViewer有自己的loading overlay -->
      <div v-if="isLoading && pages.length > 0 && currentSlideType !== 'pdf' && currentSlideType !== 'pdf-fallback'" class="loading-overlay">
        <div class="loading-spinner"></div>
        <p class="loading-text">正在加载{{ currentSlideType === 'ppt' ? 'PPT' : '内容' }}...</p>
      </div>

      <!-- 左右翻页提示 -->
      <div class="page-hint left" v-if="currentPage > 0 && !isLoading">
        <ChevronLeft :size="32" />
      </div>
      <div class="page-hint right" v-if="currentPage < pages.length - 1 && !isLoading">
        <ChevronRight :size="32" />
      </div>
    </div>

    <!-- 页码控制 - 只在非PDF类型且有多个文件时显示 -->
    <!-- PDF类型使用PdfViewer内部的翻页控件 -->
    <div class="page-controls" v-if="pages.length > 1 && currentSlideType !== 'pdf' && currentSlideType !== 'pdf-fallback'">
      <div class="page-btn prev" @click="prevPage" :class="{ disabled: currentPage === 0 }">
        <ChevronLeft :size="24" />
      </div>

      <div class="page-dots">
        <span
          v-for="(_, index) in pages"
          :key="index"
          class="dot"
          :class="{ active: currentPage === index }"
          @click="goToPage(index)"
        ></span>
      </div>

      <div class="page-btn next" @click="nextPage" :class="{ disabled: currentPage >= pages.length - 1 }">
        <ChevronRight :size="24" />
      </div>
    </div>

    <!-- 页码显示 -->
    <div class="page-info" v-if="pages.length > 0">
      {{ currentPage + 1 }} / {{ pages.length }}
    </div>

    <!-- PPT工具栏 -->
    <div class="pdf-toolbar" v-if="currentSlideType === 'ppt'">
      <a :href="pages[currentPage]" target="_blank" class="toolbar-btn" title="新窗口打开">
        <ExternalLink :size="18" />
      </a>
      <a :href="pages[currentPage]" download class="toolbar-btn" title="下载">
        <Download :size="18" />
      </a>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, watch, onMounted, onUnmounted } from 'vue';
import {
  ChevronLeft,
  ChevronRight,
  Presentation,
  Download,
  ExternalLink,
} from 'lucide-vue-next';
import PdfViewer from './PdfViewer.vue';

interface Props {
  pages: string[];
  currentPage: number;
  type: 'ppt' | 'poster' | 'pdf';
}

const props = withDefaults(defineProps<Props>(), {
  pages: () => [],
  currentPage: 0,
  type: 'ppt',
});

const emit = defineEmits<{
  (e: 'pageChange', page: number): void;
  (e: 'load', totalPages: number): void;
}>();

// 状态
const currentPage = ref(props.currentPage);
const isLoading = ref(true);
const showError = ref(false);

// 计算属性
const currentSlideType = computed(() => {
  if (props.pages.length === 0) return 'image';
  const url = props.pages[currentPage.value] || '';

  // 检查是否是PDF
  if (url.toLowerCase().includes('.pdf')) {
    // 检测浏览器是否支持PDF嵌入
    const mimeTypes = navigator.mimeTypes as MimeTypeArray | undefined;
    const supportsPdfEmbed = mimeTypes && mimeTypes.namedItem('application/pdf') !== null;
    return supportsPdfEmbed ? 'pdf' : 'pdf-fallback';
  }

  // 检查是否是PPT/PPTX - 无法在浏览器中直接显示
  if (url.toLowerCase().match(/\.pptx?$/)) {
    return 'ppt';
  }

  return 'image';
});

// 当前文件名
const currentFileName = computed(() => {
  const url = props.pages[currentPage.value] || '';
  if (!url) return '';
  const parts = url.split('/');
  return parts[parts.length - 1] || url;
});

// 方法
const onImageLoad = () => {
  isLoading.value = false;
  showError.value = false;
};

const onImageError = () => {
  isLoading.value = false;
  showError.value = true;
};

const onPdfLoad = (totalPages: number) => {
  console.log('[SlidesViewer] onPdfLoad 被调用, 总页数:', totalPages);
  // PDF加载完成后，不需要再显示SlidesViewer的loading状态
  // 因为PdfViewer有自己的loading overlay
  showError.value = false;
  emit('load', totalPages);
};

const handlePdfPageChange = (page: number) => {
  // 对于单个 PDF 文件，currentPage 应该保持为 0
  // pageChange 事件表示 PdfViewer 内部翻页，不影响 pages 数组的索引
  // 只有当有多个文件时才需要发出 pageChange 事件
  if (props.pages.length > 1) {
    currentPage.value = page;
    emit('pageChange', page);
  }
  // 对于单个 PDF 文件，不发出事件，保持 currentPage = 0
};

const prevPage = () => {
  if (currentPage.value > 0) {
    const isPdf = currentSlideType.value === 'pdf' || currentSlideType.value === 'pdf-fallback';
    // PDF类型不需要设置loading，因为PdfViewer有自己的loading状态
    if (!isPdf) {
      isLoading.value = true;
    }
    showError.value = false;
    currentPage.value--;
    emit('pageChange', currentPage.value);
  }
};

const nextPage = () => {
  if (currentPage.value < props.pages.length - 1) {
    const isPdf = currentSlideType.value === 'pdf' || currentSlideType.value === 'pdf-fallback';
    // PDF类型不需要设置loading，因为PdfViewer有自己的loading状态
    if (!isPdf) {
      isLoading.value = true;
    }
    showError.value = false;
    currentPage.value++;
    emit('pageChange', currentPage.value);
  }
};

const goToPage = (index: number) => {
  if (index !== currentPage.value) {
    const isPdf = currentSlideType.value === 'pdf' || currentSlideType.value === 'pdf-fallback';
    // PDF类型不需要设置loading，因为PdfViewer有自己的loading状态
    if (!isPdf) {
      isLoading.value = true;
    }
    showError.value = false;
    currentPage.value = index;
    emit('pageChange', currentPage.value);
  }
};

const handleContainerClick = (e: MouseEvent) => {
  // PDF时不允许点击翻页，因为需要与PDF交互
  if (currentSlideType.value === 'pdf' || currentSlideType.value === 'pdf-fallback') {
    return;
  }

  const rect = (e.currentTarget as HTMLElement).getBoundingClientRect();
  const clickX = e.clientX - rect.left;
  const halfWidth = rect.width / 2;

  if (clickX < halfWidth) {
    prevPage();
  } else {
    nextPage();
  }
};

// 键盘事件
const handleKeydown = (e: KeyboardEvent) => {
  // PDF时不允许键盘翻页，因为需要与PDF交互
  const isPdf = currentSlideType.value === 'pdf' || currentSlideType.value === 'pdf-fallback';
  if (isPdf) {
    return; // 让PdfViewer处理键盘事件
  }

  switch (e.key) {
    case 'ArrowLeft':
      prevPage();
      break;
    case 'ArrowRight':
      nextPage();
      break;
  }
};

// 监听外部页码变化
watch(() => props.currentPage, (newPage) => {
  if (newPage !== currentPage.value) {
    const isPdf = currentSlideType.value === 'pdf' || currentSlideType.value === 'pdf-fallback';
    // PDF类型不需要设置loading，因为PdfViewer有自己的loading状态
    if (!isPdf) {
      isLoading.value = true;
    }
    showError.value = false;
    currentPage.value = newPage;
  }
});

// 监听pages变化 - 只在真正需要时才重新加载
watch(() => props.pages, (newPages, oldPages) => {
  // 只有当pages真正改变时才设置loading
  const hasChanged = !oldPages || newPages.length !== oldPages.length ||
                     newPages[0] !== oldPages[0];

  if (hasChanged && newPages.length > 0) {
    console.log('[SlidesViewer] pages 内容改变, 重新加载, 设置 isLoading = true');
    isLoading.value = true;
    showError.value = false;
  }
});

// 生命周期
onMounted(() => {
  console.log('[SlidesViewer] 组件已挂载');
  console.log('[SlidesViewer] onPdfLoad 函数存在:', typeof onPdfLoad === 'function');
  document.addEventListener('keydown', handleKeydown);

  // 设置加载超时
  setTimeout(() => {
    if (isLoading.value) {
      console.log('[SlidesViewer] 加载超时, 强制设置 isLoading = false');
      isLoading.value = false;
    }
  }, 5000);
});

onUnmounted(() => {
  document.removeEventListener('keydown', handleKeydown);
});
</script>

<style scoped lang="scss">
.slides-viewer {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  background: #1a1a2e;
  position: relative;
}

.slide-container {
  flex: 1;
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  position: relative;
  overflow: hidden;

  &:hover {
    .page-hint {
      opacity: 1;
    }
  }
}

.page-hint {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  color: rgba(255, 255, 255, 0.8);
  text-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
  opacity: 0;
  transition: opacity 0.3s;
  pointer-events: none;
  z-index: 10;

  &.left {
    left: 20px;
  }

  &.right {
    right: 20px;
  }
}

.slide-image {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
  border-radius: 12px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
}

.ppt-container {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%);
  border-radius: 12px;
}

.ppt-preview {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 60px;
  color: white;

  .ppt-title {
    margin-top: 24px;
    font-size: 20px;
    font-weight: 600;
    color: rgba(255, 255, 255, 0.9);
    word-break: break-all;
    max-width: 80%;
  }

  .ppt-hint {
    margin-top: 12px;
    font-size: 16px;
    color: rgba(255, 255, 255, 0.6);
  }

  .ppt-actions {
    display: flex;
    gap: 16px;
    margin-top: 32px;
  }

  .ppt-btn {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 14px 28px;
    background: rgba(255, 255, 255, 0.1);
    color: white;
    text-decoration: none;
    border-radius: 12px;
    font-size: 16px;
    border: 1px solid rgba(255, 255, 255, 0.2);
    transition: all 0.3s;

    &:hover {
      background: rgba(255, 255, 255, 0.2);
      transform: translateY(-2px);
    }

    &.primary {
      background: #FF8C42;
      border-color: #FF8C42;

      &:hover {
        background: #E67635;
      }
    }
  }

  .ppt-tip {
    margin-top: 40px;
    font-size: 13px;
    color: rgba(255, 255, 255, 0.4);
    max-width: 400px;
  }
}

.no-slides {
  text-align: center;
  color: #666;

  p {
    margin-top: 16px;
    font-size: 18px;
  }

  .error-url {
    font-size: 12px;
    color: #999;
    word-break: break-all;
    max-width: 80%;
    margin: 8px auto 0;
  }
}

.loading-overlay {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  background: rgba(26, 26, 46, 0.9);
  border-radius: 12px;
  z-index: 20;

  .loading-text {
    margin-top: 16px;
    color: rgba(255, 255, 255, 0.8);
    font-size: 14px;
  }
}

.loading-spinner {
  width: 48px;
  height: 48px;
  border: 3px solid rgba(255, 255, 255, 0.3);
  border-top-color: #FF8C42;
  border-radius: 50%;
  animation: spin 1s linear infinite;
}

@keyframes spin {
  to { transform: rotate(360deg); }
}

.page-controls {
  display: flex;
  align-items: center;
  gap: 20px;
  padding: 16px 24px;
  background: rgba(0, 0, 0, 0.6);
  border-radius: 30px;
  margin: 16px;
  flex-shrink: 0;

  .page-btn {
    width: 44px;
    height: 44px;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.2);
    display: flex;
    align-items: center;
    justify-content: center;
    color: white;
    cursor: pointer;
    transition: all 0.3s;

    &:hover:not(.disabled) {
      background: rgba(255, 255, 255, 0.4);
      transform: scale(1.1);
    }

    &.disabled {
      opacity: 0.3;
      cursor: not-allowed;
    }
  }

  .page-dots {
    display: flex;
    gap: 8px;

    .dot {
      width: 10px;
      height: 10px;
      border-radius: 50%;
      background: rgba(255, 255, 255, 0.3);
      cursor: pointer;
      transition: all 0.3s;

      &:hover {
        background: rgba(255, 255, 255, 0.5);
      }

      &.active {
        background: #FF8C42;
        transform: scale(1.3);
      }
    }
  }
}

.page-info {
  position: absolute;
  bottom: 20px;
  right: 20px;
  padding: 8px 16px;
  background: rgba(0, 0, 0, 0.6);
  color: white;
  border-radius: 20px;
  font-size: 14px;
}

.pdf-toolbar {
  position: absolute;
  top: 20px;
  right: 20px;
  display: flex;
  gap: 8px;
  z-index: 15;

  .toolbar-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    background: rgba(255, 255, 255, 0.9);
    border-radius: 8px;
    color: #333;
    text-decoration: none;
    transition: all 0.3s;

    &:hover {
      background: #FF8C42;
      color: white;
      transform: scale(1.1);
    }
  }
}
</style>
