/**
 * 聊天业务模块测试
 * 
 * 测试范围：
 * - 模块配置验证
 * - 服务提供者注册
 * - 接口导出验证
 * 
 * @author moyin
 * @version 1.0.1
 * @since 2026-01-14
 * @lastModified 2026-01-19
 * 
 * 修改记录：
 * - 2026-01-19 moyin: Bug修复 - 添加缺失的ZulipAccountsService Mock配置
 */

import { Test, TestingModule } from '@nestjs/testing';
import { Logger } from '@nestjs/common';
import { ChatService } from './chat.service';
import { ChatSessionService } from './services/chat_session.service';
import { ChatFilterService } from './services/chat_filter.service';
import { ChatCleanupService } from './services/chat_cleanup.service';
import { SESSION_QUERY_SERVICE } from '../../core/session_core/session_core.interfaces';
import { LoginCoreService } from '../../core/login_core/login_core.service';

describe('ChatModule', () => {
  let module: TestingModule;
  let chatService: ChatService;
  let sessionService: ChatSessionService;
  let filterService: ChatFilterService;
  let cleanupService: ChatCleanupService;

  // Mock依赖
  const mockZulipClientPool = {
    createUserClient: jest.fn(),
    destroyUserClient: jest.fn(),
    sendMessage: jest.fn(),
    getUserClient: jest.fn(),
  };

  const mockZulipConfigService = {
    getStreamByMap: jest.fn().mockReturnValue('Test Stream'),
    findNearbyObject: jest.fn().mockReturnValue(null),
    getAllMapIds: jest.fn().mockReturnValue(['novice_village', 'whale_port']),
  };

  const mockApiKeySecurityService = {
    getApiKey: jest.fn(),
    deleteApiKey: jest.fn(),
  };

  const mockRedisService = {
    get: jest.fn(),
    setex: jest.fn(),
    del: jest.fn(),
    sadd: jest.fn(),
    srem: jest.fn(),
    smembers: jest.fn(),
    expire: jest.fn(),
    incr: jest.fn(),
  };

  const mockLoginCoreService = {
    verifyToken: jest.fn(),
  };

  const mockZulipAccountsService = {
    findByGameUserId: jest.fn(),
  };

  beforeEach(async () => {
    // 禁用日志输出
    jest.spyOn(Logger.prototype, 'log').mockImplementation();
    jest.spyOn(Logger.prototype, 'error').mockImplementation();
    jest.spyOn(Logger.prototype, 'warn').mockImplementation();

    module = await Test.createTestingModule({
      providers: [
        ChatService,
        ChatSessionService,
        ChatFilterService,
        ChatCleanupService,
        {
          provide: SESSION_QUERY_SERVICE,
          useExisting: ChatSessionService,
        },
        {
          provide: 'ZULIP_CLIENT_POOL_SERVICE',
          useValue: mockZulipClientPool,
        },
        {
          provide: 'ZULIP_CONFIG_SERVICE',
          useValue: mockZulipConfigService,
        },
        {
          provide: 'API_KEY_SECURITY_SERVICE',
          useValue: mockApiKeySecurityService,
        },
        {
          provide: 'REDIS_SERVICE',
          useValue: mockRedisService,
        },
        {
          provide: LoginCoreService,
          useValue: mockLoginCoreService,
        },
        {
          provide: 'ZulipAccountsService',
          useValue: mockZulipAccountsService,
        },
      ],
    }).compile();

    chatService = module.get<ChatService>(ChatService);
    sessionService = module.get<ChatSessionService>(ChatSessionService);
    filterService = module.get<ChatFilterService>(ChatFilterService);
    cleanupService = module.get<ChatCleanupService>(ChatCleanupService);
  });

  afterEach(async () => {
    if (module) {
      await module.close();
    }
    jest.clearAllMocks();
  });

  describe('模块配置', () => {
    it('应该成功编译模块', () => {
      expect(module).toBeDefined();
    });

    it('应该提供 ChatService', () => {
      expect(chatService).toBeDefined();
      expect(chatService).toBeInstanceOf(ChatService);
    });

    it('应该提供 ChatSessionService', () => {
      expect(sessionService).toBeDefined();
      expect(sessionService).toBeInstanceOf(ChatSessionService);
    });

    it('应该提供 ChatFilterService', () => {
      expect(filterService).toBeDefined();
      expect(filterService).toBeInstanceOf(ChatFilterService);
    });

    it('应该提供 ChatCleanupService', () => {
      expect(cleanupService).toBeDefined();
      expect(cleanupService).toBeInstanceOf(ChatCleanupService);
    });
  });

  describe('接口导出', () => {
    it('应该导出 SESSION_QUERY_SERVICE 接口', () => {
      const queryService = module.get(SESSION_QUERY_SERVICE);
      expect(queryService).toBeDefined();
    });

    it('SESSION_QUERY_SERVICE 应该指向 ChatSessionService', () => {
      const queryService = module.get(SESSION_QUERY_SERVICE);
      expect(queryService).toBe(sessionService);
    });

    it('SESSION_QUERY_SERVICE 应该实现 ISessionManagerService 接口', () => {
      const queryService = module.get(SESSION_QUERY_SERVICE);
      expect(typeof queryService.createSession).toBe('function');
      expect(typeof queryService.getSession).toBe('function');
      expect(typeof queryService.destroySession).toBe('function');
      expect(typeof queryService.injectContext).toBe('function');
    });
  });

  describe('服务依赖注入', () => {
    it('ChatService 应该能够获取所有依赖', () => {
      expect(chatService).toBeDefined();
      // 验证私有依赖通过检查服务是否正常工作
      expect(chatService['sessionService']).toBeDefined();
      expect(chatService['filterService']).toBeDefined();
    });

    it('ChatSessionService 应该能够获取所有依赖', () => {
      expect(sessionService).toBeDefined();
    });

    it('ChatFilterService 应该能够获取所有依赖', () => {
      expect(filterService).toBeDefined();
    });

    it('ChatCleanupService 应该能够获取所有依赖', () => {
      expect(cleanupService).toBeDefined();
      expect(cleanupService['sessionService']).toBeDefined();
    });
  });

  describe('服务协作', () => {
    it('ChatService 应该能够调用 ChatSessionService', async () => {
      mockRedisService.get.mockResolvedValue(null);
      const session = await chatService.getSession('test_socket');
      expect(session).toBeNull();
    });

    it('ChatCleanupService 应该能够调用 ChatSessionService', async () => {
      mockRedisService.smembers.mockResolvedValue([]);
      const result = await cleanupService.triggerCleanup();
      expect(result.cleanedCount).toBe(0);
    });
  });

  describe('模块导出验证', () => {
    it('所有导出的服务应该可用', () => {
      // ChatModule 导出的服务
      expect(chatService).toBeDefined();
      expect(sessionService).toBeDefined();
      expect(filterService).toBeDefined();
      expect(cleanupService).toBeDefined();
    });

    it('SESSION_QUERY_SERVICE 应该可供其他模块使用', () => {
      const queryService = module.get(SESSION_QUERY_SERVICE);
      expect(queryService).toBeDefined();
      // 验证接口方法存在
      expect(queryService.createSession).toBeDefined();
      expect(queryService.getSession).toBeDefined();
      expect(queryService.destroySession).toBeDefined();
    });
  });
});
