<template>
  <div class="ebook-viewer" ref="viewerRef">
    <!-- 绘本内容 -->
    <div class="ebook-image-container" @click="handleContainerClick">
      <!-- 图片展示 -->
      <img
        v-if="pages.length > 0 && currentPageType === 'image'"
        :src="pages[currentPage]"
        :key="'img-' + currentPage"
        class="ebook-image"
        @load="onImageLoad"
        @error="onImageError"
        :style="{ transform: `scale(${scale})` }"
        alt="绘本页面"
      />

      <!-- PDF展示 -->
      <embed
        v-else-if="pages.length > 0 && currentPageType === 'pdf'"
        :src="pdfEmbedUrl"
        type="application/pdf"
        class="ebook-pdf"
        @load="onPdfLoad"
      />

      <!-- PDF备用方案 -->
      <object
        v-else-if="pages.length > 0 && currentPageType === 'pdf-fallback'"
        :data="pdfEmbedUrl"
        type="application/pdf"
        class="ebook-pdf"
      >
        <div class="pdf-fallback">
          <FileText :size="64" stroke-width="1" />
          <p>PDF文件无法在此浏览器中预览</p>
          <a :href="pages[currentPage]" target="_blank" class="pdf-download-btn">
            <Download :size="20" />
            点击打开PDF
          </a>
        </div>
      </object>

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

      <!-- 加载中 -->
      <div v-if="isLoading && pages.length > 0" class="loading-overlay">
        <div class="loading-spinner"></div>
        <p class="loading-text">正在加载{{ currentPageType === 'pdf' ? 'PDF' : '内容' }}...</p>
      </div>

      <!-- 左右翻页提示 (仅图片模式) -->
      <template v-if="currentPageType === 'image'">
        <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>
      </template>
    </div>

    <!-- 翻页控制 -->
    <div class="page-controls" v-if="pages.length > 1 && currentPageType === 'image'">
      <div class="page-btn prev" @click="prevPage" :class="{ disabled: currentPage === 0 }">
        <ChevronLeft :size="24" />
      </div>

      <div class="page-info">
        <span class="page-number">{{ currentPage + 1 }}</span>
        <span class="page-divider">/</span>
        <span class="page-total">{{ pages.length }}</span>
      </div>

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

    <!-- PDF工具栏 -->
    <div class="pdf-toolbar" v-if="currentPageType === 'pdf' || currentPageType === 'pdf-fallback'">
      <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>
      <button v-if="pages.length > 1" class="toolbar-btn" @click="nextPage" :disabled="currentPage >= pages.length - 1" title="下一页">
        <ChevronRight :size="18" />
      </button>
      <button v-if="pages.length > 1" class="toolbar-btn" @click="prevPage" :disabled="currentPage === 0" title="上一页">
        <ChevronLeft :size="18" />
      </button>
    </div>

    <!-- 音频控制（可选） -->
    <div v-if="audioUrl" class="audio-controls">
      <audio ref="audioRef" :src="audioUrl" @ended="onAudioEnded" />
      <a-button class="audio-btn" :type="isPlaying ? 'primary' : 'default'" @click="toggleAudio">
        <template #icon>
          <VolumeX v-if="!isPlaying" :size="16" />
          <Pause v-else :size="16" />
        </template>
        {{ isPlaying ? '暂停' : '播放' }}配乐
      </a-button>
      <a-switch
        v-model:checked="audioSyncEnabled"
        checked-children="同步"
        un-checked-children="独立"
        @change="onSyncChange"
      />
    </div>

    <!-- 自动翻页控制 -->
    <div class="auto-play-controls" v-if="currentPageType === 'image'">
      <a-switch
        v-model:checked="autoPlayEnabled"
        checked-children="自动"
        un-checked-children="手动"
        @change="onAutoPlayChange"
      />
      <span class="auto-play-hint" v-if="autoPlayEnabled">每{{ autoPlayInterval }}秒翻页</span>
    </div>

    <!-- 缩放控制 (仅图片模式) -->
    <div class="zoom-controls" v-if="currentPageType === 'image'">
      <a-button @click="zoomOut" :disabled="scale <= 1">
        <ZoomOut :size="16" />
      </a-button>
      <span class="zoom-level">{{ Math.round(scale * 100) }}%</span>
      <a-button @click="zoomIn" :disabled="scale >= 3">
        <ZoomIn :size="16" />
      </a-button>
      <a-button @click="resetZoom">
        <Maximize2 :size="16" />
      </a-button>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, watch, onMounted, onUnmounted } from 'vue';
import {
  ChevronLeft,
  ChevronRight,
  VolumeX,
  Pause,
  ZoomOut,
  ZoomIn,
  Maximize2,
  BookOpen,
  FileText,
  Download,
  ExternalLink,
} from 'lucide-vue-next';

interface Props {
  pages: string[];
  currentPage: number;
  audioUrl?: string;
  autoPlay?: boolean;
}

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

const emit = defineEmits<{
  (e: 'pageChange', page: number): void;
  (e: 'toggleAudioSync', enabled: boolean): void;
}>();

// Refs
const viewerRef = ref<HTMLElement>();
const audioRef = ref<HTMLAudioElement>();

// 状态
const currentPage = ref(props.currentPage);
const scale = ref(1);
const isLoading = ref(true);
const loadError = ref(false);
const isPlaying = ref(false);
const audioSyncEnabled = ref(false);
const autoPlayEnabled = ref(false);
const autoPlayInterval = ref(5);

let autoPlayTimer: number | null = null;

// 计算属性
const currentPageType = 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';
  }

  return 'image';
});

