/**
 * RegisterService 单元测试
 * 
 * 功能描述：
 * - 测试用户注册相关的业务逻辑
 * - 验证邮箱验证功能
 * - 测试Zulip账号集成
 * 
 * 最近修改：
 * - 2026-01-15: 代码规范优化 - 清理未使用的变量apiKeySecurityService (修改者: moyin)
 * - 2026-01-12: 代码分离 - 从login.service.spec.ts中分离注册相关测试
 * 
 * @author moyin
 * @version 1.0.1
 * @since 2026-01-12
 * @lastModified 2026-01-15
 */

import { Test, TestingModule } from '@nestjs/testing';
import { RegisterService } from './register.service';
import { LoginCoreService } from '../../core/login_core/login_core.service';
import { ZulipAccountService } from '../../core/zulip_core/services/zulip_account.service';
import { ApiKeySecurityService } from '../../core/zulip_core/services/api_key_security.service';

describe('RegisterService', () => {
  let service: RegisterService;
  let loginCoreService: jest.Mocked<LoginCoreService>;
  let zulipAccountService: jest.Mocked<ZulipAccountService>;

  const mockUser = {
    id: BigInt(1),
    username: 'testuser',
    nickname: 'Test User',
    email: 'test@example.com',
    phone: null,
    avatar_url: null,
    role: 1,
    created_at: new Date(),
    updated_at: new Date(),
    password_hash: 'hashed_password',
    github_id: null,
    is_active: true,
    last_login_at: null,
    email_verified: false,
    phone_verified: false,
  };

  beforeEach(async () => {
    const mockLoginCoreService = {
      register: jest.fn(),
      sendEmailVerification: jest.fn(),
      verifyEmailCode: jest.fn(),
      resendEmailVerification: jest.fn(),
      deleteUser: jest.fn(),
      generateTokenPair: jest.fn(),
    };

    const mockZulipAccountService = {
      initializeAdminClient: jest.fn(),
      createZulipAccount: jest.fn(),
      linkGameAccount: jest.fn(),
    };

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

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

    const module: TestingModule = await Test.createTestingModule({
      providers: [
        RegisterService,
        {
          provide: LoginCoreService,
          useValue: mockLoginCoreService,
        },
        {
          provide: ZulipAccountService,
          useValue: mockZulipAccountService,
        },
        {
          provide: 'ZulipAccountsService',
          useValue: mockZulipAccountsService,
        },
        {
          provide: ApiKeySecurityService,
          useValue: mockApiKeySecurityService,
        },
      ],
    }).compile();

    service = module.get<RegisterService>(RegisterService);
    loginCoreService = module.get(LoginCoreService);
    zulipAccountService = module.get(ZulipAccountService);

    // 设置默认的mock返回值
    const mockTokenPair = {
      access_token: 'mock_access_token',
      refresh_token: 'mock_refresh_token',
      expires_in: 3600,
      token_type: 'Bearer',
    };

    loginCoreService.generateTokenPair.mockResolvedValue(mockTokenPair);
    zulipAccountService.initializeAdminClient.mockResolvedValue(true);
    zulipAccountService.createZulipAccount.mockResolvedValue({
      success: true,
      userId: 123,
      email: 'test@example.com',
      apiKey: 'mock_api_key',
      isExistingUser: false
    });
  });

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

  describe('register', () => {
    it('should handle user registration successfully', async () => {
      loginCoreService.register.mockResolvedValue({
        user: mockUser,
        isNewUser: true
      });

      const result = await service.register({
        username: 'testuser',
        password: 'password123',
        nickname: 'Test User',
        email: 'test@example.com'
      });

      expect(result.success).toBe(true);
      expect(result.data?.user.username).toBe('testuser');
      expect(result.data?.is_new_user).toBe(true);
      expect(loginCoreService.register).toHaveBeenCalled();
    });

    it('should handle registration failure', async () => {
      loginCoreService.register.mockRejectedValue(new Error('Registration failed'));

      const result = await service.register({
        username: 'testuser',
        password: 'password123',
        nickname: 'Test User',
        email: 'test@example.com'
      });

      expect(result.success).toBe(false);
      expect(result.message).toContain('Registration failed');
    });
  });

  describe('sendEmailVerification', () => {
    it('should handle sendEmailVerification in test mode', async () => {
      loginCoreService.sendEmailVerification.mockResolvedValue({
        code: '123456',
        isTestMode: true
      });

      const result = await service.sendEmailVerification('test@example.com');

      expect(result.success).toBe(false); // Test mode returns false
      expect(result.data?.verification_code).toBe('123456');
      expect(result.data?.is_test_mode).toBe(true);
      expect(loginCoreService.sendEmailVerification).toHaveBeenCalledWith('test@example.com');
    });

    it('should handle sendEmailVerification in production mode', async () => {
      loginCoreService.sendEmailVerification.mockResolvedValue({
        code: '123456',
        isTestMode: false
      });

      const result = await service.sendEmailVerification('test@example.com');

      expect(result.success).toBe(true);
      expect(result.data?.is_test_mode).toBe(false);
      expect(loginCoreService.sendEmailVerification).toHaveBeenCalledWith('test@example.com');
    });
  });

  describe('verifyEmailCode', () => {
    it('should handle verifyEmailCode successfully', async () => {
      loginCoreService.verifyEmailCode.mockResolvedValue(true);

      const result = await service.verifyEmailCode('test@example.com', '123456');

      expect(result.success).toBe(true);
      expect(result.message).toBe('邮箱验证成功');
      expect(loginCoreService.verifyEmailCode).toHaveBeenCalledWith('test@example.com', '123456');
    });

    it('should handle invalid verification code', async () => {
      loginCoreService.verifyEmailCode.mockResolvedValue(false);

      const result = await service.verifyEmailCode('test@example.com', '123456');

      expect(result.success).toBe(false);
      expect(result.message).toBe('验证码错误');
    });
  });

  describe('resendEmailVerification', () => {
    it('should handle resendEmailVerification successfully', async () => {
      loginCoreService.resendEmailVerification.mockResolvedValue({
        code: '654321',
        isTestMode: false
      });

      const result = await service.resendEmailVerification('test@example.com');

      expect(result.success).toBe(true);
      expect(result.data?.is_test_mode).toBe(false);
      expect(loginCoreService.resendEmailVerification).toHaveBeenCalledWith('test@example.com');
    });
  });
});