/**
 * 维护模式检测服务
 * 
 * 功能：
 * 1. 检测后端服务是否可用
 * 2. 连续失败达到阈值时判定为维护模式
 * 3. 自动轮询检测服务恢复
 */

class MaintenanceDetector {
  private failureCount = 0;
  private readonly FAILURE_THRESHOLD = 3; // 连续失败3次判定为维护
  private readonly RESET_INTERVAL = 60000; // 60秒后重置计数
  private resetTimer: NodeJS.Timeout | null = null;
  private recoveryCheckTimer: NodeJS.Timeout | null = null;

  /**
   * 记录请求失败
   */
  recordFailure() {
    this.failureCount++;
    console.log(`[MaintenanceDetector] 请求失败次数: ${this.failureCount}/${this.FAILURE_THRESHOLD}`);

    // 清除之前的重置计时器
    if (this.resetTimer) {
      clearTimeout(this.resetTimer);
    }

    // 60秒后自动重置计数（避免误判网络抖动）
    this.resetTimer = setTimeout(() => {
      console.log('[MaintenanceDetector] 重置失败计数');
      this.failureCount = 0;
    }, this.RESET_INTERVAL);

    // 达到阈值，判定为维护模式
    if (this.failureCount >= this.FAILURE_THRESHOLD) {
      this.enterMaintenanceMode();
    }
  }

  /**
   * 记录请求成功
   */
  recordSuccess() {
    if (this.failureCount > 0) {
      console.log('[MaintenanceDetector] 请求成功，重置失败计数');
      this.failureCount = 0;
    }

    // 清除重置计时器
    if (this.resetTimer) {
      clearTimeout(this.resetTimer);
      this.resetTimer = null;
    }
  }

  /**
   * 进入维护模式
   */
  private enterMaintenanceMode() {
    console.log('[MaintenanceDetector] ========== 进入维护模式 ==========');
    console.log('[MaintenanceDetector] 当前路径:', window.location.pathname);

    // 标记维护状态到 sessionStorage
    sessionStorage.setItem('maintenance_mode', 'true');
    sessionStorage.setItem('maintenance_start_time', Date.now().toString());
    console.log('[MaintenanceDetector] sessionStorage 已设置');

    // 跳转到维护页面
    if (window.location.pathname !== '/maintenance') {
      console.log('[MaintenanceDetector] 准备跳转到 /maintenance');
      console.log('[MaintenanceDetector] 使用 window.location.replace 跳转...');
      
      // 使用 setTimeout 确保跳转执行
      setTimeout(() => {
        window.location.replace('/maintenance');
      }, 100);
    } else {
      console.log('[MaintenanceDetector] 已在维护页面，无需跳转');
    }

    // 开始轮询检测恢复
    this.startRecoveryCheck();
  }

  /**
   * 定期检测服务恢复
   */
  private startRecoveryCheck() {
    // 避免重复启动
    if (this.recoveryCheckTimer) {
      return;
    }

    console.log('[MaintenanceDetector] 开始轮询检测服务恢复（每30秒）');

    this.recoveryCheckTimer = setInterval(async () => {
      try {
        // 尝试请求 Spring Boot Actuator 健康检查端点（无需认证）
        // 使用原生fetch避免触发axios拦截器
        const response = await fetch('/actuator/health', {
          method: 'GET',
          cache: 'no-cache',
          signal: AbortSignal.timeout(3000)
        });

        // 只有返回 200-299 才算真正恢复
        // 500+ 错误不算恢复
        if (response.ok) {
          // 服务恢复
          console.log('[MaintenanceDetector] 服务已恢复！');
          this.exitMaintenanceMode();
        } else {
          console.log(`[MaintenanceDetector] 服务仍不可用 (状态码: ${response.status})`);
        }
      } catch (error) {
        console.log('[MaintenanceDetector] 服务检测失败，继续等待...');
      }
    }, 30000); // 每30秒检查一次
  }

  /**
   * 退出维护模式
   */
  private exitMaintenanceMode() {
    console.log('[MaintenanceDetector] 退出维护模式');

    // 清除维护状态
    sessionStorage.removeItem('maintenance_mode');
    sessionStorage.removeItem('maintenance_start_time');

    // 停止轮询
    if (this.recoveryCheckTimer) {
      clearInterval(this.recoveryCheckTimer);
      this.recoveryCheckTimer = null;
    }

    // 重置失败计数
    this.failureCount = 0;

    // 刷新页面（返回应用）
    window.location.href = '/';
  }

  /**
   * 手动检测恢复（供维护页面调用）
   */
  async checkRecovery(): Promise<boolean> {
    try {
      const response = await fetch('/actuator/health', {
        method: 'GET',
        cache: 'no-cache',
        signal: AbortSignal.timeout(3000)
      });

      // 只有返回 200-299 才算真正恢复
      if (response.ok) {
        this.exitMaintenanceMode();
        return true;
      }
      return false;
    } catch {
      return false;
    }
  }

  /**
   * 获取维护开始时间
   */
  getMaintenanceStartTime(): number | null {
    const startTime = sessionStorage.getItem('maintenance_start_time');
    return startTime ? parseInt(startTime, 10) : null;
  }

  /**
   * 检查是否在维护模式
   */
  isInMaintenanceMode(): boolean {
    return sessionStorage.getItem('maintenance_mode') === 'true';
  }
}

// 导出单例
export const maintenanceDetector = new MaintenanceDetector();