const pdfEmbedUrl = computed(() => {
  const url = props.pages[currentPage.value] || '';
  if (!url) return '';

  if (url.includes('?')) {
    return `${url}#toolbar=1&navpanes=0&scrollbar=1&view=FitH`;
  }
  return `${url}#toolbar=1&navpanes=0&scrollbar=1&view=FitH`;
});

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

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

const onPdfLoad = () => {
  isLoading.value = false;
};

const prevPage = () => {
  if (currentPage.value > 0) {
    isLoading.value = true;
    loadError.value = false;
    currentPage.value--;
    emit('pageChange', currentPage.value);
  }
};

const nextPage = () => {
  if (currentPage.value < props.pages.length - 1) {
    isLoading.value = true;
    loadError.value = false;
    currentPage.value++;
    emit('pageChange', currentPage.value);
  }
};

const handleContainerClick = (e: MouseEvent) => {
  // PDF模式不允许点击翻页
  if (currentPageType.value !== 'image') 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 toggleAudio = () => {
  if (!audioRef.value) return;

  if (isPlaying.value) {
    audioRef.value.pause();
  } else {
    audioRef.value.play();
  }
  isPlaying.value = !isPlaying.value;
};

const onAudioEnded = () => {
  isPlaying.value = false;
  if (audioSyncEnabled.value && currentPage.value < props.pages.length - 1) {
    nextPage();
    setTimeout(() => {
      if (audioRef.value) {
        audioRef.value.currentTime = 0;
        audioRef.value.play();
        isPlaying.value = true;
      }
    }, 500);
  }
};

const onSyncChange = (checked: boolean | string | number) => {
  emit('toggleAudioSync', !!checked);
};

const onAutoPlayChange = (checked: boolean | string | number) => {
  if (checked) {
    startAutoPlay();
  } else {
    stopAutoPlay();
  }
};

const startAutoPlay = () => {
  stopAutoPlay();
  autoPlayTimer = setInterval(() => {
    if (currentPage.value < props.pages.length - 1) {
      nextPage();
    } else {
      autoPlayEnabled.value = false;
      stopAutoPlay();
    }
  }, autoPlayInterval.value * 1000) as unknown as number;
};

const stopAutoPlay = () => {
  if (autoPlayTimer) {
    clearInterval(autoPlayTimer);
    autoPlayTimer = null;
  }
};

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

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

const resetZoom = () => {
  scale.value = 1;
};

// 键盘事件
const handleKeydown = (e: KeyboardEvent) => {
  switch (e.key) {
    case 'ArrowLeft':
      prevPage();
      break;
    case 'ArrowRight':
      nextPage();
      break;
    case '+':
    case '=':
      zoomIn();
      break;
    case '-':
      zoomOut();
      break;
    case ' ':
      if (props.audioUrl) {
        e.preventDefault();
        toggleAudio();
      }
      break;
  }
};

// 监听外部页码变化
watch(() => props.currentPage, (newPage) => {
  if (newPage !== currentPage.value) {
    isLoading.value = true;
    loadError.value = false;
    currentPage.value = newPage;
  }
});

// 监听pages变化
watch(() => props.pages, () => {
  isLoading.value = true;
  loadError.value = false;
}, { immediate: true });

// 生命周期
onMounted(() => {
  document.addEventListener('keydown', handleKeydown);

  // 设置加载超时
  setTimeout(() => {
    if (isLoading.value) {
      isLoading.value = false;
    }
  }, 5000);
});

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

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

.ebook-image-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;

  &.left {
    left: 20px;
  }

  &.right {
    right: 20px;
  }
}

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

.ebook-pdf {
  width: 100%;
  height: 100%;
  border: none;
  border-radius: 12px;
  background: #fff;
}

.pdf-fallback {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  background: rgba(255, 255, 255, 0.95);
  border-radius: 12px;
  color: #333;
  padding: 40px;

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

  .pdf-download-btn {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 12px 24px;
    background: #FF8C42;
    color: white;
    text-decoration: none;
    border-radius: 8px;
    font-size: 16px;
    transition: all 0.3s;

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

.no-pages {
  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;
  background: rgba(0, 0, 0, 0.6);
  border-radius: 30px;
  margin: 16px;

  .page-btn {
    width: 48px;
    height: 48px;
    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-info {
    color: white;
    font-size: 24px;
    font-weight: bold;
    min-width: 80px;
    text-align: center;

    .page-divider {
      margin: 0 8px;
      opacity: 0.6;
    }

    .page-total {
      opacity: 0.6;
    }
  }
}

.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;
    border: none;
    color: #333;
    text-decoration: none;
    cursor: pointer;
    transition: all 0.3s;

    &:hover:not(:disabled) {
      background: #FF8C42;
      color: white;
      transform: scale(1.1);
    }

    &:disabled {
      opacity: 0.5;
      cursor: not-allowed;
    }
  }
}

.audio-controls,
.auto-play-controls,
.zoom-controls {
  position: absolute;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 16px;
  background: rgba(255, 255, 255, 0.95);
  border-radius: 12px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}

.audio-controls {
  top: 20px;
  left: 20px;

  .audio-btn {
    border-radius: 20px;
    display: flex;
    align-items: center;
    gap: 6px;
  }
}

.auto-play-controls {
  top: 20px;
  right: 20px;

  .auto-play-hint {
    font-size: 12px;
    color: #666;
  }
}

.zoom-controls {
  bottom: 100px;
  right: 20px;

  .zoom-level {
    font-size: 14px;
    color: #666;
    min-width: 50px;
    text-align: center;
  }
}
</style>
