<template>
  <div class="video-container">
    <div class="box-video">
      <!-- 视频 -->
      <template v-if="contentType === 'video'">
        <div class="video-wrapper" :class="{ 'video-paused': isVideoPaused }">
          <video
              class="full-box-video"
              ref="videoRef"
              :controls="true"
              @timeupdate="handleTimeUpdate"
              @seeked="handleSeeked"
              @ended="handleVideoEnded"
              @loadedmetadata="handleLoadedMetadata"
              @pause="handleVideoPause"
              @play="handleVideoPlay"
              @click="handleVideoClick"
          ></video>
          <!-- 历史播放位置提示 -->
          <div
              v-if="showHistoryTip"
              class="history-tip"
              :style="{ left: historyTipPosition + '%' }"
          >
            <el-icon @click.stop="closeHistoryTip" class="close-icon"><CloseBold /></el-icon>
            <span @click="goToLastPosition">回到上次播放位置</span>
          </div>
          <!-- 章节要点小圆点 -->
          <div class="progress-markers" v-if="chapterMarkers.length > 0">
            <div
                v-for="marker in chapterMarkers"
                :key="marker.time"
                class="progress-marker"
                :style="{ left: marker.position + '%' }"
                @click="seekToTime(marker.time)"
            ></div>
          </div>
        </div>
      </template>
    </div>
  </div>
</template>

<script setup>
import {
  ref,
  onMounted,
  onBeforeUnmount,
  defineProps,
  defineEmits,
  watch,
  nextTick
} from 'vue'

import { videoPlay as Vue3VideoPlay } from 'vue3-video-play'
import Hls from 'hls.js'
import { ElMessage } from 'element-plus'
// 导入图标
import { CloseBold, FullScreen, Close } from '@element-plus/icons-vue'


// 定义props
const props = defineProps({
  contentType: { type: String, required: true }, // contentType类型
  videoPath: { type: String }, // 变为可选
  courseId: { type: String, required: true },
  typeId: { type: String, required: true },
  courseConfigList: { type: Array, default: () => [] },
  allIndices: { type: Array, default: () => [] },
  currentIndex: { type: String, required: true }
})

// 定义emits
const emits = defineEmits(['timeUpdate', 'videoEnded', 'switchVideo', 'saveProgress'])

// 视频引用
const videoRef = ref(null)
// HLS实例
const hlsRef = ref(null)
// 记录已经暂停过的时间点索引
const pausedIndices = ref([])
// 记录已经保存的进度百分比
const savedProgress = ref([])
// 节流时间间隔(毫秒)
const THROTTLE_TIME = 3000
// 上次播放进度
const lastPlayProgress = ref(0)
// 定义进度数组
const targetProgresses = [10, 50, 100]
// 章节要点标记
const chapterMarkers = ref([])
// 历史播放位置提示状态
const showHistoryTip = ref(false)
// 上次播放位置时间
const lastPlayTime = ref(0)
// 历史播放提示位置百分比
const historyTipPosition = ref(0)
// 视频是否暂停状态
const isVideoPaused = ref(false)
// 是否处于网页全屏状态
const isWebFullscreen = ref(false)

// 定义节流函数
const throttle = (fn, delay) => {
  let lastCall = 0
  return function (...args) {
    const now = Date.now()
    if (now - lastCall >= delay) {
      lastCall = now
      return fn.apply(this, args)
    }
  }
}

// 保存进度(带节流)
const saveProgress = throttle(async (progress, currentTime) => {
  try {
    // 保存到localStorage，下次加载视频续播
    localStorage.setItem(
        `videoProgress_${props.courseId}`,
        JSON.stringify({
          progress: progress,
          currentTime: currentTime,
          timestamp: Date.now()
        })
    )

    // 通过emit事件通知父组件保存进度
    emits('saveProgress', "course", progress)
    savedProgress.value.push(progress)
  } catch (error) {
    console.error(`保存进度失败:`, error)
  }
}, THROTTLE_TIME)

// 处理视频元数据加载完成
const handleLoadedMetadata = () => {
  if (!videoRef.value) return
  const duration = videoRef.value.duration
  if (duration && props.courseConfigList && props.courseConfigList.length) {
    // 根据courseConfigList生成章节标记，过滤掉ccTime不存在或无效的配置项
    chapterMarkers.value = props.courseConfigList
        .filter(config => config.ccTime !== undefined && config.ccTime !== null && config.ccTime !== '')
        .map(config => ({
          time: config.ccTime,
          position: (config.ccTime / duration) * 100
        }))
  } else {
    // 确保在courseConfigList为空时清空标记
    chapterMarkers.value = []
  }
}

