import { Inject, InternalServerErrorException } from '@nestjs/common';
import { CommandHandler, type ICommandHandler } from '@nestjs/cqrs';
import { DomainException, LoggerService, UnauthorizedException, ValidationException } from '@modules/shared';
import { USER_REPOSITORY, type IUserRepository } from '../../../domain/repositories/user.repository';
import { MfaService } from '../../../infrastructure/services/mfa.service';
import { DisableMfaCommand } from './disable-mfa.command';

@CommandHandler(DisableMfaCommand)
export class DisableMfaHandler implements ICommandHandler<DisableMfaCommand> {
  constructor(
    @Inject(USER_REPOSITORY) private readonly userRepo: IUserRepository,
    private readonly mfaService: MfaService,
    private readonly logger: LoggerService,
  ) {}

  async execute(command: DisableMfaCommand): Promise<{ message: string }> {
    try {
      const user = await this.userRepo.findById(command.userId);
      if (!user) {
        throw new ValidationException('Người dùng không tồn tại');
      }

      if (!user.totpEnabled || !user.totpSecret) {
        throw new ValidationException('MFA chưa được bật');
      }

      // Require current TOTP code to disable MFA
      const isValid = await this.mfaService.verifyTotp(command.totpCode, user.totpSecret);
      if (!isValid) {
        throw new UnauthorizedException('Mã TOTP không hợp lệ');
      }

      // Disable MFA
      await this.userRepo.updateMfaDisabled(command.userId);

      return { message: 'MFA đã được tắt thành công' };
    } catch (error) {
      if (error instanceof DomainException) throw error;
      this.logger.error(
        `Failed to disable MFA: ${error instanceof Error ? error.message : error}`,
        error instanceof Error ? error.stack : undefined,
        this.constructor.name,
      );
      throw new InternalServerErrorException('Không thể tắt MFA');
    }
  }
}
