<template>
  <div class="pdf-viewer" ref="containerRef">
    <!-- PDF Canvas Container -->
    <div class="pdf-container" :class="{ 'full-screen': isFullScreen }">
      <canvas ref="canvasRef" class="pdf-canvas"></canvas>

      <!-- Loading Overlay -->
      <div v-if="isLoading" class="loading-overlay">
        <div class="loading-spinner"></div>
        <p class="loading-text">正在加载绘本...</p>
      </div>

      <!-- Error State -->
      <div v-if="error" class="error-state">
        <FileText :size="64" stroke-width="1" />
        <p>PDF加载失败</p>
        <p class="error-message">{{ error }}</p>
        <button class="retry-btn" @click="loadPdf">
          <RotateCcw :size="20" />
          重试
        </button>
      </div>
    </div>

    <!-- Floating Toolbar (doesn't obstruct content) -->
    <div class="toolbar" :class="{ 'toolbar-hidden': toolbarHidden }">
      <button class="toolbar-btn" @click="toolbarHidden = !toolbarHidden" :title="toolbarHidden ? '显示工具栏' : '隐藏工具栏'">
        <ChevronUp v-if="!toolbarHidden" :size="20" />
        <ChevronDown v-else :size="20" />
      </button>

      <div class="toolbar-content" v-show="!toolbarHidden">
        <!-- Page Navigation -->
        <div class="toolbar-group">
          <button class="nav-btn" @click="prevPage" :disabled="currentPage <= 1" title="上一页">
            <ChevronLeft :size="24" />
          </button>
          <span class="page-info">{{ currentPage }} / {{ totalPages }}</span>
          <button class="nav-btn" @click="nextPage" :disabled="currentPage >= totalPages" title="下一页">
            <ChevronRight :size="24" />
          </button>
        </div>

        <!-- Zoom Controls -->
        <div class="toolbar-group">
          <button class="nav-btn" @click="zoomOut" :disabled="scale <= 0.5" title="缩小">
            <ZoomOut :size="20" />
          </button>
          <span class="zoom-info">{{ Math.round(scale * 100) }}%</span>
          <button class="nav-btn" @click="zoomIn" :disabled="scale >= 3" title="放大">
            <ZoomIn :size="20" />
          </button>
          <button class="nav-btn" @click="fitToWidth" title="适合宽度">
            <Maximize :size="20" />
          </button>
        </div>

        <!-- View Mode -->
        <div class="toolbar-group">
          <button class="nav-btn" @click="toggleFullScreen" :title="isFullScreen ? '退出全屏' : '全屏'">
            <Minimize v-if="isFullScreen" :size="20" />
            <Maximize2 v-else :size="20" />
          </button>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, onUnmounted, watch, nextTick, markRaw } from 'vue';
import * as pdfjsLib from 'pdfjs-dist';
import {
  ChevronLeft,
  ChevronRight,
  ChevronUp,
  ChevronDown,
  ZoomIn,
  ZoomOut,
  Maximize,
  Minimize,
  Maximize2,
  FileText,
  RotateCcw,
} from 'lucide-vue-next';

// Set up PDF.js worker - 使用完整的URL避免CORS问题
pdfjsLib.GlobalWorkerOptions.workerSrc = `https://cdnjs.cloudflare.com/ajax/libs/pdf.js/${pdfjsLib.version}/pdf.worker.min.js`;

interface Props {
  url: string;
  currentPage?: number;
}

const props = withDefaults(defineProps<Props>(), {
  currentPage: 0,
});

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

// Refs
const containerRef = ref<HTMLElement | null>(null);
const canvasRef = ref<HTMLCanvasElement | null>(null);

// State
const pdfDoc = ref<pdfjsLib.PDFDocumentProxy | null>(null);
// PDF页码从1开始，将props的0-based转换为1-based
const currentPage = ref((props.currentPage || 0) + 1);
const totalPages = ref(0);
const scale = ref(1.5);
const isLoading = ref(true);
const error = ref('');
const isFullScreen = ref(false);
const toolbarHidden = ref(false);
// 标记是否已经完成初始渲染，避免初始加载时发出pageChange事件
const initialRenderComplete = ref(false);