// 跳转到指定时间点
const seekToTime = (time) => {
  if (videoRef.value) {
    videoRef.value.currentTime = time
    // 清除已暂停索引，确保用户点击后可以再次触发暂停
    pausedIndices.value = pausedIndices.value.filter(t => t !== time)
  }
}
// 处理视频时间更新事件
const handleTimeUpdate = ev => {
  if (!videoRef.value) return
  const currentTime = parseInt(ev.target.currentTime)
  const duration = videoRef.value.duration || 0
  // 如果章节标记为空且有课程配置，生成标记
  if (chapterMarkers.value.length === 0 && props.courseConfigList.length && duration > 0) {
    handleLoadedMetadata()
  }

  const progressPercentage =
      duration > 0 ? Math.round((currentTime / duration) * 100) : 0

  // 更新最后播放进度
  lastPlayProgress.value = progressPercentage

  // 检查是否达到目标进度点且尚未保存
  targetProgresses.some(target => {
    const isNearTarget = Math.abs(progressPercentage - target) <= 2
    const isNotSaved = !savedProgress.value.includes(target)
    if (isNearTarget && isNotSaved) {
      // 保存目标进度
      saveProgress(target, currentTime)
      return true
    }
    return false
  })

  // 使用节流保存进度
  saveProgress(progressPercentage, currentTime)

  // 触发父组件的时间更新事件
  emits('timeUpdate', { currentTime, progressPercentage })
  if (!props.courseConfigList.length) return
  props.courseConfigList.forEach(courseCofig => {
    // 暂停时间
    let time = courseCofig.ccTime
    // 检查是否到达时间点且还未暂停过
    if (currentTime === time && !pausedIndices.value.includes(time)) {
      // 无论 ccQuestSource 是什么值，都暂停视频
      videoRef.value.pause()
      // 记录暂停时间
      pausedIndices.value.push(currentTime)
      // 根据 ccQuestSource 的值决定是否显示问题弹框
      // 当 ccQuestSource 为 1 时，显示问题弹框
      if (courseCofig.ccQuestSource === '1' && courseCofig.ccQuestContent) {
        // 触发父组件显示试题
        emits('timeUpdate', {
          currentTime,
          progressPercentage,
          courseConfig: courseCofig
        })
      }
    }
  })
}

// 视频完成拖动进度条时触发的方法
const handleSeeked = () => {
  pausedIndices.value = []
}

// 添加视频结束事件处理
const handleVideoEnded = () => {
  // 视频结束时保存100%进度
  if (!savedProgress.value.includes(100)) {
    // 通过emit事件通知父组件保存进度
    emits('saveProgress', "course", 100)
    savedProgress.value.push(100)
  }

  emits('videoEnded')
}

// 在视频加载完成后设置上次播放进度
const setLastPlayPosition = () => {
  if (!videoRef.value) return
  try {
    const savedData = localStorage.getItem(`videoProgress_${props.courseId}`)
    if (savedData) {
      const { currentTime, progress } = JSON.parse(savedData)
      if (currentTime && !isNaN(currentTime) && currentTime > 0) {
        // 存储上次播放位置但不自动跳转
        lastPlayTime.value = currentTime
        lastPlayProgress.value = progress
        // 计算历史提示位置
        const duration = videoRef.value.duration
        historyTipPosition.value = duration > 0 ? (currentTime / duration) * 100 : 0
        showHistoryTip.value = true

        // 检查是否已有保存的进度点
        if (progress >= 10) savedProgress.value.push(10)
        if (progress >= 50) savedProgress.value.push(50)
        if (progress >= 100) savedProgress.value.push(100)

        // 5秒后自动隐藏历史位置提示
        setTimeout(() => {
          showHistoryTip.value = false
        }, 5000)
      }
    }
  } catch (error) {
    console.error('读取上次播放进度失败:', error)
  }
}

// 跳转到上次播放位置
const goToLastPosition = () => {
  if (videoRef.value && lastPlayTime.value > 0) {
    videoRef.value.currentTime = lastPlayTime.value
    showHistoryTip.value = false
    // 自动播放视频
    videoRef.value.play().catch(error => {
      console.error('自动播放失败:', error)
    })
  }
}

// 关闭历史播放位置提示
const closeHistoryTip = () => {
  showHistoryTip.value = false
}

// 处理视频暂停事件
const handleVideoPause = () => {
  isVideoPaused.value = true
}

// 处理视频播放事件
const handleVideoPlay = () => {
  isVideoPaused.value = false
}

