import { Controller, Get, Post, Body, UseGuards } from '@nestjs/common';
import {
  ApiTags,
  ApiOperation,
  ApiBearerAuth,
  ApiResponse,
} from '@nestjs/swagger';
import { TotpService } from '@/application/services/totp.service';
import { CurrentUser, CurrentUserPayload } from '@/shared/decorators';
import { JwtAuthGuard } from '@/shared/guards/jwt-auth.guard';

class SetupTotpResponseDto {
  secret: string;
  qrCodeUrl: string;
  manualEntryKey: string;
}

class TotpStatusResponseDto {
  isEnabled: boolean;
  isSetup: boolean;
  enabledAt: Date | null;
}

class EnableTotpDto {
  code: string;
}

class DisableTotpDto {
  code: string;
}

class VerifyTotpDto {
  code: string;
}

@ApiTags('TOTP')
@Controller('totp')
@UseGuards(JwtAuthGuard)
@ApiBearerAuth()
export class TotpController {
  constructor(private readonly totpService: TotpService) {}

  @Get('status')
  @ApiOperation({
    summary: '获取 TOTP 状态',
    description: '查询当前用户的 TOTP 启用状态',
  })
  @ApiResponse({ status: 200, type: TotpStatusResponseDto })
  async getStatus(
    @CurrentUser() user: CurrentUserPayload,
  ): Promise<TotpStatusResponseDto> {
    return this.totpService.getTotpStatus(BigInt(user.userId));
  }

  @Post('setup')
  @ApiOperation({
    summary: '设置 TOTP',
    description: '生成 TOTP 密钥，返回二维码和手动输入密钥',
  })
  @ApiResponse({ status: 201, type: SetupTotpResponseDto })
  async setup(
    @CurrentUser() user: CurrentUserPayload,
  ): Promise<SetupTotpResponseDto> {
    return this.totpService.setupTotp(BigInt(user.userId));
  }

  @Post('enable')
  @ApiOperation({
    summary: '启用 TOTP',
    description: '验证码正确后启用 TOTP 二次验证',
  })
  @ApiResponse({ status: 200, description: 'TOTP 已启用' })
  async enable(
    @CurrentUser() user: CurrentUserPayload,
    @Body() dto: EnableTotpDto,
  ): Promise<{ success: boolean; message: string }> {
    await this.totpService.enableTotp(BigInt(user.userId), dto.code);
    return { success: true, message: 'TOTP 已启用' };
  }

  @Post('disable')
  @ApiOperation({
    summary: '禁用 TOTP',
    description: '验证码正确后禁用 TOTP 二次验证',
  })
  @ApiResponse({ status: 200, description: 'TOTP 已禁用' })
  async disable(
    @CurrentUser() user: CurrentUserPayload,
    @Body() dto: DisableTotpDto,
  ): Promise<{ success: boolean; message: string }> {
    await this.totpService.disableTotp(BigInt(user.userId), dto.code);
    return { success: true, message: 'TOTP 已禁用' };
  }

  @Post('verify')
  @ApiOperation({
    summary: '验证 TOTP',
    description: '验证 TOTP 验证码是否正确',
  })
  @ApiResponse({ status: 200, description: '验证结果' })
  async verify(
    @CurrentUser() user: CurrentUserPayload,
    @Body() dto: VerifyTotpDto,
  ): Promise<{ valid: boolean }> {
    const valid = await this.totpService.verifyTotp(
      BigInt(user.userId),
      dto.code,
    );
    return { valid };
  }
}
