/**
 * 学习考试系统 - 纯逻辑定时器工具类
 */
export default class StudyTimer {
  /**
   * @param {Object} options 配置项
   * @param {Number} options.initialSeconds - 计时起点（秒）
   * @param {Number} options.maxSeconds - 最大时长（秒）
   * @param {Function} options.onTick - 每秒回调，返回当前总耗时秒数
   * @param {Function} options.onMaxTimeReached - 达到最大时长回调
   */
  constructor(options) {
    this.initialSeconds = options.initialSeconds || 0;
    this.maxSeconds = options.maxSeconds || Infinity;
    this.onTick = options.onTick || (() => {});
    this.onMaxTimeReached = options.onMaxTimeReached || (() => {});

    // 内部状态
    this.elapsedTime = this.initialSeconds;
    this.isRunning = false;
    this.isFinished = false;
    this.isPageVisible = true; // 页面是否可见
    this.timerId = null;
    this.startTimeStamp = 0;

    // 绑定切屏事件，确保 this 指向正确且方便后续移除
    this._handleVisibilityChange = this._handleVisibilityChange.bind(this);
    document.addEventListener('visibilitychange', this._handleVisibilityChange);
  }

  /**
   * 获取当前已耗时的秒数
   */
  getElapsedSeconds() {
    return this.elapsedTime;
  }

  /**
   * 启动/继续计时
   */
  resume() {
    if (this.isRunning || this.isFinished || !this.isPageVisible) return;

    this.isRunning = true;
    // 核心：基于当前时间和已消耗时间，反推基准时间戳
    this.startTimeStamp = Date.now() - this.elapsedTime * 1000;

    this.timerId = setInterval(() => {
      const now = Date.now();
      const rawElapsed = (now - this.startTimeStamp) / 1000; // 获取精确的毫秒级秒数
      const newElapsed = Math.floor(rawElapsed); // 向下取整

      // ⚠️ 核心修复：强制兜底逻辑
      // 只要实际耗时达到最大值，直接强制赋值，确保绝对能触发 maxSeconds
      if (rawElapsed >= this.maxSeconds) {
        this.elapsedTime = this.maxSeconds;
        this._finish();
      } else {
        this.elapsedTime = newElapsed;
        this.onTick(this.elapsedTime);
      }
    }, 1000);
  }

  /**
   * 暂停计时（手动暂停 或 切屏暂停 均调用此方法）
   */
  pause() {
    if (!this.isRunning) return;
    this.isRunning = false;
    clearInterval(this.timerId);
    this.timerId = null;
  }

  /**
   * ⚠️ 新增：重置并启动（用于多目标切换）
   * @param {Object} newOptions - 新的配置项（同 constructor 的参数）
   */
  resetAndStart(newOptions) {
    // 1. 停止当前计时
    this.pause();

    // 2. 移除旧的切屏监听（防止重复绑定）
    document.removeEventListener('visibilitychange', this._handleVisibilityChange);

    // 3. 更新配置和内部状态
    this.initialSeconds = newOptions.initialSeconds || 0;
    this.maxSeconds = newOptions.maxSeconds || Infinity;
    this.onTick = newOptions.onTick || (() => {});
    this.onMaxTimeReached = newOptions.onMaxTimeReached || (() => {});

    this.elapsedTime = this.initialSeconds;
    this.isFinished = false;
    this.isPageVisible = true; // 重置页面可见性状态

    // 4. 重新绑定切屏监听
    document.addEventListener('visibilitychange', this._handleVisibilityChange);

    // 5. 立即启动新计时
    this.resume();
  }

  /**
   * 彻底清除定时器并重置状态
   */
  clear() {
    // 1. 停止计时
    this.pause();
    // 2. 重置状态
    this.elapsedTime = this.initialSeconds;
    this.isFinished = false;
    // 3. 移除切屏监听
    document.removeEventListener('visibilitychange', this._handleVisibilityChange);
    // 4. 清空回调，帮助垃圾回收
    this.onTick = null;
    this.onMaxTimeReached = null;
  }

  /**
   * 内部方法：达到最大值
   */
  _finish() {
    this.pause();
    this.isFinished = true;
    this.onMaxTimeReached(this.elapsedTime);
  }

  /**
   * 内部方法：切屏监听
   */
  _handleVisibilityChange() {
    if (this.isFinished) return;

    if (document.hidden) {
      // 切屏：强制暂停
      this.isPageVisible = false;
      this.pause();
    } else {
      // 切回：自动恢复
      this.isPageVisible = true;
      this.resume();
    }
  }

  /**
   * 销毁方法（语义上用于组件卸载，内部调用 clear）
   */
  destroy() {
    this.clear();
  }
}