// 处理视频点击事件
const handleVideoClick = (event) => {
  // 阻止浏览器默认的视频点击行为
  event.preventDefault();
  // 阻止事件冒泡，防止其他元素的点击事件影响
  event.stopPropagation();
  
  if (videoRef.value) {
    if (videoRef.value.paused) {
      videoRef.value.play();
    } else {
      videoRef.value.pause();
    }
  }
}

// 初始化视频播放器
const initVideoPlayer = () => {
  if (props.contentType !== 'video') return
  // 使用nextTick确保DOM已经更新
  nextTick(() => {
    if (!videoRef.value) {
      console.error('视频元素未找到')
      return
    }

    // 清理之前的HLS实例
    if (hlsRef.value) {
      hlsRef.value.destroy()
      hlsRef.value = null
    }

    // 为视频元素添加键盘事件监听器
    addVideoKeyboardListener();

    // 检查视频路径是否是m3u8格式
    if (props.videoPath && props.videoPath.toLowerCase().endsWith('.m3u8')) {
      // 使用HLS播放
      if (Hls.isSupported()) {
        hlsRef.value = new Hls()
        hlsRef.value.loadSource(props.videoPath)
        hlsRef.value.attachMedia(videoRef.value)
        hlsRef.value.on(Hls.Events.MANIFEST_PARSED, () => {
          tryPlayVideo()
        })
        hlsRef.value.on(Hls.Events.ERROR, (event, data) => {
          console.error('HLS错误:', data)
          // 只对致命错误显示错误提示
          if (data.fatal) {
            ElMessage.error('视频加载失败，请稍后重试')
          }
        })
      } else if (videoRef.value.canPlayType('application/vnd.apple.mpegurl')) {
        // 对于不支持HLS但支持原生m3u8的浏览器
        videoRef.value.src = props.videoPath
        tryPlayVideo()
      } else {
        ElMessage.error('您的浏览器不支持播放m3u8格式视频')
      }
    } else {
      // 普通视频播放
      videoRef.value.src = props.videoPath
      tryPlayVideo()
    }
  })
}

// 尝试播放视频，处理浏览器自动播放限制
const tryPlayVideo = () => {
  // 确保videoRef存在
  if (!videoRef.value) {
    console.error('视频元素未找到')
    return
  }

  // 自动播放视频
  videoRef.value.play().catch(error => {
    console.error('自动播放失败:', error)
  })

  // 在视频加载完成后设置上次播放进度
  setTimeout(() => {
    setLastPlayPosition()
  }, 1000)
}

// 处理空格键控制播放/暂停
const handleKeyPress = (event) => {
  // 检查是否是空格键且视频元素存在
  if (event.code === 'Space' && videoRef.value) {
    event.preventDefault(); // 防止空格键默认行为
    if (videoRef.value.paused) {
      videoRef.value.play();
    } else {
      videoRef.value.pause();
    }
  }
}

// 为视频元素添加键盘事件监听器
const addVideoKeyboardListener = () => {
  if (videoRef.value) {
    videoRef.value.addEventListener('keydown', handleKeyPress);
  }
}

// 移除视频元素的键盘事件监听器
const removeVideoKeyboardListener = () => {
  if (videoRef.value) {
    videoRef.value.removeEventListener('keydown', handleKeyPress);
  }
}

// 处理视频全屏变化事件
const handleFullscreenChange = () => {
  // 检查是否是浏览器默认的全屏模式
  const isFullscreen = !!(document.fullscreenElement || 
                           document.webkitFullscreenElement || 
                           document.mozFullScreenElement || 
                           document.msFullscreenElement);
  
  if (isFullscreen) {
    // 如果是视频元素触发的全屏，退出默认全屏并调用自定义全屏
    const fullscreenElement = document.fullscreenElement || 
                              document.webkitFullscreenElement || 
                              document.mozFullScreenElement || 
                              document.msFullscreenElement;
    
    if (fullscreenElement === videoRef.value) {
      // 退出浏览器默认全屏
      if (document.exitFullscreen) {
        document.exitFullscreen();
      } else if (document.webkitExitFullscreen) {
        document.webkitExitFullscreen();
      } else if (document.mozCancelFullScreen) {
        document.mozCancelFullScreen();
      } else if (document.msExitFullscreen) {
        document.msExitFullscreen();
      }
      
      // 调用自定义全屏方法
      toggleWebFullscreen();
    }
  }
}

