/**
 * 考试倒计时预警器工具类 (绝对时间戳版)
 * 适用场景：固定时长的考试倒计时，切屏/休眠不暂停
 */
export default class WarningCountdown {
  /**
   * @param {Object} options 配置项
   * @param {Number} options.totalSeconds - 倒计时总秒数
   * @param {Function} options.onTick - 每秒回调，返回当前剩余秒数
   * @param {Function} options.onWarning - 触发预警时的回调 (剩余秒数)
   * @param {Function} options.onFinished - 倒计时结束时的回调
   */
  constructor(options) {
    this.totalSeconds = options.totalSeconds || 0;
    this.onTick = options.onTick || (() => {});
    this.onWarning = options.onWarning || (() => {});
    this.onFinished = options.onFinished || (() => {});

    // 内部状态
    this.remainingTime = this.totalSeconds;
    this.isRunning = false;
    this.isFinished = false;
    this.isManualPaused = false;
    this.isWarningTriggered = false; // 预警是否已触发
    this.timerId = null;

    // ⚠️ 核心：绝对结束时间戳（不受切屏、休眠影响）
    this.endTimeStamp = 0;

    // ⚠️ 移除 visibilitychange 监听，考试倒计时不需要切屏暂停
  }

  /**
   * 获取当前剩余秒数
   */
  getRemainingSeconds() {
    return this.remainingTime;
  }

  /**
   * 内部核心：启动定时器
   */
  _startEngine() {
    // 如果是首次启动，计算绝对结束时间
    if (this.endTimeStamp === 0) {
      this.endTimeStamp = Date.now() + this.remainingTime * 1000;
    }

    this.timerId = setInterval(() => {
      const now = Date.now();
      // ⚠️ 核心：直接用绝对结束时间减去当前时间，得出剩余秒数
      const rawRemaining = (this.endTimeStamp - now) / 1000;
      const newRemaining = Math.ceil(rawRemaining > 0 ? rawRemaining : 0);

      // 1. 更新剩余时间
      this.remainingTime = newRemaining;

      // 2. 每秒通知
      this.onTick(this.remainingTime);

      // 3. 预警逻辑判断
      if (!this.isWarningTriggered && this.remainingTime > 0) {
        const total = this.totalSeconds;
        let shouldWarn = false;

        if (total > 300) {
          // 大于5分钟：最后5分钟预警
          if (this.remainingTime <= 300) shouldWarn = true;
        } else if (total >= 60) {
          // 不大于5分钟，但大于等于1分钟：最后1分钟预警
          if (this.remainingTime <= 60) shouldWarn = true;
        }

        if (shouldWarn) {
          this.isWarningTriggered = true;
          this.onWarning(this.remainingTime);
        }
      }

      // 4. 倒计时结束判断
      if (this.remainingTime <= 0) {
        this._finish();
      }
    }, 1000);
  }

  /**
   * 内部核心：停止定时器
   */
  _stopEngine() {
    clearInterval(this.timerId);
    this.timerId = null;
  }

  /**
   * 启动/继续倒计时
   */
  start() {
    if (this.isFinished || this.isRunning) return;
    if (this.isManualPaused) return; // 仅受手动暂停控制

    this.isRunning = true;
    this._startEngine();
  }

  /**
   * 手动暂停倒计时（注意：仅允许用户主动点击暂停，切屏不会暂停）
   */
  pause() {
    if (!this.isRunning) return;
    this.isRunning = false;
    this.isManualPaused = true;
    this._stopEngine();
  }

  /**
   * 切换暂停/继续状态（二合一）
   */
  toggle() {
    if (this.isFinished) return;
    if (this.isRunning) {
      this.pause();
    } else {
      this.start();
    }
  }

  /**
   * 重置并启动（用于多目标切换）
   */
  resetAndStart(newOptions) {
    this._stopEngine();
    this.isRunning = false;
    this.isManualPaused = false;

    this.totalSeconds = newOptions.totalSeconds || 0;
    this.onTick = newOptions.onTick || (() => {});
    this.onWarning = newOptions.onWarning || (() => {});
    this.onFinished = newOptions.onFinished || (() => {});

    this.remainingTime = this.totalSeconds;
    this.isFinished = false;
    this.isWarningTriggered = false;

    // ⚠️ 重置绝对时间戳，重新计算
    this.endTimeStamp = 0;

    this.isRunning = true;
    this._startEngine();
  }

  /**
   * 彻底清除定时器
   */
  clear() {
    this._stopEngine();
    this.isRunning = false;
    this.isManualPaused = false;
    this.remainingTime = this.totalSeconds;
    this.isFinished = false;
    this.isWarningTriggered = false;
    this.endTimeStamp = 0;

    this.onTick = null;
    this.onWarning = null;
    this.onFinished = null;
  }

  /**
   * 内部方法：倒计时结束
   */
  _finish() {
    this._stopEngine();
    this.isRunning = false;
    this.isFinished = true;
    this.remainingTime = 0;
    this.onFinished();
  }

  /**
   * 销毁方法
   */
  destroy() {
    this.clear();
  }
}
