<script setup lang="ts">
/**
 * 文章 PPT 预览页
 */
import { computed, onMounted, ref } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import Icon from '../components/Icon.vue'
import PptSlideViewer from '../components/ppt/PptSlideViewer.vue'
import { usePptPresentation } from '../composables/usePptPresentation'
import { usePptTemplate } from '../composables/usePptTemplate'
import { useToast } from '../composables/useToast'
import { fetchPost, type Post } from '../services/api'
import { exportAsPptStructured } from '../utils/articleExport'
import { buildPptSlides } from '../utils/articlePptSlides'
import { getCachedSiteTitle } from '../router'

const route = useRoute()
const router = useRouter()
const toast = useToast()

const postId = route.params.id as string
const post = ref<Post | null>(null)
const loading = ref(true)
const error = ref('')
const isExporting = ref(false)

const {
  templates,
  selectedTemplateId,
  templateVars,
  slideTransitionForward,
  slideTransitionBackward,
  revealTransition,
  showThumbnailsDefault,
  loadTemplates,
  setTemplate,
} = usePptTemplate()

const showThumbnails = ref(true)

const containerRef = ref<HTMLElement | null>(null)
const toolbarVisible = ref(true)
let hideToolbarTimer: ReturnType<typeof setTimeout> | null = null

const slides = computed(() => (post.value ? buildPptSlides(post.value) : []))

const {
  currentIndex,
  currentStep,
  totalSlides,
  totalSteps,
  slideDirection,
  isFullscreen,
  goToSlide,
  advance,
  retreat,
  toggleFullscreen,
} = usePptPresentation(slides, containerRef)

const showHeader = computed(
  () => !loading.value && !error.value && (!isFullscreen.value || toolbarVisible.value)
)

const pptChromeHeight = computed(() => {
  if (loading.value || error.value || !slides.value.length) return '0px'
  if (isFullscreen.value && !toolbarVisible.value) return '0px'

  let px = 0
  if (showHeader.value) px += 52
  if (showHeader.value) px += 88
  return `${px}px`
})

const fetchDetail = async () => {
  loading.value = true
  error.value = ''
  try {
    const data = await fetchPost(postId)
    if (data) {
      post.value = data
      document.title = `${data.title} · PPT 预览 | ${getCachedSiteTitle()}`
    } else {
      error.value = '未找到该文章'
    }
  } catch (err) {
    console.error('Failed to load post for PPT preview:', err)
    error.value = '加载文章失败，请稍后重试'
  } finally {
    loading.value = false
  }
}

const goBack = () => {
  router.push(`/blog/${postId}`)
}

const handleExport = async () => {
  if (!post.value || isExporting.value) return
  isExporting.value = true
  toast.info('正在生成 PPT…')
  try {
    const result = await exportAsPptStructured(post.value)
    if (result.success) {
      toast.success('导出成功')
      if (result.warning) toast.warning(result.warning)
    } else {
      toast.error(result.warning || '导出失败')
    }
  } catch (err) {
    console.error('PPT export failed:', err)
    toast.error('导出失败，请稍后重试')
  } finally {
    isExporting.value = false
  }
}

const handleMouseMove = () => {
  if (!isFullscreen.value) return
  toolbarVisible.value = true
  if (hideToolbarTimer) clearTimeout(hideToolbarTimer)
  hideToolbarTimer = setTimeout(() => {
    toolbarVisible.value = false
  }, 3000)
}

const onTemplateChange = (e: Event) => {
  const id = Number.parseInt((e.target as HTMLSelectElement).value, 10)
  if (Number.isFinite(id)) setTemplate(id)
}

onMounted(async () => {
  await loadTemplates()
  showThumbnails.value = showThumbnailsDefault.value
  void fetchDetail()
})
</script>

