<template>
  <div class="video-study-root">
    <div v-if="boxShow" class="video-study">
      <aside class="study-sidebar">
        <div class="sidebar-top">
          <el-button
            type="text"
            icon="el-icon-arrow-left"
            class="back-btn"
            @click="$router.push({ path: '/oa/study/myStudy' })"
          >返回我的学习</el-button>
        </div>

        <div v-if="resource.title" class="resource-title" :title="resource.title">
          {{ resource.title }}
        </div>

        <div class="progress-card">
          <div class="progress-header">
            <span class="progress-label">学习进度</span>
            <span class="progress-percent" :class="progressPercentClass">{{ percentage }}%</span>
          </div>
          <el-progress
            :percentage="percentage"
            :status="formatStatus(percentage)"
            :stroke-width="10"
            :show-text="false"
          />
          <div class="page-stats">
            <span v-if="lastPosition > 0">上次播放 {{ formatTime(lastPosition) }}</span>
            <span v-else>尚未开始播放</span>
            <el-tag v-if="isComplete" type="success" size="mini">已完成</el-tag>
          </div>
          <div v-if="resource.hours" class="hours-info">
            可获得学时：<span>{{ resource.hours }}</span> 小时
          </div>
        </div>

        <div class="tips-card">
          <i class="el-icon-info" />
          <p>视频不可拖动进度条；每 30 秒自动保存，暂停时也会保存。若进度异常，请退出后重新进入课程。</p>
        </div>
      </aside>

      <main class="video-main">
        <div class="video-wrapper">
          <video
            ref="videoPlayer"
            class="video-js vjs-big-play-centered custom-video"
            @play="handlePlay"
            @pause="handlePause"
            @ended="handleEnd"
          />
          <el-alert
            v-if="showProgressTip"
            type="info"
            :closable="false"
            class="resume-alert"
            show-icon
          >
            已为您定位到上次播放位置：{{ formatTime(lastPosition) }}
          </el-alert>
        </div>
      </main>
    </div>

    <div v-else class="mobile-tip">
      <i class="el-icon-monitor" />
      <p>抱歉，暂不支持手机端，请前往电脑端观看学习</p>
    </div>
  </div>
</template>

<script>
import videojs from 'video.js';
import 'video.js/dist/video-js.css';
import { listResource, getResource, delResource, addResource, updateResource } from "@/api/oa/study/resource";
import { listStudy, getStudy, delStudy, addStudy, updateStudy } from "@/api/oa/study/myStudy";

export default {
  data() {
    return {
      baseUrl: process.env.VUE_APP_BASE_API,
      videoId: '',
      videoPath: '',
      player: null,
      lastPosition: 0,
      getHours: '', //可获得的学时
      isComplete: false, //是否已经看完
      showProgressTip: false,
      resource: {},
      // 禁用功能配置
      disabledControls: [
        'progressControl', // 隐藏进度条
        'seekBar',         // 禁用拖拽
        'remainingTimeDisplay',
        'playbackRateMenuButton'
      ],
      videoDuration: undefined,
      percentage: 0,
      boxShow: false,
    };
  },
  watch: {
    videoPath() {
      this.$nextTick(() => {
        const video = this.$refs.videoPlayer;
        if (!video) return;
        video.pause();
        video.removeAttribute("src");
        video.load();
        setTimeout(() => {
          video.src = this.fullVideoPath;
          video.load();
        }, 100);
      });
    }
  },
  computed: {
    fullVideoPath() {
      return `${process.env.VUE_APP_BASE_API}/profile/upload/${this.videoPath}`
    },
    progressPercentClass() {
      if (this.percentage >= 100) return 'is-complete'
      if (this.percentage >= 80) return 'is-high'
      if (this.percentage >= 50) return 'is-mid'
      return 'is-low'
    }
  },
  created() {
    if (this.$store.getters.device === 'mobile') {
      this.boxShow = false;
      return
    } else {
      this.boxShow = true;
    }
    this.getData();
  },
  mounted() {
    this.initPlayer();
    this.loadLastPosition();
  },
  methods: {
    async getData() {
      let studyId = this.$route.params.id;
      let resData = await getStudy(studyId);
      let data = resData.data
      this.resource = data.resource;
      this.videoPath = data.resource.sourcePath;
      this.percentage = Number(data.lastPoint);
      if (Number(data.lastPoint) > 0 && Number(data.lastPoint) < 100) {
        this.showProgressTip = true;
      }
      if (Number(data.lastPoint) == 100) {
        this.isComplete = true;
        this.getHours = data.resource.hours;
        this.$message.warning('视频已学习完毕，若要再次学习，请重新点击复习。')
      }
    },
    // 初始化播放器
    initPlayer() {
      const self = this;
      this.player = videojs(this.$refs.videoPlayer, {
        errorDisplay: false,
        autoplay: false,
        fluid: true,
        controls: true,
        sources: [{ src: this.fullVideoPath, type: 'video/mp4' }],
        controlBar: {
          // children: this.disabledControls,
          // 自定义禁止拖拽的进度条
          progressControl: false, // 关闭进度条
          volumePanel: true      // 启用音量控制
        },
        userActions: {
          hotkeys: false,
          // 禁用双击全屏
          doubleClick: false
        }
      });
      let retryCount = 0;
      // 增加错误监听
      this.player.on('error', () => {
        console.error('播放器错误:', this.player.error());
        if (retryCount < 3) {
          this.player.src(this.fullVideoPath);
          this.player.load();
          retryCount++;
        }
      });

      // 节流保存（每30秒保存一次）
      this.player.on('timeupdate', _.throttle(() => {
        this.saveCurrentPosition();
      }, 30000));
    },
    // 加载上次播放位置
    async loadLastPosition() {
      this.videoId = this.$route.params.id;
      try {
        const { data } = await getStudy(this.videoId);
        const percentage = data.lastPoint || 0;
        // 添加 readyState 检查
        const checkReady = () => {
          return new Promise(resolve => {
            if (this.player.readyState() >= 2) { // HAVE_CURRENT_DATA
              resolve();
            } else {
              this.player.one('loadedmetadata', resolve);
            }
          });
        };
        await checkReady();
        const duration = this.player.duration();
        const targetTime = duration * (percentage / 100);

        // 使用播放器原生方法
        this.player.currentTime(targetTime);
        this.lastPosition = targetTime;

      } catch (error) {
        console.error('加载进度失败:', error);
      }
    },

    // 处理播放事件
    handlePlay() {
      this.player.currentTime(this.lastPosition);
    },

    // 处理暂停事件
    handlePause() {
      this.saveCurrentPosition();
    },

    // 处理视频结束
    async handleEnd() {
      this.$message.warning('视频已学习完毕，若要再次学习，请重新点击复习。')
      await updateStudy({
        studyId: this.videoId,
        lastPoint: 100,
        getHours: this.resource.hours,
        lastTime: this.parseTime(new Date(), '{y}-{m}-{d}')
      });
    },
    // 保存当前进度
    async saveCurrentPosition(isEnd = false) {
      const currentTime = this.player.currentTime();
      const duration = this.player.duration();
      let percentage = isEnd ? 100 : Number(((currentTime / duration) * 100).toFixed(2));
      if (isNaN(percentage)) {
        return
      }
      this.percentage = Number(percentage)
      try {
        if (Number(percentage) == 100) {
          return
        }
        await updateStudy({
          studyId: this.videoId,
          lastPoint: percentage,
          getHours: Math.round((Number(this.resource.hours) * percentage / 100) * 10) / 10,
          lastTime: this.parseTime(new Date(), '{y}-{m}-{d}')
        });
        // 始终更新 lastPosition（即使播放结束）
        this.lastPosition = currentTime;
      } catch (error) {
        console.error('保存进度失败:', error);
      }
    },

    // 时间格式化
    formatTime(seconds) {
      const date = new Date(0);
      date.setSeconds(seconds);
      return date.toISOString().substr(11, 8);
    },
    formatStatus(row) {
      if (!row) {
        row = 0
        return 'exception'
      }
      if (row <= 20) {
        return 'exception'
      } else if (row > 20 && row <= 50) {
        return 'warning'
      } else if (row > 50 && row <= 80) {
        return null
      } else {
        return 'success'
      }
    },
  },
  beforeDestroy() {
    if (this.player) {
      this.player.dispose();
    }
  }
};
</script>