// Methods
const loadPdf = async () => {
  isLoading.value = true;
  error.value = '';

  console.log('[PdfViewer] 开始加载PDF:', props.url);

  try {
    console.log('[PdfViewer] 调用 getDocument...');
    const loadingTask = pdfjsLib.getDocument(props.url);
    console.log('[PdfViewer] 等待 PDF 加载...');

    const doc = await loadingTask.promise;
    console.log('[PdfViewer] PDF 加载成功, 页数:', doc.numPages);

    // 使用 markRaw 避免Vue响应式系统干扰PDF.js内部对象
    pdfDoc.value = markRaw(doc);
    totalPages.value = doc.numPages;

    console.log('[PdfViewer] 准备渲染第一页...');

    // 渲染第一页
    if (totalPages.value > 0) {
      await renderPage(1);
      console.log('[PdfViewer] 第一页渲染完成');
    } else {
      console.error('[PdfViewer] PDF没有页面');
      error.value = 'PDF文件没有页面';
    }

    // 通知父组件加载完成
    console.log('[PdfViewer] 触发 pdfLoaded 事件, 总页数:', totalPages.value);
    console.log('[PdfViewer] emit 函数类型:', typeof emit);
    try {
      emit('pdfLoaded', totalPages.value);
      console.log('[PdfViewer] pdfLoaded 事件已发送');
    } catch (err) {
      console.error('[PdfViewer] 发送 pdfLoaded 事件时出错:', err);
    }
  } catch (err: any) {
    console.error('[PdfViewer] PDF loading error:', err);
    error.value = err.message || '无法加载PDF文件';
  } finally {
    isLoading.value = false;
    console.log('[PdfViewer] 加载完成, isLoading:', isLoading.value);
  }
};

const renderPage = async (pageNumber: number) => {
  console.log(`[PdfViewer] renderPage 被调用, 页码: ${pageNumber}`);

  if (!pdfDoc.value) {
    console.error('[PdfViewer] pdfDoc 为空，无法渲染');
    return;
  }

  if (!canvasRef.value) {
    console.error('[PdfViewer] canvasRef 为空，无法渲染');
    return;
  }

  try {
    console.log(`[PdfViewer] 获取第 ${pageNumber} 页...`);
    const page = await pdfDoc.value.getPage(pageNumber);
    console.log(`[PdfViewer] 页面获取成功, 计算视口...`);

    const viewport = page.getViewport({ scale: scale.value });
    console.log(`[PdfViewer] 视口尺寸: ${viewport.width}x${viewport.height}`);

    const canvas = canvasRef.value;
    const context = canvas.getContext('2d');

    if (!context) {
      throw new Error('Cannot get canvas context');
    }

    // 设置canvas尺寸
    canvas.width = viewport.width;
    canvas.height = viewport.height;

    // 清除canvas
    context.clearRect(0, 0, canvas.width, canvas.height);

    console.log(`[PdfViewer] 开始渲染...`);

    // 渲染PDF页面
    await page.render({
      canvasContext: context,
      viewport: viewport,
    }).promise;

    console.log(`[PdfViewer] 渲染完成`);
    currentPage.value = pageNumber;
    // 只在初始渲染完成后才发出 pageChange 事件，避免初始加载时导致父组件状态混乱
    if (initialRenderComplete.value) {
      // 将 1-based 转换为 0-based 传递给父组件
      emit('pageChange', pageNumber - 1);
      console.log(`[PdfViewer] 发出 pageChange: ${pageNumber} (1-based) -> ${pageNumber - 1} (0-based)`);
    } else {
      console.log('[PdfViewer] 初始渲染，不发出 pageChange 事件');
      initialRenderComplete.value = true;
    }
    // 触发 loaded 事件通知 SlidesViewer
    emit('loaded');
  } catch (err: any) {
    console.error('[PdfViewer] Page render error:', err);
    error.value = `渲染第${pageNumber}页失败: ${err.message}`;
  }
};

const prevPage = () => {
  if (currentPage.value > 1) {
    renderPage(currentPage.value - 1);
  }
};

const nextPage = () => {
  if (currentPage.value < totalPages.value) {
    renderPage(currentPage.value + 1);
  }
};

const goToPage = (pageNumber: number) => {
  if (pageNumber >= 1 && pageNumber <= totalPages.value) {
    renderPage(pageNumber);
  }
};

const zoomIn = () => {
  if (scale.value < 3) {
    scale.value = Math.min(3, scale.value + 0.25);
    renderPage(currentPage.value);
  }
};

const zoomOut = () => {
  if (scale.value > 0.5) {
    scale.value = Math.max(0.5, scale.value - 0.25);
    renderPage(currentPage.value);
  }
};

const fitToWidth = () => {
  if (!containerRef.value || !pdfDoc.value) return;

  const containerWidth = containerRef.value.clientWidth - 40; // padding
  pdfDoc.value.getPage(currentPage.value).then((page) => {
    const viewport = page.getViewport({ scale: 1 });
    scale.value = containerWidth / viewport.width;
    renderPage(currentPage.value);
  });
};

const toggleFullScreen = () => {
  if (!document.fullscreenElement) {
    containerRef.value?.requestFullscreen();
    isFullScreen.value = true;
  } else {
    document.exitFullscreen();
    isFullScreen.value = false;
  }
};

