<script setup lang="ts">
/**
 * PPT 幻灯片预览器：主视图、缩略图、分步揭示交互
 */
import { computed } from 'vue'
import Icon from '../Icon.vue'
import PptSlideCanvas from './PptSlideCanvas.vue'
import type { PptSlide } from '../../utils/articlePptSlides'
import { getSlideStepCount, isMediaInteractionTarget } from '../../utils/articlePptSlides'
import type { SlideDirection } from '../../composables/usePptPresentation'
import '../../styles/pptPreview.css'

interface Props {
  slides: PptSlide[]
  currentIndex: number
  currentStep: number
  slideDirection?: SlideDirection
  isFullscreen?: boolean
  showThumbnails?: boolean
  toolbarVisible?: boolean
  templateVars?: Record<string, string>
  slideTransitionForward?: string
  slideTransitionBackward?: string
  revealTransition?: string
}

const props = withDefaults(defineProps<Props>(), {
  slideDirection: 'none',
  isFullscreen: false,
  showThumbnails: true,
  toolbarVisible: true,
  templateVars: () => ({}),
  slideTransitionForward: 'ppt-slide',
  slideTransitionBackward: 'ppt-slide-back',
  revealTransition: 'ppt-reveal',
})

const emit = defineEmits<{
  advance: []
  retreat: []
  goToSlide: [index: number]
}>()

const total = computed(() => props.slides.length)
const currentSlide = computed(() => props.slides[props.currentIndex])

const stepTotal = computed(() => {
  const slide = currentSlide.value
  return slide ? getSlideStepCount(slide) : 1
})

const canRetreat = computed(() => props.currentStep > 0 || props.currentIndex > 0)

const canAdvance = computed(() => {
  const slide = currentSlide.value
  if (!slide) return false
  const maxStep = getSlideStepCount(slide) - 1
  return props.currentStep < maxStep || props.currentIndex < props.slides.length - 1
})

const showThumbnailsBar = computed(
  () => props.showThumbnails && (!props.isFullscreen || props.toolbarVisible)
)

const isEdgeToEdge = computed(() => props.isFullscreen && !props.toolbarVisible)

const FULL_STEP = Number.POSITIVE_INFINITY

const slideTransitionName = computed(() =>
  props.slideDirection === 'backward'
    ? props.slideTransitionBackward
    : props.slideTransitionForward
)

const handleSlideClick = (e: MouseEvent) => {
  if (e.button !== 0) return
  if (isMediaInteractionTarget(e.target)) return
  emit('advance')
}

const handleSlideContextMenu = (e: MouseEvent) => {
  e.preventDefault()
  emit('retreat')
}
</script>

<template>
  <div
    class="ppt-preview-root ppt-viewer flex flex-col flex-1 min-h-0 w-full"
    :class="{ 'ppt-viewer--fullscreen': isEdgeToEdge }"
    :style="templateVars"
  >
    <div class="ppt-stage">
      <button
        type="button"
        class="ppt-nav-btn ppt-nav-btn--prev"
        :disabled="!canRetreat"
        aria-label="上一步"
        @click="emit('retreat')"
      >
        <Icon name="chevron-left" :size="24" />
      </button>

      <div
        class="ppt-slide-scaler cursor-pointer select-none"
        @click="handleSlideClick"
        @contextmenu="handleSlideContextMenu"
      >
        <Transition :name="slideTransitionName">
          <PptSlideCanvas
            v-if="currentSlide"
            :key="currentIndex"
            :slide="currentSlide"
            :visible-step="currentStep"
            :slide-direction="slideDirection"
            :template-vars="templateVars"
            :reveal-transition="revealTransition"
          />
        </Transition>
      </div>

      <button
        type="button"
        class="ppt-nav-btn ppt-nav-btn--next"
        :disabled="!canAdvance"
        aria-label="下一步"
        @click="emit('advance')"
      >
        <Icon name="chevron-right" :size="24" />
      </button>
    </div>

    <Transition
      enter-active-class="transition duration-200 ease-out"
      enter-from-class="opacity-0 translate-y-2"
      enter-to-class="opacity-100 translate-y-0"
      leave-active-class="transition duration-150 ease-in"
      leave-from-class="opacity-100 translate-y-0"
      leave-to-class="opacity-0 translate-y-2"
    >
      <div
        v-if="showThumbnailsBar"
        class="ppt-thumbnails-bar flex-shrink-0 border-t border-white/10 bg-black/60 backdrop-blur-md px-4 py-3"
      >
        <div class="flex gap-2 overflow-x-auto pb-1 max-w-full mx-auto">
          <button
            v-for="(slide, idx) in slides"
            :key="idx"
            type="button"
            class="ppt-thumbnail"
            :class="{ 'ppt-thumbnail--active': idx === currentIndex }"
            :aria-label="`第 ${idx + 1} 页`"
            @click="emit('goToSlide', idx)"
          >
            <div class="ppt-thumbnail-inner">
              <PptSlideCanvas
                :slide="slide"
                compact
                :visible-step="FULL_STEP"
                :template-vars="templateVars"
                :reveal-transition="revealTransition"
              />
            </div>
          </button>
        </div>
      </div>
    </Transition>

    <div
      v-if="!isFullscreen || toolbarVisible"
      class="absolute bottom-20 md:bottom-24 left-1/2 -translate-x-1/2 px-3 py-1 rounded-full bg-black/50 text-white/60 text-xs font-mono pointer-events-none z-10"
    >
      {{ currentIndex + 1 }} / {{ total }}
      <span class="text-white/30 mx-1">·</span>
      {{ currentStep + 1 }} / {{ stepTotal }}
    </div>

    <div
      v-if="!isFullscreen"
      class="absolute bottom-4 right-4 text-[10px] text-white/30 hidden md:block pointer-events-none text-right leading-relaxed z-10"
    >
      左键/滚轮下/方向键 → 下一步<br />
      右键/滚轮上 → 上一步 · F 全屏
    </div>
  </div>
</template>
