/**
 * 注册网关控制器
 * 
 * 架构层级：Gateway Layer（网关层）
 * 
 * 功能描述：
 * - 处理用户注册相关的HTTP请求和响应
 * - 提供RESTful API接口
 * - 数据验证和格式化
 * - 邮箱验证功能
 * 
 * 职责分离：
 * - 专注于HTTP协议处理和请求响应
 * - 调用业务层服务完成具体功能
 * - 处理API文档和参数验证
 * - 不包含业务逻辑，只做数据转换和路由
 * 
 * 依赖关系：
 * - 依赖 Business Layer 的 RegisterService
 * - 使用 DTO 进行数据验证
 * 
 * API端点：
 * - POST /auth/register - 用户注册
 * - POST /auth/send-email-verification - 发送邮箱验证码
 * - POST /auth/verify-email - 验证邮箱验证码
 * - POST /auth/resend-email-verification - 重新发送邮箱验证码
 * 
 * @author moyin
 * @version 2.0.0
 * @since 2026-01-14
 * @lastModified 2026-01-14
 */

import { 
  Controller, 
  Post, 
  Body, 
  HttpStatus, 
  ValidationPipe, 
  UsePipes, 
  Logger, 
  Res 
} from '@nestjs/common';
import { 
  ApiTags, 
  ApiOperation, 
  ApiResponse as SwaggerApiResponse, 
  ApiBody 
} from '@nestjs/swagger';
import { Response } from 'express';
import { RegisterService } from '../../business/auth/register.service';
import { 
  RegisterDto, 
  EmailVerificationDto, 
  SendEmailVerificationDto 
} from './dto/login.dto';
import { 
  RegisterResponseDto, 
  CommonResponseDto,
  TestModeEmailVerificationResponseDto,
  SuccessEmailVerificationResponseDto
} from './dto/login_response.dto';
import { Throttle, ThrottlePresets } from '../../core/security_core/throttle.decorator';
import { Timeout, TimeoutPresets } from '../../core/security_core/timeout.decorator';

// 错误代码到HTTP状态码的映射
const ERROR_STATUS_MAP = {
  REGISTER_FAILED: HttpStatus.BAD_REQUEST,
  TEST_MODE_ONLY: HttpStatus.PARTIAL_CONTENT,
  SEND_EMAIL_VERIFICATION_FAILED: HttpStatus.BAD_REQUEST,
  EMAIL_VERIFICATION_FAILED: HttpStatus.BAD_REQUEST,
  RESEND_EMAIL_VERIFICATION_FAILED: HttpStatus.BAD_REQUEST,
  INVALID_VERIFICATION_CODE: HttpStatus.BAD_REQUEST,
} as const;

@ApiTags('auth')
@Controller('auth')
export class RegisterController {
  private readonly logger = new Logger(RegisterController.name);

  constructor(private readonly registerService: RegisterService) {}

  /**
   * 通用响应处理方法
   * 
   * 职责：
   * - 根据业务结果设置HTTP状态码
   * - 处理不同类型的错误响应
   * - 统一响应格式和错误处理
   * 
   * @param result 业务服务返回的结果
   * @param res Express响应对象
   * @param successStatus 成功时的HTTP状态码，默认为200
   * @private
   */
  private handleResponse(result: any, res: Response, successStatus: HttpStatus = HttpStatus.OK): void {
    if (result.success) {
      res.status(successStatus).json(result);
      return;
    }

    const statusCode = this.getErrorStatusCode(result);
    res.status(statusCode).json(result);
  }

  /**
   * 根据错误代码和消息获取HTTP状态码
   * 
   * @param result 业务服务返回的结果
   * @returns HTTP状态码
   * @private
   */
  private getErrorStatusCode(result: any): HttpStatus {
    if (result.error_code && ERROR_STATUS_MAP[result.error_code as keyof typeof ERROR_STATUS_MAP]) {
      return ERROR_STATUS_MAP[result.error_code as keyof typeof ERROR_STATUS_MAP];
    }

    if (result.message?.includes('已存在') || result.message?.includes('已被注册')) {
      return HttpStatus.CONFLICT;
    }
    
    if (result.message?.includes('用户不存在')) {
      return HttpStatus.NOT_FOUND;
    }

    return HttpStatus.BAD_REQUEST;
  }

