<template>
  <view class="video-player-container">
    <!-- 视频播放器 -->
    <view class="video-wrapper">
      <video
        v-if="!player.showError.value && player.videoUrl.value"
        :id="videoId"
        :src="player.videoUrl.value"
        :poster="player.posterUrl.value"
        :controls="true"
        :page-gesture="true"
        :vslide-gesture="true"
        :vslide-gesture-in-fullscreen="true"
        :show-center-play-btn="true"
        :show-fullscreen-btn="true"
        :show-play-btn="true"
        :show-progress="true"
        :enable-play-gesture="true"
        :enable-progress-gesture="true"
        :object-fit="objectFit"
        :autoplay="true"
        :initial-time="initialTime"
        class="video-element"
        @play="play"
        @pause="pause"
        @ended="ended"
        @timeupdate="timeupdate"
        @error="error"
        @fullscreenchange="fullscreenChange"
        @waiting="waiting"
        @loadedmetadata="loadedmetadata"
      />
      
      <!-- 倒计时遮罩 - 使用 cover-view 在 APP 中显示 -->
      <cover-view v-if="showCountdown" class="countdown-overlay">
        <cover-view class="countdown-content">
          <cover-view class="countdown-timer">
            <cover-view class="countdown-number">{{ countdownRemaining }}</cover-view>
            <cover-view class="countdown-text">秒后播放下一个视频</cover-view>
          </cover-view>
          
          <cover-view class="countdown-actions">
            <cover-view class="btn-cancel" @click="cancelCountdown">取消</cover-view>
            <cover-view class="btn-replay" @click="replayVideo">重新播放</cover-view>
            <cover-view class="btn-next" @click="playNext">立即播放</cover-view>
          </cover-view>
        </cover-view>
      </cover-view>
      
      <!-- 错误显示 -->
      <view v-if="player.showError.value" class="error-display">
        <view class="error-content">
          <view class="error-message">{{ player.errorMessage.value }}</view>
          <button v-if="player.canRetry.value" class="btn-retry" @click="retry">重试</button>
        </view>
      </view>
      
      <!-- 加载中 -->
      <view v-if="player.isLoading.value" class="loading-display">
        <view class="loading-spinner"></view>
        <text class="loading-text">加载中...</text>
      </view>
    </view>
  </view>
</template>

<script setup lang="ts">
import { ref, watch, onMounted, onUnmounted, nextTick } from 'vue'
import { useVideoPlayer } from './composables/useVideoPlayer'
import { videoStorage } from '@/utils/videoStorage'
import type { IVideoPlayerProps, IVideoInfo } from '@/types/video'

// 页面生命周期
// @ts-ignore
const onHide = typeof uni !== 'undefined' ? uni.onHide || (() => {}) : () => {}

// Props
const props = withDefaults(defineProps<IVideoPlayerProps>(), {
  countdownSeconds: 5,
  showWatermark: false,
  watermarkText: '本课程版权归天津众妙之门科技有限公司所有，翻版必究!'
})

// Emits
const emit = defineEmits<{
  play: [videoInfo: IVideoInfo]
  pause: [position: number]
  fullscreen: [isFullscreen: boolean]
  error: [error: { type: string; message: string }]
  ended: [videoInfo: IVideoInfo]
  timeupdate: [data: { currentTime: number; duration: number }]
  'video-change': [newIndex: number]
  'update:current-index': [newIndex: number]
  'countdown-start': []
  'countdown-cancel': []
}>()

// 使用 composables
const player = useVideoPlayer(props)

// 视频相关状态
const videoId = 'video-player-' + Date.now()
const videoContext = ref<any>(null)
const duration = ref(0)
const isPlaying = ref(false)
const isFullScreen = ref(false)
const showCountdown = ref(false)
const countdownRemaining = ref(props.countdownSeconds)
const objectFit = ref<'contain' | 'cover'>('contain')
const initialTime = ref(0)
let countdownTimer: any = null