// 组件挂载时
onMounted(() => {
  initVideoPlayer()
  // 键盘事件监听
  document.addEventListener('keydown', handleKeyPress);
  // 添加全屏事件监听
  document.addEventListener('fullscreenchange', handleFullscreenChange);
  document.addEventListener('webkitfullscreenchange', handleFullscreenChange);
  document.addEventListener('mozfullscreenchange', handleFullscreenChange);
  document.addEventListener('MSFullscreenChange', handleFullscreenChange);
})
// 组件卸载时
onBeforeUnmount(() => {
  if (hlsRef.value) {
    hlsRef.value.destroy()
    hlsRef.value = null
  }
  // 确保退出网页全屏
  if (isWebFullscreen.value) {
    const videoWrapper = document.querySelector('.video-wrapper')
    if (videoWrapper) {
      videoWrapper.style.position = ''
      videoWrapper.style.top = ''
      videoWrapper.style.left = ''
      videoWrapper.style.width = '70%'
      videoWrapper.style.height = '100%'
      videoWrapper.style.zIndex = ''
      videoWrapper.style.backgroundColor = ''
    }
  }
  // 移除键盘事件监听
  document.removeEventListener('keydown', handleKeyPress);
  // 移除视频元素的键盘事件监听器
  removeVideoKeyboardListener();
  // 移除全屏事件监听
    document.removeEventListener('fullscreenchange', handleFullscreenChange);
    document.removeEventListener('webkitfullscreenchange', handleFullscreenChange);
    document.removeEventListener('mozfullscreenchange', handleFullscreenChange);
    document.removeEventListener('MSFullscreenChange', handleFullscreenChange);
})

// 监听contentType和videoPath变化
watch([() => props.contentType, () => props.videoPath], () => {
  // 当contentType变为video或videoPath变化时，重新初始化
  if (props.contentType === 'video') {
    initVideoPlayer()
  }
})

// 切换网页全屏
const toggleWebFullscreen = () => {
  const videoWrapper = document.querySelector('.video-wrapper')
  if (!videoWrapper) return

  if (!isWebFullscreen.value) {
    // 进入网页全屏
    videoWrapper.style.position = 'fixed'
    videoWrapper.style.top = '0'
    videoWrapper.style.left = '0'
    videoWrapper.style.width = '100vw'
    videoWrapper.style.height = '100vh'
    videoWrapper.style.zIndex = '9999'
    videoWrapper.style.backgroundColor = 'black'
    videoWrapper.style.display = 'flex'
    videoWrapper.style.justifyContent = 'center'
    videoWrapper.style.alignItems = 'center'

    // 调整视频大小
    const video = videoWrapper.querySelector('.full-box-video')
    if (video) {
      video.style.width = '100%'
      video.style.height = '100%'
      video.style.objectFit = 'contain'
      video.focus();
    }

    isWebFullscreen.value = true
  } else {
    // 退出网页全屏
    videoWrapper.style.position = ''
    videoWrapper.style.top = ''
    videoWrapper.style.left = ''
    videoWrapper.style.width = '70%'
    videoWrapper.style.height = '100%'
    videoWrapper.style.zIndex = ''
    videoWrapper.style.backgroundColor = ''
    videoWrapper.style.display = 'flex'
    videoWrapper.style.justifyContent = 'center'
    videoWrapper.style.alignItems = 'center'

    // 恢复视频大小
    const video = videoWrapper.querySelector('.full-box-video')
    if (video) {
      video.style.width = '100%'
      video.style.height = '100%'
      video.style.objectFit = 'cover'
      video.focus();
    }

    isWebFullscreen.value = false
  }
}

</script>

<style scoped lang="scss">
@use 'sass:math';
// 定义rpx转换函数
@function rpx($px) {
  @return math.div($px, 750) * 100vw;
}
.box-video {
  width: 100%;
  height: rpx(300);
  display: flex;
  justify-content: center;
  align-items: center;
  .d-player-wrap {
    height: rpx(289);
    width: 68.5%;
    border-radius: rpx(12);
    object-fit: cover;
  }
}
.video-wrapper {
  position: relative;
  width: 70%;
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
}
.full-box-video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: rpx(12);
}
.ppt-box{
  width: 100%;
  height: rpx(300);
  display: flex;
  justify-content: center;
  align-items: center;
  position: relative;
}
.ppt-page-info {
  position: absolute;
  bottom: rpx(10); // 距离底部10rpx
  left: 50%; // 水平居中
  transform: translateX(-50%); // 水平居中调整
  background-color: rgba(0, 0, 0, 0.5);
  color: white;
  padding: rpx(3) rpx(8);
  border-radius: rpx(4);
  font-size: rpx(8);
  z-index: 10;
}
.ppt-container {
  width: 70%;
  height: 100%;
  border-radius: rpx(12);
  overflow: hidden;
}
.ppt-container ::v-deep(.pptx-preview-wrapper) {
  // 滚动条整体样式
  &::-webkit-scrollbar {
    width: rpx(0); // 滚动条宽度
    height: rpx(0);
  }
  // 滚动条滑块样式
  &::-webkit-scrollbar-thumb {
    background-color: #e2ddfc; // 滑块颜色
    border-radius: rpx(4); // 滑块圆角
  }
  // 滚动条轨道样式
  &::-webkit-scrollbar-track {
    background-color: rgba(143, 116, 255, 0.2); // 轨道颜色
    border-radius: rpx(4); // 轨道圆角
  }
  // border-radius: rpx(12);
}


