/**
 * 错误处理服务测试
 * 
 * 功能描述：
 * - 测试ErrorHandlerService的核心功能
 * - 包含属性测试验证错误处理和服务降级
 * - 验证重试机制和指数退避策略
 * - 测试系统负载监控和限流功能
 * 
 * 测试策略：
 * - 使用fast-check进行属性测试，验证错误处理的一致性
 * - 模拟各种错误场景，测试降级策略的有效性
 * - 验证重试机制在不同错误类型下的行为
 * 
 * **Feature: zulip-integration, Property 9: 错误处理和服务降级**
 * **Validates: Requirements 8.1, 8.2, 8.3, 8.4**
 * 
 * 最近修改：
 * - 2026-01-12: 代码规范优化 - 完善测试文件注释规范 (修改者: moyin)
 * 
 * @author angjustinl, moyin
 * @version 1.0.1
 * @since 2025-12-25
 * @lastModified 2026-01-12
 */

import { Test, TestingModule } from '@nestjs/testing';
import { ConfigService } from '@nestjs/config';
import * as fc from 'fast-check';
import {
  ErrorHandlerService,
  ErrorType,
  ServiceStatus,
  LoadStatus,
  ErrorHandlingResult,
  RetryConfig,
} from './error_handler.service';
import { AppLoggerService } from '../../../core/utils/logger/logger.service';