// 生命周期
onMounted(async () => {
  // 初始化视频上下文
  videoContext.value = uni.createVideoContext(videoId)

  // 加载视频信息
  const videoInfo = await player.loadVideo(props.currentIndex)

  if (videoInfo) {
    // 设置初始播放位置（loadVideo 内部已经调用过 getInitialPosition）
    // 这里再次获取是为了确保 initialTime 和 video 组件同步
    const position = player.videoProgress.getInitialPosition(videoInfo)
    initialTime.value = position
    console.log('Set initial time:', position, 'for video:', videoInfo.id)
    
    // 如果有历史进度，使用 seek 跳转（因为 initial-time 可能不生效）
    if (position > 0) {
      setTimeout(() => {
        videoContext.value?.seek(position)
        console.log('Seek to position:', position)
      }, 500) // 延迟 500ms 确保视频已加载
    }
    
    // 开始保存进度
    player.videoProgress.startSaving(videoInfo)
  }
})

// 页面隐藏时保存进度
onHide(() => {
  console.log('Page hidden, saving progress...')
  if (player.currentVideoData.value && player.videoProgress.currentTime.value > 0) {
    // 立即保存到本地
    videoStorage.saveVideoPosition(
      player.currentVideoData.value.id,
      Math.floor(player.videoProgress.currentTime.value),
      player.currentVideoData.value
    )
    // 保存到服务器
    player.videoProgress.saveToServer(
      player.currentVideoData.value.id,
      Math.floor(player.videoProgress.currentTime.value)
    )
  }
})

onUnmounted(() => {
  console.log('Component unmounting, saving progress...')
  
  // 停止进度保存
  player.videoProgress.stopSaving()

  // 立即保存当前播放进度（同步保存到本地，异步保存到服务器）
  if (player.currentVideoData.value && player.videoProgress.currentTime.value > 0) {
    // 立即保存到本地
    videoStorage.saveVideoPosition(
      player.currentVideoData.value.id,
      Math.floor(player.videoProgress.currentTime.value),
      player.currentVideoData.value
    )
    // 保存到服务器（不等待完成）
    player.videoProgress.saveToServer(
      player.currentVideoData.value.id,
      Math.floor(player.videoProgress.currentTime.value)
    )
  }

  // 清除倒计时
  if (countdownTimer) {
    clearInterval(countdownTimer)
  }

  // 恢复竖屏
  // #ifdef APP-PLUS
  plus.screen.lockOrientation('portrait-primary')
  // #endif
})

// 监听 currentIndex 变化（仅当外部主动修改时才触发）
watch(
  () => props.currentIndex,
  async (newIndex, oldIndex) => {
    // 只有当新值与组件内部维护的索引不同时才处理
    // 这样可以避免组件内部切换视频时触发 watch
    if (newIndex !== player.currentIndex.value) {
      await player.changeVideo(newIndex)
    }
  }
)

// 事件处理
const play = () => {
  isPlaying.value = true
  if (player.currentVideoData.value) {
    emit('play', player.currentVideoData.value)
  }
}

const pause = () => {
  isPlaying.value = false
  emit('pause', player.videoProgress.currentTime.value)
  
  // 暂停时保存进度
  if (player.currentVideoData.value && player.videoProgress.currentTime.value > 0) {
    videoStorage.saveVideoPosition(
      player.currentVideoData.value.id,
      Math.floor(player.videoProgress.currentTime.value),
      player.currentVideoData.value
    )
    player.videoProgress.saveToServer(
      player.currentVideoData.value.id,
      Math.floor(player.videoProgress.currentTime.value)
    )
  }
}

const ended = () => {
  if (player.currentVideoData.value) {
    emit('ended', player.currentVideoData.value)

    // 检查是否有下一个视频
    if (player.currentIndex.value < props.videoList.length - 1) {
      startCountdown()
    }
  }
}

const timeupdate = (e: any) => {
  const currentTime = e.detail.currentTime
  const videoDuration = e.detail.duration

  player.videoProgress.updateCurrentTime(currentTime)
  duration.value = videoDuration

  emit('timeupdate', {
    currentTime,
    duration: videoDuration
  })
}

const error = (e: any) => {
  console.error('Video error:', e)
  player.showError.value = true
  player.errorMessage.value = '视频播放出错，请稍后重试'
  player.canRetry.value = true

  emit('error', {
    type: 'VIDEO_LOAD_ERROR',
    message: '视频播放出错'
  })
}

const fullscreenChange = (e: any) => {
  isFullScreen.value = e.detail.fullScreen

  // #ifdef APP-PLUS
  if (e.detail.fullScreen) {
    // 进入全屏，锁定横屏
    setTimeout(() => {
      plus.screen.lockOrientation('landscape-primary')
    }, 100)
  } else {
    // 退出全屏，恢复竖屏
    setTimeout(() => {
      plus.screen.lockOrientation('portrait-primary')
    }, 100)
  }
  // #endif

  emit('fullscreen', isFullScreen.value)
}