.ppt-navigation {
  position: absolute;
  bottom: rpx(18);
  width: 70%;
  display: flex;
  justify-content: center;
  gap: rpx(20);
  padding: 0 rpx(10);
  box-sizing: border-box;
}

.ppt-btn {
  background-color: rgb(255, 255, 255, 0.5);
  color: white;
  border: 1px white solid;
  border-radius: rpx(12);
  font-size: rpx(7);
  cursor: pointer;
  transition: background-color 0.3s;
  display: flex;
  align-items: center;
  justify-content: center;
  height: rpx(15);
}

.ppt-btn:hover {
  background-color: rgba(0, 0, 0, 0.7);
}

.ppt-prev-btn, .ppt-next-btn {
  width: rpx(50);
}


/* 章节要点标记样式 */
.progress-markers {
  position: absolute;
  bottom: 26px;
  left: 15px;
  right: 15px;
  height: 10px;
  pointer-events: none;
  z-index: 10;
  opacity: 0; /* 默认隐藏 */
  transition: opacity 0.3s ease; /* 过渡效果 */
}
.video-wrapper:hover .progress-markers {
  opacity: 1; /* 鼠标悬停在视频上时显示 */
}
/* 当视频控件可见时显示标记 */
video::-webkit-media-controls-panel:not([hidden]) ~ .progress-markers {
  opacity: 1;
}
/* 当视频暂停时显示标记 */
.video-paused .progress-markers {
  opacity: 1;
}
.progress-marker {position: absolute;
  width: rpx(4);
  height: rpx(4);
  background-color: orange;
  border-radius: 50%;
  transform: translateX(-50%);
  cursor: pointer;
  transition: all 0.3s ease;
  pointer-events: all;
}

.progress-marker:hover {
  width: rpx(6);
  height: rpx(6);
}

/* 历史播放位置提示样式 */
.history-tip {
  position: absolute;
  bottom: rpx(22);
  transform: translateX(-50%);
  background-color: rgba(0, 0, 0, 0.5);
  color: white;
  padding: rpx(5) rpx(7);
  border-radius: rpx(4);
  font-size: rpx(6);
  cursor: pointer;
  transition: all 0.3s ease;
  z-index: 20;
  white-space: nowrap;
  display: flex;
  align-items: center;
  gap: rpx(2);
}

.history-tip .close-icon {
  cursor: pointer;
  font-size: rpx(7);
  transition: color 0.3s ease;
}

.history-tip .close-icon:hover {
  color: #ff4d4f;
}

.history-tip::after {
  content: '';
  position: absolute;
  top: 100%;
  left: 50%;
  transform: translateX(-50%);
  border: rpx(4) solid transparent;
  border-top-color: rgba(0, 0, 0, 0.5);
  width: 0;
  height: 0;
}

.history-tip:hover {
  background-color: rgba(0, 0, 0, 0.6);
}

/* 网页全屏按钮样式 */
.fullscreen-btn {
  position: absolute;
  top: 10px;
  right: 10px;
  width: 30px;
  height: 30px;
  background-color: rgba(0, 0, 0, 0.5);
  color: white;
  border-radius: 4px;
  display: flex;
  justify-content: center;
  align-items: center;
  cursor: pointer;
  z-index: 15;
  transition: all 0.3s ease;
}

.fullscreen-btn:hover {
  background-color: rgba(0, 0, 0, 0.7);
}

/* 调整视频控件样式以适应我们的自定义标记 */
video::-webkit-media-controls-timeline {
  margin-bottom: 10px;
}

video::-webkit-media-controls {
  overflow: visible !important;
}

video::-webkit-media-controls-panel {
  width: calc(100% + 30px); /* 扩展控件面板宽度，确保与自定义标记对齐 */
  background: transparent !important; /* 去掉背景渐变，设为透明 */
}

</style>