<template>
  <div
    ref="containerRef"
    class="flex flex-col h-[100dvh] min-h-0 bg-[#0a0a0a] text-white relative ppt-preview-page"
    :style="{ '--ppt-chrome-h': pptChromeHeight }"
    @mousemove="handleMouseMove"
  >
    <header
      v-if="showHeader"
      class="flex-shrink-0 flex items-center justify-between gap-3 px-4 py-3 border-b border-white/10 bg-[#0a0a0a]/90 backdrop-blur-md z-20"
    >
      <button
        type="button"
        class="flex items-center gap-2 text-sm text-white/60 hover:text-white transition-colors"
        @click="goBack"
      >
        <Icon name="arrow-left" :size="16" />
        <span class="hidden sm:inline">返回文章</span>
      </button>

      <div class="text-sm font-medium text-white/80 truncate max-w-[30%] text-center">
        {{ post?.title }}
        <span v-if="totalSlides" class="text-white/40 font-mono text-xs ml-1">
          {{ currentIndex + 1 }}/{{ totalSlides }} · {{ currentStep + 1 }}/{{ totalSteps }}
        </span>
      </div>

      <div class="flex items-center gap-2">
        <label v-if="templates.length" class="flex items-center gap-1.5 text-xs text-white/70">
          <span class="hidden sm:inline">模板</span>
          <select
            class="rounded-full border border-white/10 bg-white/5 px-2 py-1.5 text-xs text-white/90 outline-none"
            :value="selectedTemplateId ?? ''"
            @change="onTemplateChange"
          >
            <option v-for="t in templates" :key="t.id" :value="t.id">{{ t.name }}</option>
          </select>
        </label>

        <button
          type="button"
          class="flex items-center gap-1.5 rounded-full border border-white/10 bg-white/5 px-3 py-1.5 text-xs text-white/70 hover:text-white hover:bg-white/10 transition-colors"
          @click="toggleFullscreen"
        >
          <Icon :name="isFullscreen ? 'minimize' : 'maximize'" :size="14" />
          <span class="hidden sm:inline">{{ isFullscreen ? '退出' : '全屏' }}</span>
        </button>

        <button
          type="button"
          :disabled="isExporting"
          class="flex items-center gap-1.5 rounded-full border border-white/10 bg-white/5 px-3 py-1.5 text-xs text-white/70 hover:text-white hover:bg-white/10 transition-colors disabled:opacity-50"
          @click="handleExport"
        >
          <Icon :name="isExporting ? 'loader-2' : 'download'" :size="14" :class="isExporting ? 'animate-spin' : ''" />
          <span class="hidden sm:inline">{{ isExporting ? '导出中…' : '导出 PPT' }}</span>
        </button>
      </div>
    </header>

    <div v-if="loading" class="flex-1 flex items-center justify-center">
      <div class="animate-spin rounded-full h-10 w-10 border-t-2 border-b-2 border-art-accent"></div>
    </div>

    <div v-else-if="error" class="flex-1 flex flex-col items-center justify-center gap-4 text-center px-4">
      <p class="text-red-400">{{ error }}</p>
      <button
        type="button"
        class="rounded-full border border-white/10 px-4 py-2 text-sm text-white/70 hover:text-white hover:bg-white/5 transition-colors"
        @click="goBack"
      >
        返回文章
      </button>
    </div>

    <PptSlideViewer
      v-else-if="slides.length"
      :slides="slides"
      :current-index="currentIndex"
      :current-step="currentStep"
      :slide-direction="slideDirection"
      :is-fullscreen="isFullscreen"
      :show-thumbnails="showThumbnails"
      :toolbar-visible="toolbarVisible"
      :template-vars="templateVars"
      :slide-transition-forward="slideTransitionForward"
      :slide-transition-backward="slideTransitionBackward"
      :reveal-transition="revealTransition"
      class="flex-1 min-h-0 relative"
      @advance="advance"
      @retreat="retreat"
      @go-to-slide="goToSlide"
    />

    <div v-else class="flex-1 flex items-center justify-center text-white/50 text-sm">
      暂无幻灯片内容
    </div>
  </div>
</template>
