/**
 * LoginController 单元测试
 * 
 * 功能描述：
 * - 测试登录控制器的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 { LoginController } from './login.controller';
import { LoginService } from '../../business/auth/login.service';

describe('LoginController', () => {
  let controller: LoginController;
  let loginService: jest.Mocked<LoginService>;
  let mockResponse: jest.Mocked<Response>;

  beforeEach(async () => {
    const mockLoginService = {
      login: jest.fn(),
      githubOAuth: jest.fn(),
      sendPasswordResetCode: jest.fn(),
      resetPassword: jest.fn(),
      changePassword: jest.fn(),
      verificationCodeLogin: jest.fn(),
      sendLoginVerificationCode: jest.fn(),
      refreshAccessToken: jest.fn(),
      debugVerificationCode: jest.fn(),
    };

    const module: TestingModule = await Test.createTestingModule({
      controllers: [LoginController],
      providers: [
        {
          provide: LoginService,
          useValue: mockLoginService,
        },
      ],
    }).compile();

    controller = module.get<LoginController>(LoginController);
    loginService = module.get(LoginService);

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

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

  describe('login', () => {
    it('should handle successful login', async () => {
      const loginDto = {
        identifier: 'testuser',
        password: 'password123'
      };

      const mockResult = {
        success: true,
        data: {
          user: { 
            id: '1', 
            username: 'testuser',
            nickname: '测试用户',
            role: 1,
            created_at: new Date()
          },
          access_token: 'token',
          refresh_token: 'refresh_token',
          expires_in: 3600,
          token_type: 'Bearer',
          message: '登录成功'
        },
        message: '登录成功'
      };

      loginService.login.mockResolvedValue(mockResult);

      await controller.login(loginDto, mockResponse);

      expect(loginService.login).toHaveBeenCalledWith({
        identifier: 'testuser',
        password: 'password123'
      });
      expect(mockResponse.status).toHaveBeenCalledWith(HttpStatus.OK);
      expect(mockResponse.json).toHaveBeenCalledWith(mockResult);
    });

    it('should handle login failure', async () => {
      const loginDto = {
        identifier: 'testuser',
        password: 'wrongpassword'
      };

      const mockResult = {
        success: false,
        message: '用户名或密码错误',
        error_code: 'LOGIN_FAILED'
      };

      loginService.login.mockResolvedValue(mockResult);

      await controller.login(loginDto, mockResponse);

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

  describe('githubOAuth', () => {
    it('should handle GitHub OAuth successfully', async () => {
      const githubDto = {
        github_id: '12345',
        username: 'githubuser',
        nickname: 'GitHub User',
        email: 'github@example.com'
      };

      const mockResult = {
        success: true,
        data: {
          user: { 
            id: '1', 
            username: 'githubuser',
            nickname: 'GitHub User',
            role: 1,
            created_at: new Date()
          },
          access_token: 'token',
          refresh_token: 'refresh_token',
          expires_in: 3600,
          token_type: 'Bearer',
          message: 'GitHub登录成功'
        },
        message: 'GitHub登录成功'
      };

      loginService.githubOAuth.mockResolvedValue(mockResult);

      await controller.githubOAuth(githubDto, mockResponse);

      expect(loginService.githubOAuth).toHaveBeenCalledWith(githubDto);
      expect(mockResponse.status).toHaveBeenCalledWith(HttpStatus.OK);
      expect(mockResponse.json).toHaveBeenCalledWith(mockResult);
    });
  });

  describe('refreshToken', () => {
    it('should handle token refresh successfully', async () => {
      const refreshTokenDto = {
        refresh_token: 'valid_refresh_token'
      };

      const mockResult = {
        success: true,
        data: {
          access_token: 'new_access_token',
          refresh_token: 'new_refresh_token',
          expires_in: 3600,
          token_type: 'Bearer'
        },
        message: '令牌刷新成功'
      };

      loginService.refreshAccessToken.mockResolvedValue(mockResult);

      await controller.refreshToken(refreshTokenDto, mockResponse);

      expect(loginService.refreshAccessToken).toHaveBeenCalledWith('valid_refresh_token');
      expect(mockResponse.status).toHaveBeenCalledWith(HttpStatus.OK);
      expect(mockResponse.json).toHaveBeenCalledWith(mockResult);
    });

    it('should handle token refresh failure', async () => {
      const refreshTokenDto = {
        refresh_token: 'invalid_refresh_token'
      };

      const mockResult = {
        success: false,
        message: '刷新令牌无效或已过期',
        error_code: 'TOKEN_REFRESH_FAILED'
      };

      loginService.refreshAccessToken.mockResolvedValue(mockResult);

      await controller.refreshToken(refreshTokenDto, mockResponse);

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