/**
 * 配置管理服务测试
 * 
 * 功能描述：
 * - 测试ConfigManagerService的核心功能
 * - 验证配置加载和热重载功能
 * - 测试配置文件监听和自动更新
 * 
 * 职责分离：
 * - 单元测试：测试服务的各个方法功能
 * - 集成测试：测试文件系统交互和配置热重载
 * 
 * 测试策略：
 * - 模拟文件系统操作，测试配置文件的读写功能
 * - 验证配置更新时的事件通知机制
 * 
 * 使用场景：
 * - 开发阶段验证配置管理功能的正确性
 * - CI/CD流程中确保配置相关代码质量
 * - 重构时保证配置功能的稳定性
 * 
 * 最近修改：
 * - 2026-01-12: 代码规范优化 - 移除属性测试到test/property目录，保留单元测试 (修改者: moyin)
 * - 2026-01-12: 代码规范优化 - 完善测试文件注释规范，添加职责分离和使用场景 (修改者: moyin)
 * 
 * @author angjustinl, moyin
 * @version 1.0.3
 * @since 2025-12-25
 * @lastModified 2026-01-12
 */

import { Test, TestingModule } from '@nestjs/testing';
import { ConfigManagerService } from './config_manager.service';
import { AppLoggerService } from '../../utils/logger/logger.service';
import * as fs from 'fs';
import * as fc from 'fast-check';

// Mock fs module
jest.mock('fs');