// Keyboard shortcuts
const handleKeydown = (e: KeyboardEvent) => {
  switch (e.key) {
    case 'ArrowLeft':
      prevPage();
      break;
    case 'ArrowRight':
      nextPage();
      break;
    case '+':
    case '=':
      zoomIn();
      break;
    case '-':
      zoomOut();
      break;
    case 'f':
    case 'F':
      toggleFullScreen();
      break;
  }
};

// Watch for URL changes
watch(() => props.url, () => {
  if (props.url) {
    // 重置初始渲染标志
    initialRenderComplete.value = false;
    loadPdf();
  }
}, { immediate: true });

// Watch for external page changes
watch(() => props.currentPage, (newPage) => {
  // 将 0-based 转换为 1-based
  const pdfPage = (newPage || 0) + 1;
  if (pdfPage !== currentPage.value) {
    console.log(`[PdfViewer] 外部页码变化: ${newPage} (0-based) -> ${pdfPage} (1-based)`);
    renderPage(pdfPage);
  }
});

// Fullscreen change detection
const handleFullScreenChange = () => {
  isFullScreen.value = !!document.fullscreenElement;
};

// Lifecycle
onMounted(() => {
  console.log('[PdfViewer] 组件已挂载');
  document.addEventListener('keydown', handleKeydown);
  document.addEventListener('fullscreenchange', handleFullScreenChange);
});

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

<style scoped lang="scss">
.pdf-viewer {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  background: linear-gradient(135deg, #FFF8E1 0%, #FFE0B2 50%, #FFCCBC 100%);
  position: relative;
  overflow: hidden;
}

.pdf-container {
  flex: 1;
  display: flex;
  align-items: flex-start;
  justify-content: center;
  overflow: auto;
  padding: 20px;
  position: relative;

  &.full-screen {
    padding: 40px;
  }
}

.pdf-canvas {
  max-width: 100%;
  height: auto;
  box-shadow: 0 10px 60px rgba(0, 0, 0, 0.2);
  border-radius: 8px;
  background: white;
  transition: transform 0.3s ease;
}

.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(255, 248, 225, 0.95);
  z-index: 100;

  .loading-text {
    margin-top: 20px;
    font-size: 18px;
    color: #FF8C42;
    font-weight: 500;
  }
}

.loading-spinner {
  width: 60px;
  height: 60px;
  border: 4px solid rgba(255, 140, 66, 0.2);
  border-top-color: #FF8C42;
  border-radius: 50%;
  animation: spin 1s linear infinite;
}

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

.error-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 60px;
  text-align: center;
  color: #333;

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

  .error-message {
    font-size: 14px;
    color: #999;
  }

  .retry-btn {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-top: 24px;
    padding: 12px 24px;
    background: #FF8C42;
    color: white;
    border: none;
    border-radius: 8px;
    font-size: 16px;
    cursor: pointer;
    transition: all 0.3s;

    &:hover {
      background: #E67635;
      transform: scale(1.05);
    }
  }
}

.toolbar {
  position: absolute;
  bottom: 20px;
  left: 50%;
  transform: translateX(-50%);
  background: rgba(255, 255, 255, 0.95);
  backdrop-filter: blur(10px);
  border-radius: 16px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
  padding: 12px 20px;
  z-index: 50;
  transition: all 0.3s ease;

  &.toolbar-hidden {
    bottom: 20px;
    transform: translateX(-50%) translateY(calc(100% - 50px));

    &:hover {
      transform: translateX(-50%) translateY(0);
    }
  }

  .toolbar-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    border: none;
    background: transparent;
    color: #FF8C42;
    cursor: pointer;
    border-radius: 8px;
    transition: all 0.3s;
    margin: 0 auto 8px;

    &:hover {
      background: rgba(255, 140, 66, 0.1);
    }
  }

  .toolbar-content {
    display: flex;
    align-items: center;
    gap: 16px;
  }

  .toolbar-group {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 0 8px;
    border-right: 1px solid rgba(0, 0, 0, 0.1);

    &:last-child {
      border-right: none;
    }
  }

  .nav-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    border: none;
    background: #FF8C42;
    color: white;
    border-radius: 10px;
    cursor: pointer;
    transition: all 0.3s;

    &:hover:not(:disabled) {
      background: #E67635;
      transform: scale(1.1);
    }

    &:disabled {
      background: rgba(0, 0, 0, 0.1);
      color: rgba(0, 0, 0, 0.3);
      cursor: not-allowed;
    }
  }

  .page-info,
  .zoom-info {
    padding: 0 12px;
    font-size: 14px;
    font-weight: 600;
    color: #333;
    min-width: 60px;
    text-align: center;
  }
}
</style>
