/**
 * RegisterController 单元测试
 * 
 * 功能描述：
 * - 测试注册控制器的HTTP请求处理
 * - 验证API响应格式和状态码
 * - 测试邮箱验证流程
 * 
 * 最近修改：
 * - 2026-01-14: 架构重构 - 从business层移动到gateway层 (修改者: moyin)
 * - 2026-01-12: 代码规范优化 - 创建缺失的控制器测试文件 (修改者: moyin)
 * 
 * @author moyin
 * @version 1.1.0
 * @since 2026-01-12
 * @lastModified 2026-01-14
 */

import { Test, TestingModule } from '@nestjs/testing';
import { Response } from 'express';
import { HttpStatus } from '@nestjs/common';
import { RegisterController } from './register.controller';
import { RegisterService } from '../../business/auth/register.service';

describe('RegisterController', () => {
  let controller: RegisterController;
  let registerService: jest.Mocked<RegisterService>;
  let mockResponse: jest.Mocked<Response>;

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

    const module: TestingModule = await Test.createTestingModule({
      controllers: [RegisterController],
      providers: [
        {
          provide: RegisterService,
          useValue: mockRegisterService,
        },
      ],
    }).compile();

    controller = module.get<RegisterController>(RegisterController);
    registerService = module.get(RegisterService);

    // Mock Response object
    mockResponse = {
      status: jest.fn().mockReturnThis(),
      json: jest.fn().mockReturnThis(),
    } as any;
  });

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

  describe('register', () => {
    it('should handle successful registration', async () => {
      const registerDto = {
        username: 'newuser',
        password: 'password123',
        nickname: '新用户',
        email: 'newuser@example.com',
        email_verification_code: '123456'
      };

      const mockResult = {
        success: true,
        data: {
          user: { 
            id: '1', 
            username: 'newuser',
            nickname: '新用户',
            role: 1,
            created_at: new Date()
          },
          access_token: 'token',
          refresh_token: 'refresh_token',
          expires_in: 3600,
          token_type: 'Bearer',
          is_new_user: true,
          message: '注册成功'
        },
        message: '注册成功'
      };

      registerService.register.mockResolvedValue(mockResult);

      await controller.register(registerDto, mockResponse);

      expect(registerService.register).toHaveBeenCalledWith(registerDto);
      expect(mockResponse.status).toHaveBeenCalledWith(HttpStatus.CREATED);
      expect(mockResponse.json).toHaveBeenCalledWith(mockResult);
    });

    it('should handle registration failure', async () => {
      const registerDto = {
        username: 'existinguser',
        password: 'password123',
        nickname: '用户'
      };

      const mockResult = {
        success: false,
        message: '用户名已存在',
        error_code: 'REGISTER_FAILED'
      };

      registerService.register.mockResolvedValue(mockResult);

      await controller.register(registerDto, mockResponse);

      expect(mockResponse.status).toHaveBeenCalledWith(HttpStatus.BAD_REQUEST);
      expect(mockResponse.json).toHaveBeenCalledWith(mockResult);
    });
  });

  describe('sendEmailVerification', () => {
    it('should handle email verification in production mode', async () => {
      const sendEmailDto = {
        email: 'test@example.com'
      };

      const mockResult = {
        success: true,
        data: { is_test_mode: false },
        message: '验证码已发送，请查收邮件'
      };

      registerService.sendEmailVerification.mockResolvedValue(mockResult);

      await controller.sendEmailVerification(sendEmailDto, mockResponse);

      expect(registerService.sendEmailVerification).toHaveBeenCalledWith('test@example.com');
      expect(mockResponse.status).toHaveBeenCalledWith(HttpStatus.OK);
      expect(mockResponse.json).toHaveBeenCalledWith(mockResult);
    });

    it('should handle email verification in test mode', async () => {
      const sendEmailDto = {
        email: 'test@example.com'
      };

      const mockResult = {
        success: false,
        data: { 
          verification_code: '123456',
          is_test_mode: true 
        },
        message: '⚠️ 测试模式：验证码已生成但未真实发送。请在控制台查看验证码，或配置邮件服务以启用真实发送。',
        error_code: 'TEST_MODE_ONLY'
      };

      registerService.sendEmailVerification.mockResolvedValue(mockResult);

      await controller.sendEmailVerification(sendEmailDto, mockResponse);

      expect(mockResponse.status).toHaveBeenCalledWith(HttpStatus.PARTIAL_CONTENT);
      expect(mockResponse.json).toHaveBeenCalledWith(mockResult);
    });
  });

  describe('verifyEmail', () => {
    it('should handle email verification successfully', async () => {
      const verifyEmailDto = {
        email: 'test@example.com',
        verification_code: '123456'
      };

      const mockResult = {
        success: true,
        message: '邮箱验证成功'
      };

      registerService.verifyEmailCode.mockResolvedValue(mockResult);

      await controller.verifyEmail(verifyEmailDto, mockResponse);

      expect(registerService.verifyEmailCode).toHaveBeenCalledWith('test@example.com', '123456');
      expect(mockResponse.status).toHaveBeenCalledWith(HttpStatus.OK);
      expect(mockResponse.json).toHaveBeenCalledWith(mockResult);
    });

    it('should handle invalid verification code', async () => {
      const verifyEmailDto = {
        email: 'test@example.com',
        verification_code: '000000'
      };

      const mockResult = {
        success: false,
        message: '验证码错误',
        error_code: 'INVALID_VERIFICATION_CODE'
      };

      registerService.verifyEmailCode.mockResolvedValue(mockResult);

      await controller.verifyEmail(verifyEmailDto, mockResponse);

      expect(mockResponse.status).toHaveBeenCalledWith(HttpStatus.BAD_REQUEST);
      expect(mockResponse.json).toHaveBeenCalledWith(mockResult);
    });
  });

  describe('resendEmailVerification', () => {
    it('should handle resend email verification successfully', async () => {
      const sendEmailDto = {
        email: 'test@example.com'
      };

      const mockResult = {
        success: true,
        data: { is_test_mode: false },
        message: '验证码已重新发送，请查收邮件'
      };

      registerService.resendEmailVerification.mockResolvedValue(mockResult);

      await controller.resendEmailVerification(sendEmailDto, mockResponse);

      expect(registerService.resendEmailVerification).toHaveBeenCalledWith('test@example.com');
      expect(mockResponse.status).toHaveBeenCalledWith(HttpStatus.OK);
      expect(mockResponse.json).toHaveBeenCalledWith(mockResult);
    });
  });
});