  /**
   * 用户注册
   * 
   * @param registerDto 注册数据
   * @param res Express响应对象
   */
  @ApiOperation({ 
    summary: '用户注册', 
    description: '创建新用户账户' 
  })
  @ApiBody({ type: RegisterDto })
  @SwaggerApiResponse({ 
    status: 201, 
    description: '注册成功', 
    type: RegisterResponseDto 
  })
  @SwaggerApiResponse({ 
    status: 400, 
    description: '请求参数错误' 
  })
  @SwaggerApiResponse({ 
    status: 409, 
    description: '用户名或邮箱已存在' 
  })
  @SwaggerApiResponse({ 
    status: 429, 
    description: '注册请求过于频繁' 
  })
  @Throttle(ThrottlePresets.REGISTER)
  @Timeout(TimeoutPresets.NORMAL)
  @Post('register')
  @UsePipes(new ValidationPipe({ transform: true }))
  async register(@Body() registerDto: RegisterDto, @Res() res: Response): Promise<void> {
    const result = await this.registerService.register({
      username: registerDto.username,
      password: registerDto.password,
      nickname: registerDto.nickname,
      email: registerDto.email,
      phone: registerDto.phone,
      email_verification_code: registerDto.email_verification_code
    });

    this.handleResponse(result, res, HttpStatus.CREATED);
  }

  /**
   * 发送邮箱验证码
   * 
   * @param sendEmailVerificationDto 发送验证码数据
   * @param res Express响应对象
   */
  @ApiOperation({ 
    summary: '发送邮箱验证码', 
    description: '向指定邮箱发送验证码' 
  })
  @ApiBody({ type: SendEmailVerificationDto })
  @SwaggerApiResponse({ 
    status: 200, 
    description: '验证码发送成功（真实发送模式）', 
    type: SuccessEmailVerificationResponseDto 
  })
  @SwaggerApiResponse({ 
    status: 206, 
    description: '测试模式：验证码已生成但未真实发送', 
    type: TestModeEmailVerificationResponseDto 
  })
  @SwaggerApiResponse({ 
    status: 400, 
    description: '请求参数错误' 
  })
  @SwaggerApiResponse({ 
    status: 429, 
    description: '发送频率过高' 
  })
  @Throttle(ThrottlePresets.SEND_CODE_PER_EMAIL)
  @Timeout(TimeoutPresets.EMAIL_SEND)
  @Post('send-email-verification')
  @UsePipes(new ValidationPipe({ transform: true }))
  async sendEmailVerification(
    @Body() sendEmailVerificationDto: SendEmailVerificationDto,
    @Res() res: Response
  ): Promise<void> {
    const result = await this.registerService.sendEmailVerification(sendEmailVerificationDto.email);
    this.handleResponse(result, res);
  }

  /**
   * 验证邮箱验证码
   * 
   * @param emailVerificationDto 邮箱验证数据
   * @param res Express响应对象
   */
  @ApiOperation({ 
    summary: '验证邮箱验证码', 
    description: '使用验证码验证邮箱' 
  })
  @ApiBody({ type: EmailVerificationDto })
  @SwaggerApiResponse({ 
    status: 200, 
    description: '邮箱验证成功', 
    type: CommonResponseDto 
  })
  @SwaggerApiResponse({ 
    status: 400, 
    description: '验证码错误或已过期' 
  })
  @Post('verify-email')
  @UsePipes(new ValidationPipe({ transform: true }))
  async verifyEmail(@Body() emailVerificationDto: EmailVerificationDto, @Res() res: Response): Promise<void> {
    const result = await this.registerService.verifyEmailCode(
      emailVerificationDto.email,
      emailVerificationDto.verification_code
    );

    this.handleResponse(result, res);
  }

  /**
   * 重新发送邮箱验证码
   * 
   * @param sendEmailVerificationDto 发送验证码数据
   * @param res Express响应对象
   */
  @ApiOperation({ 
    summary: '重新发送邮箱验证码', 
    description: '重新向指定邮箱发送验证码' 
  })
  @ApiBody({ type: SendEmailVerificationDto })
  @SwaggerApiResponse({ 
    status: 200, 
    description: '验证码重新发送成功', 
    type: SuccessEmailVerificationResponseDto 
  })
  @SwaggerApiResponse({ 
    status: 206, 
    description: '测试模式：验证码已生成但未真实发送', 
    type: TestModeEmailVerificationResponseDto 
  })
  @SwaggerApiResponse({ 
    status: 400, 
    description: '邮箱已验证或用户不存在' 
  })
  @SwaggerApiResponse({ 
    status: 429, 
    description: '发送频率过高' 
  })
  @Throttle(ThrottlePresets.SEND_CODE)
  @Post('resend-email-verification')
  @UsePipes(new ValidationPipe({ transform: true }))
  async resendEmailVerification(
    @Body() sendEmailVerificationDto: SendEmailVerificationDto,
    @Res() res: Response
  ): Promise<void> {
    const result = await this.registerService.resendEmailVerification(sendEmailVerificationDto.email);
    this.handleResponse(result, res);
  }
}