const waiting = () => {
  // 视频缓冲中
  console.log('Video waiting...')
}

const loadedmetadata = (e: any) => {
  duration.value = e.detail.duration
  console.log('Video metadata loaded, duration:', duration.value)
}

// 倒计时相关
const startCountdown = () => {
  showCountdown.value = true
  countdownRemaining.value = props.countdownSeconds
  emit('countdown-start')

  countdownTimer = setInterval(() => {
    countdownRemaining.value--

    if (countdownRemaining.value <= 0) {
      clearInterval(countdownTimer)
      playNext()
    }
  }, 1000)
}

const cancelCountdown = () => {
  if (countdownTimer) {
    clearInterval(countdownTimer)
    countdownTimer = null
  }
  showCountdown.value = false
  emit('countdown-cancel')
}

const replayVideo = () => {
  cancelCountdown()

  // 重置播放位置并播放
  initialTime.value = 0
  player.videoProgress.updateCurrentTime(0)
  
  // 重新加载当前视频
  player.loadVideo(player.currentIndex.value)
}

const playNext = async () => {
  cancelCountdown()

  const nextIndex = player.currentIndex.value + 1
  if (nextIndex < props.videoList.length) {
    await player.changeVideo(nextIndex)
    
    // 通知父组件更新 currentIndex
    emit('update:current-index', nextIndex)
    emit('video-change', nextIndex)

    // 获取新视频的初始播放位置
    if (player.currentVideoData.value) {
      initialTime.value = player.videoProgress.getInitialPosition(player.currentVideoData.value)
      player.videoProgress.startSaving(player.currentVideoData.value)
    }
  }
}

const retry = () => {
  player.retry()
}
</script>

<style lang="scss" scoped>
.video-player-container {
  width: 100%;
  height: 100%;
  position: relative;
  background-color: #000;
}

.video-wrapper {
  width: 100%;
  height: 100%;
  position: relative;
}

.video-element {
  width: 100%;
  height: 400rpx;
}

.error-display {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: rgba(0, 0, 0, 0.8);
}

.error-content {
  text-align: center;
  padding: 40rpx;
}

.error-icon {
  font-size: 80rpx;
  margin-bottom: 20rpx;
}

.error-message {
  color: #fff;
  font-size: 28rpx;
  line-height: 1.6;
  margin-bottom: 30rpx;
}

.btn-retry {
  background-color: #1989fa;
  color: #fff;
  border: none;
  padding: 20rpx 40rpx;
  border-radius: 8rpx;
  font-size: 28rpx;
}

.loading-display {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  background-color: rgba(0, 0, 0, 0.5);
}

.loading-spinner {
  width: 60rpx;
  height: 60rpx;
  border: 4rpx solid rgba(255, 255, 255, 0.3);
  border-top-color: #fff;
  border-radius: 50%;
  animation: spin 1s linear infinite;
}

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

.loading-text {
  color: #fff;
  font-size: 28rpx;
  margin-top: 20rpx;
}

.countdown-overlay {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.8);
  z-index: 9999;
}

.countdown-content {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 600rpx;
  margin-left: -300rpx;
  margin-top: -150rpx;
  text-align: center;
}

.countdown-timer {
  margin-bottom: 60rpx;
}

.countdown-number {
  color: #fff;
  font-size: 32px;
  font-weight: bold;
  line-height: 1.2;
  text-align: center;
}

.countdown-text {
  color: #fff;
  font-size: 16px;
  line-height: 50rpx;
  text-align: center;
  margin-top: 20rpx;
}

.countdown-actions {
  display: flex;
  flex-direction: row;
  justify-content: center;
  align-items: center;
  width: 100%;
}

.btn-cancel,
.btn-replay,
.btn-next {
  padding: 0 20px;
  text-align: center;
  border-radius: 4px;
  font-size: 14px;
  height: 26px;
  line-height: 26px;
  color: #fff;
  margin: 0 5px;
  background-color: #666;
}

// .btn-cancel {
//   background-color: #666;
// }

// .btn-replay {
//   background-color: #ff9800;
// }

// .btn-next {
//   background-color: #1989fa;
// }
</style>