<style lang="scss" scoped>
.video-study-root {
  height: calc(100vh - 84px);
  min-height: 520px;
  background: #f0f2f5;
}

.video-study {
  display: flex;
  height: 100%;
  overflow: hidden;
}

.study-sidebar {
  flex-shrink: 0;
  width: 280px;
  display: flex;
  flex-direction: column;
  gap: 16px;
  padding: 20px 18px;
  background: #fff;
  border-right: 1px solid #e4e7ed;
  box-shadow: 2px 0 8px rgba(0, 0, 0, 0.04);
  overflow-y: auto;
}

.sidebar-top {
  .back-btn {
    padding: 0;
    font-size: 14px;
    color: #409eff;

    &:hover {
      color: #66b1ff;
    }
  }
}

.resource-title {
  font-size: 15px;
  font-weight: 600;
  color: #303133;
  line-height: 1.5;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  word-break: break-all;
}

.progress-card {
  padding: 16px;
  background: linear-gradient(135deg, #f5f9ff 0%, #f0f7ff 100%);
  border: 1px solid #d9ecff;
  border-radius: 8px;
}

.progress-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 12px;
}

.progress-label {
  font-size: 13px;
  color: #606266;
}

.progress-percent {
  font-size: 22px;
  font-weight: 700;
  line-height: 1;

  &.is-low { color: #f56c6c; }
  &.is-mid { color: #e6a23c; }
  &.is-high { color: #409eff; }
  &.is-complete { color: #67c23a; }
}

.page-stats {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-top: 12px;
  font-size: 12px;
  color: #606266;
}

.hours-info {
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px dashed #d9ecff;
  font-size: 12px;
  color: #909399;

  span {
    color: #409eff;
    font-weight: 600;
  }
}

.tips-card {
  display: flex;
  gap: 8px;
  padding: 12px;
  font-size: 12px;
  line-height: 1.6;
  color: #909399;
  background: #fafafa;
  border-radius: 6px;
  border: 1px solid #ebeef5;

  i {
    flex-shrink: 0;
    margin-top: 2px;
    font-size: 14px;
    color: #c0c4cc;
  }

  p {
    margin: 0;
  }
}

.video-main {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  background: #1a1a1a;
}

.video-wrapper {
  position: relative;
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px 32px;
  min-height: 0;
}

.custom-video {
  width: 100%;
  max-width: 1100px;
  max-height: 100%;
}

.video-wrapper ::v-deep .video-js {
  width: 100%;
  max-width: 1100px;
  max-height: calc(100vh - 84px - 48px);
  border-radius: 8px;
  overflow: hidden;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.45);
}

.video-wrapper ::v-deep .vjs-tech {
  border-radius: 8px;
}

.resume-alert {
  position: absolute;
  left: 50%;
  bottom: 32px;
  transform: translateX(-50%);
  width: auto;
  max-width: 480px;
  border-radius: 6px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
}

.mobile-tip {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 100%;
  color: #909399;

  i {
    font-size: 48px;
    margin-bottom: 16px;
  }

  p {
    margin: 0;
    font-size: 14px;
  }
}
</style>