<template>
  <div class="video-component">
    <!-- 注意：移除了 :src="url"，因为 src 将由 JS 动态绑定 -->
    <video
      ref="videoRef"
      autoplay controls muted
      preload="metadata"
      class="video-player"
      @timeupdate="onTimeUpdate"
      @loadedmetadata="onLoadedMetadata"
      @pause="saveProgress"
      @ended="onEnded"
    ></video>
  </div>
</template>

<script>
  import Hls from 'hls.js';

  const STORAGE_KEY_PREFIX = 'video_progress_';

  export default {
    name: 'VideoComponent',
    props: {
      userId: {
        type: [String, Number],
        required: true,
      },
      url: {
        type: String,
        required: true,
      },
    },
    data() {
      return {
        _saveTimer: null,
        hls: null, // 新增：存储 hls 实例
      };
    },
    computed: {
      storageKey() {
        const safeUrl = this.url.replace(/[^a-zA-Z0-9]/g, '_').slice(-60);
        return `${STORAGE_KEY_PREFIX}${this.userId}_${safeUrl}`;
      },
    },
    mounted() {
      this.initPlayer();
    },
    methods: {
      // 初始化播放器
      initPlayer() {
        const video = this.$refs.videoRef;
        if (!video) return;

        // 1. 优先检测浏览器是否原生支持 HLS (如 Safari, iOS)
        if (video.canPlayType('application/vnd.apple.mpegurl')) {
          video.src = this.url;
        }
        // 2. 检测是否支持 hls.js (如 Firefox, Chrome)
        else if (Hls.isSupported()) {
          this.hls = new Hls();
          this.hls.loadSource(this.url);
          this.hls.attachMedia(video);

          // 监听 HLS 解析完成事件
          this.hls.on(Hls.Events.MANIFEST_PARSED, () => {
            console.log('HLS 视频源解析完成，准备播放');
          });

          // 监听错误事件
          this.hls.on(Hls.Events.ERROR, (event, data) => {
            if (data.fatal) {
              switch (data.type) {
                case Hls.ErrorTypes.NETWORK_ERROR:
                  console.error('网络错误，尝试恢复...');
                  this.hls.startLoad();
                  break;
                case Hls.ErrorTypes.MEDIA_ERROR:
                  console.error('媒体解码错误，尝试恢复...');
                  this.hls.recoverMediaError();
                  break;
                default:
                  console.error('发生不可恢复的致命错误');
                  this.hls.destroy();
                  break;
              }
            }
          });
        }
        // 3. 都不支持
        else {
          console.error('当前浏览器不支持 HLS 视频播放');
        }
      },

      // 读取上次保存的时间点
      getSavedTime() {
        try {
          const val = localStorage.getItem(this.storageKey);
          return val ? parseFloat(val) : 0;
        } catch {
          return 0;
        }
      },

      // 视频元数据加载完成后跳转到上次位置
      onLoadedMetadata() {
        const saved = this.getSavedTime();
        const video = this.$refs.videoRef;
        if (saved > 0 && video && saved < video.duration - 1) {
          video.currentTime = saved;
        }
      },

      // timeupdate 节流处理
      onTimeUpdate() {
        if (this._saveTimer) return;
        this._saveTimer = setTimeout(() => {
          this._saveTimer = null;
          this.saveProgress();
        }, 5000);
      },

      // 实际写入 localStorage
      saveProgress() {
        const video = this.$refs.videoRef;
        if (!video) return;
        try {
          localStorage.setItem(this.storageKey, String(video.currentTime));
        } catch {
          // localStorage 不可用时静默失败
        }
      },

      // 播放结束时清除记录
      onEnded() {
        try {
          localStorage.removeItem(this.storageKey);
        } catch {
          // ignore
        }
      },
    },
    beforeDestroy() {
      // 1. 清除保存进度的定时器
      if (this._saveTimer) {
        clearTimeout(this._saveTimer);
        this._saveTimer = null;
      }
      // 2. 销毁前立即保存一次进度
      this.saveProgress();

      // 3. 【关键】销毁 hls 实例，释放内存并断开网络连接
      if (this.hls) {
        this.hls.destroy();
        this.hls = null;
      }
    },
  };
</script>

<style scoped lang="scss">
  .video-component {
    width: 100%;

    .video-player {
      width: 1458px;
      height: 797px;
      display: block;
      background: #000;
      border-radius: 6px;
    }
  }
</style>