describe('ConfigManagerService', () => {
  let service: ConfigManagerService;
  let mockLogger: jest.Mocked<AppLoggerService>;
  const mockFs = fs as jest.Mocked<typeof fs>;

  // 默认有效配置
  const validMapConfig = {
    maps: [
      {
        mapId: 'novice_village',
        mapName: '新手村',
        zulipStream: 'Novice Village',
        interactionObjects: [
          {
            objectId: 'notice_board',
            objectName: '公告板',
            zulipTopic: 'Notice Board',
            position: { x: 100, y: 150 }
          }
        ]
      },
      {
        mapId: 'tavern',
        mapName: '酒馆',
        zulipStream: 'Tavern',
        interactionObjects: [
          {
            objectId: 'bar_counter',
            objectName: '吧台',
            zulipTopic: 'Bar Counter',
            position: { x: 150, y: 100 }
          }
        ]
      }
    ]
  };

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

    // 设置测试环境变量
    process.env.NODE_ENV = 'test';
    process.env.ZULIP_SERVER_URL = 'https://test-zulip.com';
    process.env.ZULIP_BOT_EMAIL = 'test-bot@test.com';
    process.env.ZULIP_BOT_API_KEY = 'test-api-key';
    process.env.ZULIP_API_KEY_ENCRYPTION_KEY = '0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef';

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

    // 默认mock fs行为
    mockFs.existsSync.mockReturnValue(true);
    mockFs.readFileSync.mockReturnValue(JSON.stringify(validMapConfig));
    mockFs.writeFileSync.mockImplementation(() => {});
    mockFs.mkdirSync.mockImplementation(() => undefined);

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

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

  afterEach(() => {
    jest.restoreAllMocks();
    // 清理环境变量
    delete process.env.NODE_ENV;
    delete process.env.ZULIP_SERVER_URL;
    delete process.env.ZULIP_BOT_EMAIL;
    delete process.env.ZULIP_BOT_API_KEY;
    delete process.env.ZULIP_API_KEY_ENCRYPTION_KEY;
  });

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

  describe('loadMapConfig - 加载地图配置', () => {
    it('应该成功加载有效的地图配置', async () => {
      await service.loadMapConfig();
      
      const mapIds = service.getAllMapIds();
      expect(mapIds).toContain('novice_village');
      expect(mapIds).toContain('tavern');
    });

    it('应该在配置文件不存在时创建默认配置', async () => {
      mockFs.existsSync.mockReturnValue(false);
      
      await service.loadMapConfig();
      
      expect(mockFs.writeFileSync).toHaveBeenCalled();
    });

    it('应该在配置格式无效时抛出错误', async () => {
      mockFs.readFileSync.mockReturnValue(JSON.stringify({ invalid: 'config' }));
      
      await expect(service.loadMapConfig()).rejects.toThrow('配置格式无效');
    });
  });

  describe('getStreamByMap - 根据地图获取Stream', () => {
    it('应该返回正确的Stream名称', () => {
      const stream = service.getStreamByMap('novice_village');
      expect(stream).toBe('Novice Village');
    });

    it('应该在地图不存在时返回null', () => {
      const stream = service.getStreamByMap('nonexistent');
      expect(stream).toBeNull();
    });

    it('应该在mapId为空时返回null', () => {
      const stream = service.getStreamByMap('');
      expect(stream).toBeNull();
    });
  });

  describe('getMapConfig - 获取地图配置', () => {
    it('应该返回完整的地图配置', () => {
      const config = service.getMapConfig('novice_village');
      expect(config).toBeDefined();
      expect(config?.mapId).toBe('novice_village');
      expect(config?.mapName).toBe('新手村');
      expect(config?.zulipStream).toBe('Novice Village');
    });

    it('应该在地图不存在时返回null', () => {
      const config = service.getMapConfig('nonexistent');
      expect(config).toBeNull();
    });
  });

  describe('getTopicByObject - 根据交互对象获取Topic', () => {
    it('应该返回正确的Topic名称', () => {
      const topic = service.getTopicByObject('novice_village', 'notice_board');
      expect(topic).toBe('Notice Board');
    });

    it('应该在对象不存在时返回null', () => {
      const topic = service.getTopicByObject('novice_village', 'nonexistent');
      expect(topic).toBeNull();
    });

    it('应该在地图不存在时返回null', () => {
      const topic = service.getTopicByObject('nonexistent', 'notice_board');
      expect(topic).toBeNull();
    });
  });

  describe('findNearbyObject - 查找附近的交互对象', () => {
    it('应该找到半径内的交互对象', () => {
      const obj = service.findNearbyObject('novice_village', 110, 160, 50);
      expect(obj).toBeDefined();
      expect(obj?.objectId).toBe('notice_board');
    });

    it('应该在没有附近对象时返回null', () => {
      const obj = service.findNearbyObject('novice_village', 500, 500, 50);
      expect(obj).toBeNull();
    });
  });

  describe('getMapIdByStream - 根据Stream获取地图ID', () => {
    it('应该返回正确的地图ID', () => {
      const mapId = service.getMapIdByStream('Novice Village');
      expect(mapId).toBe('novice_village');
    });

    it('应该支持大小写不敏感查询', () => {
      const mapId = service.getMapIdByStream('novice village');
      expect(mapId).toBe('novice_village');
    });

    it('应该在Stream不存在时返回null', () => {
      const mapId = service.getMapIdByStream('nonexistent');
      expect(mapId).toBeNull();
    });
  });

  describe('validateConfig - 验证配置', () => {
    it('应该对有效配置返回valid=true（除了API Key警告）', async () => {
      const result = await service.validateConfig();
      // 由于测试环境没有设置API Key，会有一个错误
      // 但地图配置应该是有效的
      expect(result.errors.some(e => e.includes('地图配置无效'))).toBe(false);
    });
  });

  describe('validateMapConfigDetailed - 详细验证地图配置', () => {
    it('应该对有效配置返回valid=true', () => {
      const config = {
        mapId: 'test_map',
        mapName: '测试地图',
        zulipStream: 'Test Stream',
        interactionObjects: [] as any[]
      };
      
      const result = service.validateMapConfigDetailed(config);
      expect(result.valid).toBe(true);
      expect(result.errors).toHaveLength(0);
    });

    it('应该检测缺少mapId的错误', () => {
      const config = {
        mapName: '测试地图',
        zulipStream: 'Test Stream',
        interactionObjects: [] as any[]
      };
      
      const result = service.validateMapConfigDetailed(config);
      expect(result.valid).toBe(false);
      expect(result.errors).toContain('缺少mapId字段');
    });

    it('应该检测缺少mapName的错误', () => {
      const config = {
        mapId: 'test_map',
        zulipStream: 'Test Stream',
        interactionObjects: [] as any[]
      };
      
      const result = service.validateMapConfigDetailed(config);
      expect(result.valid).toBe(false);
      expect(result.errors).toContain('缺少mapName字段');
    });

    it('应该检测缺少zulipStream的错误', () => {
      const config = {
        mapId: 'test_map',
        mapName: '测试地图',
        interactionObjects: [] as any[]
      };
      
      const result = service.validateMapConfigDetailed(config);
      expect(result.valid).toBe(false);
      expect(result.errors).toContain('缺少zulipStream字段');
    });

    it('应该检测交互对象中缺少字段的错误', () => {
      const config = {
        mapId: 'test_map',
        mapName: '测试地图',
        zulipStream: 'Test Stream',
        interactionObjects: [
          {
            objectId: 'test_obj',
            // 缺少objectName, zulipTopic, position
          }
        ]
      };
      
      const result = service.validateMapConfigDetailed(config);
      expect(result.valid).toBe(false);
      expect(result.errors.length).toBeGreaterThan(0);
    });
  });

  describe('getConfigStats - 获取配置统计', () => {
    it('应该返回正确的统计信息', () => {
      const stats = service.getConfigStats();
      expect(stats.mapCount).toBe(2);
      expect(stats.totalObjects).toBe(2);
      expect(stats.isValid).toBe(true);
    });
  });

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

  describe('hasMap - 检查地图是否存在', () => {
    it('应该返回true当地图存在时', () => {
      const exists = service.hasMap('novice_village');
      expect(exists).toBe(true);
    });

    it('应该返回false当地图不存在时', () => {
      const exists = service.hasMap('nonexistent');
      expect(exists).toBe(false);
    });

    it('应该处理空字符串输入', () => {
      const exists = service.hasMap('');
      expect(exists).toBe(false);
    });

    it('应该处理null/undefined输入', () => {
      const exists1 = service.hasMap(null as any);
      const exists2 = service.hasMap(undefined as any);
      expect(exists1).toBe(false);
      expect(exists2).toBe(false);
    });
  });

  describe('getAllMapIds - 获取所有地图ID', () => {
    it('应该返回所有地图ID列表', () => {
      const mapIds = service.getAllMapIds();
      expect(mapIds).toContain('novice_village');
      expect(mapIds).toContain('tavern');
      expect(mapIds.length).toBe(2);
    });
  });

  describe('getMapConfigByStream - 根据Stream获取地图配置', () => {
    it('应该返回正确的地图配置', () => {
      const config = service.getMapConfigByStream('Novice Village');
      expect(config).toBeDefined();
      expect(config?.mapId).toBe('novice_village');
    });

    it('应该支持大小写不敏感查询', () => {
      const config = service.getMapConfigByStream('novice village');
      expect(config).toBeDefined();
      expect(config?.mapId).toBe('novice_village');
    });

    it('应该在Stream不存在时返回null', () => {
      const config = service.getMapConfigByStream('nonexistent');
      expect(config).toBeNull();
    });
  });

  describe('getAllStreams - 获取所有Stream名称', () => {
    it('应该返回所有Stream名称列表', () => {
      const streams = service.getAllStreams();
      expect(streams).toContain('Novice Village');
      expect(streams).toContain('Tavern');
      expect(streams.length).toBe(2);
    });
  });

  describe('hasStream - 检查Stream是否存在', () => {
    it('应该返回true当Stream存在时', () => {
      const exists = service.hasStream('Novice Village');
      expect(exists).toBe(true);
    });

    it('应该支持大小写不敏感查询', () => {
      const exists = service.hasStream('novice village');
      expect(exists).toBe(true);
    });

    it('应该返回false当Stream不存在时', () => {
      const exists = service.hasStream('nonexistent');
      expect(exists).toBe(false);
    });

    it('应该处理空字符串输入', () => {
      const exists = service.hasStream('');
      expect(exists).toBe(false);
    });
  });

  describe('findObjectByTopic - 根据Topic查找交互对象', () => {
    it('应该找到正确的交互对象', () => {
      const obj = service.findObjectByTopic('Notice Board');
      expect(obj).toBeDefined();
      expect(obj?.objectId).toBe('notice_board');
      expect(obj?.mapId).toBe('novice_village');
    });

    it('应该支持大小写不敏感查询', () => {
      const obj = service.findObjectByTopic('notice board');
      expect(obj).toBeDefined();
      expect(obj?.objectId).toBe('notice_board');
    });

    it('应该在Topic不存在时返回null', () => {
      const obj = service.findObjectByTopic('nonexistent');
      expect(obj).toBeNull();
    });

    it('应该处理空字符串输入', () => {
      const obj = service.findObjectByTopic('');
      expect(obj).toBeNull();
    });
  });

  describe('getObjectsInMap - 获取地图中的所有交互对象', () => {
    it('应该返回地图中的所有交互对象', () => {
      const objects = service.getObjectsInMap('novice_village');
      expect(objects.length).toBe(1);
      expect(objects[0].objectId).toBe('notice_board');
      expect(objects[0].mapId).toBe('novice_village');
    });

    it('应该在地图不存在时返回空数组', () => {
      const objects = service.getObjectsInMap('nonexistent');
      expect(objects).toEqual([]);
    });
  });

  describe('getConfigFilePath - 获取配置文件路径', () => {
    it('应该返回正确的配置文件路径', () => {
      const filePath = service.getConfigFilePath();
      expect(filePath).toContain('map-config.json');
    });
  });

  describe('configFileExists - 检查配置文件是否存在', () => {
    it('应该返回true当配置文件存在时', () => {
      mockFs.existsSync.mockReturnValue(true);
      const exists = service.configFileExists();
      expect(exists).toBe(true);
    });

    it('应该返回false当配置文件不存在时', () => {
      mockFs.existsSync.mockReturnValue(false);
      const exists = service.configFileExists();
      expect(exists).toBe(false);
    });
  });

  describe('reloadConfig - 热重载配置', () => {
    it('应该成功重载配置', async () => {
      await expect(service.reloadConfig()).resolves.not.toThrow();
    });

    it('应该在配置文件读取失败时抛出错误', async () => {
      mockFs.readFileSync.mockImplementation(() => {
        throw new Error('File read error');
      });

      await expect(service.reloadConfig()).rejects.toThrow();
    });
  });

  describe('getZulipConfig - 获取Zulip配置', () => {
    it('应该返回Zulip配置对象', () => {
      const config = service.getZulipConfig();
      expect(config).toBeDefined();
      expect(config.zulipServerUrl).toBeDefined();
      expect(config.websocketPort).toBeDefined();
    });
  });

  describe('getAllMapConfigs - 获取所有地图配置', () => {
    it('应该返回所有地图配置列表', () => {
      const configs = service.getAllMapConfigs();
      expect(configs.length).toBe(2);
      expect(configs.some(c => c.mapId === 'novice_village')).toBe(true);
      expect(configs.some(c => c.mapId === 'tavern')).toBe(true);
    });
  });

  describe('配置文件监听功能', () => {
    let mockWatcher: any;

    beforeEach(() => {
      mockWatcher = {
        close: jest.fn(),
      };
      (fs.watch as jest.Mock).mockReturnValue(mockWatcher);
    });

    describe('enableConfigWatcher - 启用配置文件监听', () => {
      it('应该成功启用配置文件监听', () => {
        const result = service.enableConfigWatcher();
        expect(result).toBe(true);
        expect(fs.watch).toHaveBeenCalled();
      });

      it('应该在配置文件不存在时返回false', () => {
        mockFs.existsSync.mockReturnValue(false);
        const result = service.enableConfigWatcher();
        expect(result).toBe(false);
      });

      it('应该在已启用时跳过重复启用', () => {
        service.enableConfigWatcher();
        (fs.watch as jest.Mock).mockClear();
        
        const result = service.enableConfigWatcher();
        expect(result).toBe(true);
        expect(fs.watch).not.toHaveBeenCalled();
      });

      it('应该处理fs.watch抛出的错误', () => {
        (fs.watch as jest.Mock).mockImplementation(() => {
          throw new Error('Watch error');
        });

        const result = service.enableConfigWatcher();
        expect(result).toBe(false);
      });
    });

    describe('disableConfigWatcher - 禁用配置文件监听', () => {
      it('应该成功禁用配置文件监听', () => {
        service.enableConfigWatcher();
        service.disableConfigWatcher();
        expect(mockWatcher.close).toHaveBeenCalled();
      });

      it('应该处理未启用监听的情况', () => {
        // 不应该抛出错误
        expect(() => service.disableConfigWatcher()).not.toThrow();
      });
    });

    describe('isConfigWatcherEnabled - 检查监听状态', () => {
      it('应该返回正确的监听状态', () => {
        expect(service.isConfigWatcherEnabled()).toBe(false);
        
        service.enableConfigWatcher();
        expect(service.isConfigWatcherEnabled()).toBe(true);
        
        service.disableConfigWatcher();
        expect(service.isConfigWatcherEnabled()).toBe(false);
      });
    });
  });

  describe('getFullConfiguration - 获取完整配置', () => {
    it('应该返回完整的配置对象', () => {
      const config = service.getFullConfiguration();
      expect(config).toBeDefined();
    });
  });

  describe('updateConfigValue - 更新配置值', () => {
    it('应该成功更新有效的配置值', () => {
      // 这个测试需要模拟fullConfig存在
      const result = service.updateConfigValue('message.rateLimit', 20);
      // 由于测试环境中fullConfig可能未初始化，这里主要测试不抛出异常
      expect(typeof result).toBe('boolean');
    });

    it('应该在配置键不存在时返回false', () => {
      const result = service.updateConfigValue('nonexistent.key', 'value');
      expect(result).toBe(false);
    });

    it('应该处理无效的键路径', () => {
      const result = service.updateConfigValue('', 'value');
      expect(result).toBe(false);
    });
  });

  describe('exportMapConfig - 导出地图配置', () => {
    it('应该成功导出配置到文件', () => {
      const result = service.exportMapConfig();
      expect(result).toBe(true);
      expect(mockFs.writeFileSync).toHaveBeenCalled();
    });

    it('应该处理文件写入错误', () => {
      mockFs.writeFileSync.mockImplementation(() => {
        throw new Error('Write error');
      });

      const result = service.exportMapConfig();
      expect(result).toBe(false);
    });

    it('应该支持自定义文件路径', () => {
      const customPath = '/custom/path/config.json';
      const result = service.exportMapConfig(customPath);
      expect(result).toBe(true);
      expect(mockFs.writeFileSync).toHaveBeenCalledWith(
        customPath,
        expect.any(String),
        'utf-8'
      );
    });
  });

  describe('错误处理测试', () => {
    it('应该处理JSON解析错误', async () => {
      mockFs.readFileSync.mockReturnValue('invalid json');
      
      await expect(service.loadMapConfig()).rejects.toThrow();
    });

    it('应该处理文件系统错误', async () => {
      mockFs.readFileSync.mockImplementation(() => {
        throw new Error('File system error');
      });

      await expect(service.loadMapConfig()).rejects.toThrow();
    });

    it('应该处理配置验证过程中的错误', async () => {
      // 模拟验证过程中抛出异常
      const originalValidateMapConfig = (service as any).validateMapConfig;
      (service as any).validateMapConfig = jest.fn().mockImplementation(() => {
        throw new Error('Validation error');
      });

      const result = await service.validateConfig();
      expect(result.valid).toBe(false);
      expect(result.errors.some(e => e.includes('验证过程出错'))).toBe(true);

      // 恢复原方法
      (service as any).validateMapConfig = originalValidateMapConfig;
    });
  });

  describe('边界条件测试', () => {
    it('应该处理空的地图配置', async () => {
      const emptyConfig = { maps: [] };
      mockFs.readFileSync.mockReturnValue(JSON.stringify(emptyConfig));
      
      await service.loadMapConfig();
      
      const mapIds = service.getAllMapIds();
      expect(mapIds).toEqual([]);
    });

    it('应该处理大量地图配置', async () => {
      const largeConfig = {
        maps: Array.from({ length: 1000 }, (_, i) => ({
          mapId: `map_${i}`,
          mapName: `地图${i}`,
          zulipStream: `Stream${i}`,
          interactionObjects: []
        }))
      };
      mockFs.readFileSync.mockReturnValue(JSON.stringify(largeConfig));
      
      await service.loadMapConfig();
      
      const mapIds = service.getAllMapIds();
      expect(mapIds.length).toBe(1000);
    });

    it('应该处理极长的字符串输入', () => {
      const longString = 'a'.repeat(10000);
      const stream = service.getStreamByMap(longString);
      expect(stream).toBeNull();
    });

    it('应该处理特殊字符输入', () => {
      const specialChars = '!@#$%^&*()[]{}|;:,.<>?';
      const stream = service.getStreamByMap(specialChars);
      expect(stream).toBeNull();
    });
  });

  describe('并发操作测试', () => {
    it('应该处理并发的配置查询', async () => {
      const promises = Array.from({ length: 100 }, () => 
        Promise.resolve(service.getStreamByMap('novice_village'))
      );
      
      const results = await Promise.all(promises);
      results.forEach(result => {
        expect(result).toBe('Novice Village');
      });
    });

    it('应该处理并发的配置重载', async () => {
      const promises = Array.from({ length: 10 }, () => service.reloadConfig());
      
      // 不应该抛出异常
      await expect(Promise.all(promises)).resolves.not.toThrow();
    });
  });

  describe('内存管理测试', () => {
    it('应该正确清理资源', () => {
      service.enableConfigWatcher();
      
      // 模拟模块销毁
      service.onModuleDestroy();
      
      expect(service.isConfigWatcherEnabled()).toBe(false);
    });
  });

  describe('属性测试 - 配置查询一致性', () => {
    /**
     * 属性测试: 配置查询的一致性
     * 验证双向查询的一致性（mapId <-> stream）
     */
    it('mapId和stream之间的双向查询应该保持一致', async () => {
      await fc.assert(
        fc.asyncProperty(
          // 从现有的mapId中选择
          fc.constantFrom('novice_village', 'tavern'),
          async (mapId) => {
            // 通过mapId获取stream
            const stream = service.getStreamByMap(mapId);
            expect(stream).not.toBeNull();
            
            // 通过stream反向获取mapId
            const retrievedMapId = service.getMapIdByStream(stream!);
            expect(retrievedMapId).toBe(mapId);
            
            // 通过stream获取配置
            const config = service.getMapConfigByStream(stream!);
            expect(config).not.toBeNull();
            expect(config!.mapId).toBe(mapId);
          }
        ),
        { numRuns: 50 }
      );
    }, 30000);

    /**
     * 属性测试: 交互对象查询的一致性
     */
    it('交互对象的不同查询方式应该返回一致的结果', async () => {
      await fc.assert(
        fc.asyncProperty(
          fc.constantFrom('novice_village', 'tavern'),
          async (mapId) => {
            // 获取地图中的所有对象
            const objectsInMap = service.getObjectsInMap(mapId);
            
            for (const obj of objectsInMap) {
              // 通过topic查找对象
              const objByTopic = service.findObjectByTopic(obj.zulipTopic);
              expect(objByTopic).not.toBeNull();
              expect(objByTopic!.objectId).toBe(obj.objectId);
              expect(objByTopic!.mapId).toBe(mapId);
              
              // 通过mapId和objectId获取topic
              const topic = service.getTopicByObject(mapId, obj.objectId);
              expect(topic).toBe(obj.zulipTopic);
            }
          }
        ),
        { numRuns: 50 }
      );
    }, 30000);

    /**
     * 属性测试: 配置验证的幂等性
     */
    it('配置验证应该是幂等的', async () => {
      await fc.assert(
        fc.asyncProperty(
          fc.record({
            mapId: fc.string({ minLength: 1, maxLength: 50 }).filter(s => s.trim().length > 0),
            mapName: fc.string({ minLength: 1, maxLength: 100 }).filter(s => s.trim().length > 0),
            zulipStream: fc.string({ minLength: 1, maxLength: 100 }).filter(s => s.trim().length > 0),
            interactionObjects: fc.array(
              fc.record({
                objectId: fc.string({ minLength: 1, maxLength: 50 }).filter(s => s.trim().length > 0),
                objectName: fc.string({ minLength: 1, maxLength: 100 }).filter(s => s.trim().length > 0),
                zulipTopic: fc.string({ minLength: 1, maxLength: 100 }).filter(s => s.trim().length > 0),
                position: fc.record({
                  x: fc.integer({ min: 0, max: 10000 }),
                  y: fc.integer({ min: 0, max: 10000 }),
                }),
              }),
              { maxLength: 5 }
            ),
          }),
          async (config) => {
            // 多次验证同一个配置应该返回相同结果
            const result1 = service.validateMapConfigDetailed(config);
            const result2 = service.validateMapConfigDetailed(config);
            const result3 = service.validateMapConfigDetailed(config);
            
            expect(result1.valid).toBe(result2.valid);
            expect(result2.valid).toBe(result3.valid);
            expect(result1.errors).toEqual(result2.errors);
            expect(result2.errors).toEqual(result3.errors);
          }
        ),
        { numRuns: 100 }
      );
    }, 60000);
  });
});