describe('ErrorHandlerService', () => {
  let service: ErrorHandlerService;
  let mockLogger: jest.Mocked<AppLoggerService>;
  let mockConfigService: jest.Mocked<ConfigService>;

  beforeEach(async () => {
    jest.clearAllMocks();

    mockLogger = {
      info: jest.fn(),
      warn: jest.fn(),
      error: jest.fn(),
      debug: jest.fn(),
    } as any;

    mockConfigService = {
      get: jest.fn((key: string, defaultValue?: any) => {
        const config: Record<string, any> = {
          'ZULIP_DEGRADED_MODE_ENABLED': 'true',
          'ZULIP_AUTO_RECONNECT_ENABLED': 'true',
          'ZULIP_MAX_RECONNECT_ATTEMPTS': 5,
          'ZULIP_RECONNECT_BASE_DELAY': 1000,
          'ZULIP_API_TIMEOUT': 30000,
          'ZULIP_MAX_RETRIES': 3,
          'ZULIP_MAX_CONNECTIONS': 1000,
        };
        return config[key] ?? defaultValue;
      }),
    } as any;

    const module: TestingModule = await Test.createTestingModule({
      providers: [
        ErrorHandlerService,
        {
          provide: AppLoggerService,
          useValue: mockLogger,
        },
        {
          provide: ConfigService,
          useValue: mockConfigService,
        },
      ],
    }).compile();

    service = module.get<ErrorHandlerService>(ErrorHandlerService);
  });

  afterEach(async () => {
    // 清理服务资源
    await service.onModuleDestroy();
  });

  it('should be defined', () => {
    expect(service).toBeDefined();
  });

  describe('基础功能测试', () => {
    it('应该正确初始化服务状态', () => {
      expect(service.getServiceStatus()).toBe(ServiceStatus.NORMAL);
      expect(service.getLoadStatus()).toBe(LoadStatus.NORMAL);
      expect(service.isServiceAvailable()).toBe(true);
      expect(service.isDegradedMode()).toBe(false);
    });

    it('应该正确读取配置', () => {
      const config = service.getConfig();
      expect(config.degradedModeEnabled).toBe(true);
      expect(config.autoReconnectEnabled).toBe(true);
      expect(config.maxReconnectAttempts).toBe(5);
      expect(config.apiTimeout).toBe(30000);
      expect(config.maxRetries).toBe(3);
    });
  });

  describe('错误分类测试', () => {
    it('应该正确分类认证错误', async () => {
      const error = { code: 401, message: 'Unauthorized' };
      const result = await service.handleZulipError(error, 'testOperation');
      
      expect(result.shouldRetry).toBe(false);
      expect(result.message).toContain('认证');
    });

    it('应该正确分类频率限制错误', async () => {
      const error = { code: 429, message: 'Too many requests' };
      const result = await service.handleZulipError(error, 'testOperation');
      
      expect(result.shouldRetry).toBe(true);
      expect(result.retryAfter).toBe(60000);
    });

    it('应该正确分类连接错误', async () => {
      const error = { code: 'ECONNREFUSED', message: 'Connection refused' };
      const result = await service.handleZulipError(error, 'testOperation');
      
      expect(result.shouldRetry).toBe(true);
    });

    it('应该正确分类超时错误', async () => {
      const error = { code: 'ETIMEDOUT', message: 'Request timeout' };
      const result = await service.handleZulipError(error, 'testOperation');
      
      expect(result.shouldRetry).toBe(true);
    });
  });

  describe('降级模式测试', () => {
    it('应该正确启用降级模式', async () => {
      await service.enableDegradedMode();
      
      expect(service.isDegradedMode()).toBe(true);
      expect(service.getServiceStatus()).toBe(ServiceStatus.DEGRADED);
    });

    it('应该正确恢复正常模式', async () => {
      await service.enableDegradedMode();
      await service.enableNormalMode();
      
      expect(service.isDegradedMode()).toBe(false);
      expect(service.getServiceStatus()).toBe(ServiceStatus.NORMAL);
    });

    it('降级模式禁用时不应该启用', async () => {
      // 重新创建服务，禁用降级模式
      mockConfigService.get.mockImplementation((key: string, defaultValue?: any) => {
        if (key === 'ZULIP_DEGRADED_MODE_ENABLED') return 'false';
        return defaultValue;
      });

      const module: TestingModule = await Test.createTestingModule({
        providers: [
          ErrorHandlerService,
          { provide: AppLoggerService, useValue: mockLogger },
          { provide: ConfigService, useValue: mockConfigService },
        ],
      }).compile();

      const disabledService = module.get<ErrorHandlerService>(ErrorHandlerService);
      
      await disabledService.enableDegradedMode();
      
      expect(disabledService.isDegradedMode()).toBe(false);
      
      await disabledService.onModuleDestroy();
    });
  });

  describe('重试机制测试', () => {
    it('应该在操作成功时返回结果', async () => {
      const operation = jest.fn().mockResolvedValue('success');
      
      const result = await service.retryWithBackoff(operation);
      
      expect(result).toBe('success');
      expect(operation).toHaveBeenCalledTimes(1);
    });

    it('应该在失败后重试', async () => {
      const operation = jest.fn()
        .mockRejectedValueOnce(new Error('First failure'))
        .mockResolvedValue('success');
      
      const result = await service.retryWithBackoff(operation, { maxRetries: 3, baseDelay: 10 });
      
      expect(result).toBe('success');
      expect(operation).toHaveBeenCalledTimes(2);
    });

    it('应该在达到最大重试次数后抛出错误', async () => {
      const operation = jest.fn().mockRejectedValue(new Error('Always fails'));
      
      await expect(
        service.retryWithBackoff(operation, { maxRetries: 2, baseDelay: 10 })
      ).rejects.toThrow('Always fails');
      
      expect(operation).toHaveBeenCalledTimes(3); // 初始 + 2次重试
    });
  });

  describe('超时执行测试', () => {
    it('应该在操作完成前返回结果', async () => {
      const operation = jest.fn().mockResolvedValue('success');
      
      const result = await service.executeWithTimeout(operation, {
        timeout: 5000,
        operation: 'testOperation',
      });
      
      expect(result).toBe('success');
    });

    it('应该在超时时抛出错误', async () => {
      const operation = jest.fn().mockImplementation(
        () => new Promise(resolve => setTimeout(() => resolve('late'), 1000))
      );
      
      await expect(
        service.executeWithTimeout(operation, {
          timeout: 50,
          operation: 'testOperation',
        })
      ).rejects.toThrow('操作超时');
    });
  });

  describe('连接管理测试', () => {
    it('应该正确更新活跃连接数', () => {
      service.updateActiveConnections(10);
      expect(service.getLoadStatus()).toBe(LoadStatus.NORMAL);
      
      service.updateActiveConnections(690); // 总共700，70%
      expect(service.getLoadStatus()).toBe(LoadStatus.HIGH);
      
      service.updateActiveConnections(200); // 总共900，90%
      expect(service.getLoadStatus()).toBe(LoadStatus.CRITICAL);
    });

    it('应该在负载过高时限制新连接', () => {
      service.updateActiveConnections(950);
      expect(service.shouldLimitNewConnections()).toBe(true);
    });

    it('应该在负载正常时允许新连接', () => {
      service.updateActiveConnections(100);
      expect(service.shouldLimitNewConnections()).toBe(false);
    });
  });

  describe('自动重连测试', () => {
    it('应该成功调度重连', async () => {
      const reconnectCallback = jest.fn().mockResolvedValue(true);
      
      const scheduled = await service.scheduleReconnect({
        userId: 'user1',
        reconnectCallback,
        maxAttempts: 3,
        baseDelay: 10,
      });
      
      expect(scheduled).toBe(true);
      
      // 等待重连完成
      await new Promise(resolve => setTimeout(resolve, 100));
      
      expect(reconnectCallback).toHaveBeenCalled();
    });

    it('应该在重连成功后清理状态', async () => {
      const reconnectCallback = jest.fn().mockResolvedValue(true);
      
      await service.scheduleReconnect({
        userId: 'user1',
        reconnectCallback,
        maxAttempts: 3,
        baseDelay: 10,
      });
      
      // 等待重连完成
      await new Promise(resolve => setTimeout(resolve, 100));
      
      expect(service.getReconnectState('user1')).toBeNull();
    });

    it('应该能够取消重连', async () => {
      const reconnectCallback = jest.fn().mockImplementation(
        () => new Promise(resolve => setTimeout(() => resolve(false), 500))
      );
      
      await service.scheduleReconnect({
        userId: 'user1',
        reconnectCallback,
        maxAttempts: 5,
        baseDelay: 100,
      });
      
      // 立即取消
      service.cancelReconnect('user1');
      
      expect(service.getReconnectState('user1')).toBeNull();
    });

    it('自动重连禁用时不应该调度', async () => {
      // 重新创建服务，禁用自动重连
      mockConfigService.get.mockImplementation((key: string, defaultValue?: any) => {
        if (key === 'ZULIP_AUTO_RECONNECT_ENABLED') return 'false';
        return defaultValue;
      });

      const module: TestingModule = await Test.createTestingModule({
        providers: [
          ErrorHandlerService,
          { provide: AppLoggerService, useValue: mockLogger },
          { provide: ConfigService, useValue: mockConfigService },
        ],
      }).compile();

      const disabledService = module.get<ErrorHandlerService>(ErrorHandlerService);
      const reconnectCallback = jest.fn().mockResolvedValue(true);
      
      const scheduled = await disabledService.scheduleReconnect({
        userId: 'user1',
        reconnectCallback,
        maxAttempts: 3,
        baseDelay: 10,
      });
      
      expect(scheduled).toBe(false);
      expect(reconnectCallback).not.toHaveBeenCalled();
      
      await disabledService.onModuleDestroy();
    });
  });


  /**
   * 属性测试: 错误处理和服务降级
   * 
   * **Feature: zulip-integration, Property 9: 错误处理和服务降级**
   * **Validates: Requirements 8.1, 8.2, 8.3, 8.4**
   * 
   * 对于任何Zulip服务不可用、API超时或连接断开的情况，
   * 系统应该实施适当的错误处理、重试机制或服务降级策略
   */
  describe('Property 9: 错误处理和服务降级', () => {
    /**
     * 属性: 对于任何错误，系统应该返回有效的处理结果
     */
    it('对于任何错误，系统应该返回有效的处理结果', async () => {
      await fc.assert(
        fc.asyncProperty(
          // 生成错误码
          fc.oneof(
            fc.constant(401),
            fc.constant(429),
            fc.constant(500),
            fc.constant('ECONNREFUSED'),
            fc.constant('ETIMEDOUT'),
            fc.integer({ min: 400, max: 599 })
          ),
          // 生成错误消息
          fc.string({ minLength: 1, maxLength: 200 }),
          // 生成操作名称
          fc.string({ minLength: 1, maxLength: 50 }).filter(s => s.trim().length > 0),
          async (errorCode, errorMessage, operation) => {
            const error = { code: errorCode, message: errorMessage };
            
            const result = await service.handleZulipError(error, operation);
            
            // 验证结果结构
            expect(result).toBeDefined();
            expect(typeof result.success).toBe('boolean');
            expect(typeof result.shouldRetry).toBe('boolean');
            expect(typeof result.message).toBe('string');
            expect(result.message.length).toBeGreaterThan(0);
            
            // 如果需要重试，应该有重试延迟
            if (result.shouldRetry && result.retryAfter !== undefined) {
              expect(result.retryAfter).toBeGreaterThan(0);
            }
          }
        ),
        { numRuns: 100 }
      );
    }, 30000);

    /**
     * 属性: 认证错误不应该重试
     */
    it('认证错误不应该重试', async () => {
      await fc.assert(
        fc.asyncProperty(
          fc.string({ minLength: 1, maxLength: 200 }),
          fc.string({ minLength: 1, maxLength: 50 }).filter(s => s.trim().length > 0),
          async (errorMessage, operation) => {
            const error = { code: 401, message: errorMessage };
            
            const result = await service.handleZulipError(error, operation);
            
            // 认证错误不应该重试
            expect(result.shouldRetry).toBe(false);
          }
        ),
        { numRuns: 100 }
      );
    }, 30000);

    /**
     * 属性: 连接错误应该触发重试
     */
    it('连接错误应该触发重试', async () => {
      await fc.assert(
        fc.asyncProperty(
          fc.oneof(
            fc.constant('ECONNREFUSED'),
            fc.constant('ENOTFOUND'),
            fc.constant('connection refused'),
            fc.constant('network error')
          ),
          fc.string({ minLength: 1, maxLength: 50 }).filter(s => s.trim().length > 0),
          async (errorCode, operation) => {
            const error = { code: errorCode, message: `Connection error: ${errorCode}` };
            
            const result = await service.handleConnectionError(error, operation);
            
            // 连接错误应该重试
            expect(result.shouldRetry).toBe(true);
            expect(result.retryAfter).toBeGreaterThan(0);
          }
        ),
        { numRuns: 100 }
      );
    }, 30000);

    /**
     * 属性: 重试机制应该使用指数退避
     */
    it('重试机制应该使用指数退避', async () => {
      await fc.assert(
        fc.asyncProperty(
          fc.integer({ min: 1, max: 2 }), // 减少重试次数
          fc.integer({ min: 10, max: 50 }), // 使用更小的延迟
          async (maxRetries, baseDelay) => {
            let attemptCount = 0;
            
            const operation = jest.fn().mockImplementation(() => {
              attemptCount++;
              return Promise.reject(new Error('Test error'));
            });
            
            try {
              await service.retryWithBackoff(operation, {
                maxRetries,
                baseDelay,
                backoffMultiplier: 2,
                maxDelay: 1000,
              });
            } catch {
              // 预期会失败
            }
            
            // 验证重试次数正确
            expect(attemptCount).toBe(maxRetries + 1);
          }
        ),
        { numRuns: 10 } // 减少运行次数
      );
    }, 30000);

    /**
     * 属性: 超时操作应该在指定时间内返回或抛出错误
     */
    it('超时操作应该在指定时间内返回或抛出错误', async () => {
      await fc.assert(
        fc.asyncProperty(
          fc.integer({ min: 50, max: 200 }),
          fc.string({ minLength: 1, maxLength: 50 }).filter(s => s.trim().length > 0),
          async (timeout, operationName) => {
            const startTime = Date.now();
            
            // 创建一个会超时的操作
            const slowOperation = () => new Promise(resolve => 
              setTimeout(() => resolve('late'), timeout + 100)
            );
            
            try {
              await service.executeWithTimeout(slowOperation, {
                timeout,
                operation: operationName,
              });
              // 如果没有超时，说明操作完成了
            } catch (error) {
              const elapsed = Date.now() - startTime;
              // 应该在超时时间附近抛出错误
              expect(elapsed).toBeLessThan(timeout + 100);
              expect((error as Error).message).toContain('超时');
            }
          }
        ),
        { numRuns: 20 } // 减少运行次数因为涉及实际延迟
      );
    }, 30000);

    /**
     * 属性: 负载状态应该根据连接数正确更新
     */
    it('负载状态应该根据连接数正确更新', async () => {
      await fc.assert(
        fc.asyncProperty(
          fc.integer({ min: 0, max: 2000 }),
          async (connectionCount) => {
            // 重置连接数
            service.updateActiveConnections(-service['activeConnections']);
            service.updateActiveConnections(connectionCount);
            
            const maxConnections = service.getConfig().maxConnections;
            const ratio = connectionCount / maxConnections;
            const loadStatus = service.getLoadStatus();
            
            if (ratio >= 0.9) {
              expect(loadStatus).toBe(LoadStatus.CRITICAL);
            } else if (ratio >= 0.7) {
              expect(loadStatus).toBe(LoadStatus.HIGH);
            } else {
              expect(loadStatus).toBe(LoadStatus.NORMAL);
            }
          }
        ),
        { numRuns: 100 }
      );
    }, 30000);

    /**
     * 属性: 服务健康检查应该返回完整的状态信息
     */
    it('服务健康检查应该返回完整的状态信息', async () => {
      await fc.assert(
        fc.asyncProperty(
          fc.boolean(),
          async (shouldDegrade) => {
            if (shouldDegrade) {
              await service.enableDegradedMode();
            } else {
              await service.enableNormalMode();
            }
            
            const health = await service.checkServiceHealth();
            
            // 验证健康检查结果结构
            expect(health).toBeDefined();
            expect(health.status).toBeDefined();
            expect(health.details).toBeDefined();
            expect(health.details.serviceStatus).toBeDefined();
            expect(health.details.errorCounts).toBeDefined();
            
            // 验证状态一致性
            if (shouldDegrade && service.isDegradedModeEnabled()) {
              expect(health.status).toBe(ServiceStatus.DEGRADED);
            }
          }
        ),
        { numRuns: 50 }
      );
    }, 30000);
  });


  // ==================== 补充测试用例 ====================

  describe('错误统计测试', () => {
    it('应该正确记录和获取错误统计', async () => {
      // 触发几个不同类型的错误
      await service.handleZulipError({ code: 401, message: 'Unauthorized' }, 'auth');
      await service.handleZulipError({ code: 429, message: 'Rate limit' }, 'rate');
      await service.handleZulipError({ code: 401, message: 'Unauthorized' }, 'auth2');

      const stats = service.getErrorStats();
      
      expect(stats.serviceStatus).toBeDefined();
      expect(stats.errorCounts).toBeDefined();
      expect(stats.recentErrors).toBeDefined();
      
      // 应该有认证错误和频率限制错误的记录
      expect(Object.keys(stats.errorCounts).length).toBeGreaterThan(0);
    });

    it('应该能够重置错误统计', async () => {
      // 先产生一些错误
      await service.handleZulipError({ code: 500, message: 'Server error' }, 'test');
      
      service.resetErrorStats();
      
      const stats = service.getErrorStats();
      expect(Object.keys(stats.errorCounts)).toHaveLength(0);
      expect(Object.keys(stats.recentErrors)).toHaveLength(0);
    });
  });

  describe('服务健康检查测试', () => {
    it('应该返回完整的健康状态信息', async () => {
      const health = await service.checkServiceHealth();
      
      expect(health.status).toBeDefined();
      expect(health.details).toBeDefined();
      expect(health.details.serviceStatus).toBeDefined();
      expect(health.details.errorCounts).toBeDefined();
      expect(health.details.lastErrors).toBeDefined();
    });

    it('应该在降级模式下返回正确状态', async () => {
      await service.enableDegradedMode();
      
      const health = await service.checkServiceHealth();
      
      expect(health.status).toBe(ServiceStatus.DEGRADED);
      expect(health.details.degradedModeStartTime).toBeDefined();
    });
  });

  describe('配置获取测试', () => {
    it('应该返回正确的配置信息', () => {
      const config = service.getConfig();
      
      expect(config.degradedModeEnabled).toBe(true);
      expect(config.autoReconnectEnabled).toBe(true);
      expect(config.maxReconnectAttempts).toBe(5);
      expect(config.reconnectBaseDelay).toBe(1000);
      expect(config.apiTimeout).toBe(30000);
      expect(config.maxRetries).toBe(3);
      expect(config.maxConnections).toBe(1000);
    });

    it('应该返回正确的单个配置项', () => {
      expect(service.isDegradedModeEnabled()).toBe(true);
      expect(service.isAutoReconnectEnabled()).toBe(true);
      expect(service.getApiTimeout()).toBe(30000);
      expect(service.getMaxRetries()).toBe(3);
      expect(service.getMaxReconnectAttempts()).toBe(5);
      expect(service.getReconnectBaseDelay()).toBe(1000);
    });

    it('应该返回默认重试配置', () => {
      const retryConfig = service.getDefaultRetryConfig();
      
      expect(retryConfig.maxRetries).toBe(3);
      expect(retryConfig.baseDelay).toBe(1000);
      expect(retryConfig.maxDelay).toBe(30000);
      expect(retryConfig.backoffMultiplier).toBe(2);
    });
  });

  describe('状态检查方法测试', () => {
    it('应该正确检查服务可用性', () => {
      expect(service.isServiceAvailable()).toBe(true);
      
      // 设置为不可用状态（通过私有属性）
      (service as any).serviceStatus = ServiceStatus.UNAVAILABLE;
      expect(service.isServiceAvailable()).toBe(false);
    });

    it('应该正确检查降级模式状态', async () => {
      expect(service.isDegradedMode()).toBe(false);
      
      await service.enableDegradedMode();
      expect(service.isDegradedMode()).toBe(true);
      
      await service.enableNormalMode();
      expect(service.isDegradedMode()).toBe(false);
    });
  });

  describe('连接数管理测试', () => {
    it('应该能够设置最大连接数', () => {
      service.setMaxConnections(500);
      expect(service.getConfig().maxConnections).toBe(500);
    });

    it('应该正确处理负连接数变化', () => {
      service.updateActiveConnections(100);
      service.updateActiveConnections(-150); // 应该不会变成负数
      
      // 活跃连接数不应该小于0
      const loadStatus = service.getLoadStatus();
      expect(loadStatus).toBeDefined();
    });

    it('应该在连接数达到上限时限制新连接', () => {
      service.setMaxConnections(100);
      service.updateActiveConnections(100);
      
      expect(service.shouldLimitNewConnections()).toBe(true);
    });
  });

  describe('带超时和重试的操作执行测试', () => {
    it('应该成功执行带超时和重试的操作', async () => {
      const operation = jest.fn().mockResolvedValue('success');
      
      const result = await service.executeWithTimeoutAndRetry(
        operation,
        { timeout: 1000, operation: 'test' },
        { maxRetries: 2, baseDelay: 10 }
      );
      
      expect(result).toBe('success');
      expect(operation).toHaveBeenCalledTimes(1);
    });

    it('应该在超时后重试', async () => {
      let callCount = 0;
      const operation = jest.fn().mockImplementation(() => {
        callCount++;
        if (callCount === 1) {
          return new Promise(resolve => setTimeout(() => resolve('late'), 200));
        }
        return Promise.resolve('success');
      });
      
      const result = await service.executeWithTimeoutAndRetry(
        operation,
        { timeout: 50, operation: 'test' },
        { maxRetries: 2, baseDelay: 10 }
      );
      
      expect(result).toBe('success');
      expect(operation).toHaveBeenCalledTimes(2);
    });
  });

  describe('重连状态管理测试', () => {
    it('应该正确获取重连状态', async () => {
      const reconnectCallback = jest.fn().mockImplementation(
        () => new Promise(resolve => setTimeout(() => resolve(false), 100))
      );
      
      await service.scheduleReconnect({
        userId: 'user1',
        reconnectCallback,
        maxAttempts: 3,
        baseDelay: 50,
      });
      
      const state = service.getReconnectState('user1');
      expect(state).toBeDefined();
      expect(state?.userId).toBe('user1');
      expect(state?.isReconnecting).toBe(true);
      
      // 清理
      service.cancelReconnect('user1');
    });

    it('应该在重连失败达到最大次数后停止', async () => {
      const reconnectCallback = jest.fn().mockResolvedValue(false);
      
      await service.scheduleReconnect({
        userId: 'user1',
        reconnectCallback,
        maxAttempts: 2,
        baseDelay: 10,
      });
      
      // 等待重连尝试完成
      await new Promise(resolve => setTimeout(resolve, 200));
      
      // 应该尝试了最大次数
      expect(reconnectCallback).toHaveBeenCalledTimes(2);
      
      // 重连状态应该被清理
      expect(service.getReconnectState('user1')).toBeNull();
    });

    it('应该处理重连回调异常', async () => {
      const reconnectCallback = jest.fn().mockRejectedValue(new Error('Reconnect failed'));
      
      await service.scheduleReconnect({
        userId: 'user1',
        reconnectCallback,
        maxAttempts: 2,
        baseDelay: 10,
      });
      
      // 等待重连尝试完成
      await new Promise(resolve => setTimeout(resolve, 200));
      
      // 应该尝试了最大次数
      expect(reconnectCallback).toHaveBeenCalledTimes(2);
      
      // 重连状态应该被清理
      expect(service.getReconnectState('user1')).toBeNull();
    });

    it('应该在已有重连进行时跳过新的重连调度', async () => {
      const reconnectCallback1 = jest.fn().mockImplementation(
        () => new Promise(resolve => setTimeout(() => resolve(false), 200))
      );
      const reconnectCallback2 = jest.fn().mockResolvedValue(true);
      
      // 第一次调度
      const scheduled1 = await service.scheduleReconnect({
        userId: 'user1',
        reconnectCallback: reconnectCallback1,
        maxAttempts: 3,
        baseDelay: 50,
      });
      
      // 第二次调度（应该被跳过）
      const scheduled2 = await service.scheduleReconnect({
        userId: 'user1',
        reconnectCallback: reconnectCallback2,
        maxAttempts: 3,
        baseDelay: 50,
      });
      
      expect(scheduled1).toBe(true);
      expect(scheduled2).toBe(false);
      expect(reconnectCallback2).not.toHaveBeenCalled();
      
      // 清理
      service.cancelReconnect('user1');
    });
  });

  describe('事件发射测试', () => {
    it('应该在启用降级模式时发射事件', async () => {
      const eventListener = jest.fn();
      service.on('degraded_mode_enabled', eventListener);
      
      await service.enableDegradedMode();
      
      expect(eventListener).toHaveBeenCalledWith({
        startTime: expect.any(Date),
      });
    });

    it('应该在重连成功时发射事件', async () => {
      const eventListener = jest.fn();
      service.on('reconnect_success', eventListener);
      
      const reconnectCallback = jest.fn().mockResolvedValue(true);
      
      await service.scheduleReconnect({
        userId: 'user1',
        reconnectCallback,
        maxAttempts: 3,
        baseDelay: 10,
      });
      
      // 等待重连完成
      await new Promise(resolve => setTimeout(resolve, 100));
      
      expect(eventListener).toHaveBeenCalledWith({
        userId: 'user1',
        attempts: 1,
      });
    });

    it('应该在重连失败时发射事件', async () => {
      const eventListener = jest.fn();
      service.on('reconnect_failed', eventListener);
      
      const reconnectCallback = jest.fn().mockResolvedValue(false);
      
      await service.scheduleReconnect({
        userId: 'user1',
        reconnectCallback,
        maxAttempts: 1,
        baseDelay: 10,
      });
      
      // 等待重连完成
      await new Promise(resolve => setTimeout(resolve, 100));
      
      expect(eventListener).toHaveBeenCalledWith({
        userId: 'user1',
        attempts: 1,
      });
    });
  });

  describe('错误处理边界条件测试', () => {
    it('应该处理空错误对象', async () => {
      const result = await service.handleZulipError(null, 'test');
      
      expect(result.success).toBe(false);
      expect(result.shouldRetry).toBe(false);
    });

    it('应该处理没有code和message的错误', async () => {
      const result = await service.handleZulipError({}, 'test');
      
      expect(result.success).toBe(false);
      expect(result.message).toBeDefined();
    });

    it('应该处理错误处理过程中的异常', async () => {
      // 模拟错误分类过程中的异常
      const originalClassifyError = (service as any).classifyError;
      (service as any).classifyError = jest.fn().mockImplementation(() => {
        throw new Error('Classification error');
      });
      
      const result = await service.handleZulipError({ code: 500 }, 'test');
      
      expect(result.success).toBe(false);
      expect(result.message).toContain('错误处理失败');
      
      // 恢复原方法
      (service as any).classifyError = originalClassifyError;
    });
  });

  describe('模块销毁测试', () => {
    it('应该正确清理所有资源', async () => {
      // 设置一些状态
      await service.enableDegradedMode();
      
      const reconnectCallback = jest.fn().mockImplementation(
        () => new Promise(resolve => setTimeout(() => resolve(false), 1000))
      );
      
      await service.scheduleReconnect({
        userId: 'user1',
        reconnectCallback,
        maxAttempts: 5,
        baseDelay: 100,
      });
      
      // 销毁模块
      await service.onModuleDestroy();
      
      // 验证资源被清理
      expect(service.getReconnectState('user1')).toBeNull();
    });
  });

  describe('并发操作测试', () => {
    it('应该处理并发的错误处理请求', async () => {
      const errors = [
        { code: 401, message: 'Unauthorized' },
        { code: 429, message: 'Rate limit' },
        { code: 500, message: 'Server error' },
        { code: 'ECONNREFUSED', message: 'Connection refused' },
      ];
      
      const promises = errors.map((error, index) => 
        service.handleZulipError(error, `operation${index}`)
      );
      
      const results = await Promise.all(promises);
      
      // 所有请求都应该得到处理
      expect(results).toHaveLength(4);
      results.forEach(result => {
        expect(result).toBeDefined();
        expect(typeof result.success).toBe('boolean');
        expect(typeof result.shouldRetry).toBe('boolean');
      });
    });

    it('应该处理并发的重连请求', async () => {
      const users = ['user1', 'user2', 'user3'];
      const reconnectCallback = jest.fn().mockResolvedValue(true);
      
      const promises = users.map(userId => 
        service.scheduleReconnect({
          userId,
          reconnectCallback,
          maxAttempts: 2,
          baseDelay: 10,
        })
      );
      
      const results = await Promise.all(promises);
      
      // 所有重连都应该被调度
      expect(results.every(r => r === true)).toBe(true);
      
      // 等待重连完成
      await new Promise(resolve => setTimeout(resolve, 100));
      
      // 验证所有用户的重连状态都被清理
      users.forEach(userId => {
        expect(service.getReconnectState(userId)).toBeNull();
      });
    });
  });

  describe('性能测试', () => {
    it('应该能够处理大量错误而不影响性能', async () => {
      const startTime = Date.now();
      
      // 处理100个错误
      const promises = Array.from({ length: 100 }, (_, i) => 
        service.handleZulipError({ code: 500, message: `Error ${i}` }, `op${i}`)
      );
      
      await Promise.all(promises);
      
      const elapsed = Date.now() - startTime;
      
      // 应该在合理时间内完成（比如1秒）
      expect(elapsed).toBeLessThan(1000);
    });

    it('应该能够处理大量连接数更新', () => {
      const startTime = Date.now();
      
      // 更新1000次连接数
      for (let i = 0; i < 1000; i++) {
        service.updateActiveConnections(1);
      }
      
      const elapsed = Date.now() - startTime;
      
      // 应该在合理时间内完成
      expect(elapsed).toBeLessThan(100);
    });
  });
});
