import { Inject, InternalServerErrorException } from '@nestjs/common';
import { CommandHandler, EventBus, type ICommandHandler } from '@nestjs/cqrs';
import { USER_REPOSITORY, type IUserRepository } from '@modules/auth';
import { DomainException, NotFoundException, ValidationException, LoggerService } from '@modules/shared';
import { KycRejectedEvent } from '../../../domain/events/kyc-rejected.event';
import { RejectKycCommand } from './reject-kyc.command';

export interface RejectKycResult {
  userId: string;
  kycStatus: string;
  message: string;
}

@CommandHandler(RejectKycCommand)
export class RejectKycHandler implements ICommandHandler<RejectKycCommand> {
  constructor(
    @Inject(USER_REPOSITORY) private readonly userRepo: IUserRepository,
    private readonly eventBus: EventBus,
    private readonly logger: LoggerService,
  ) {}

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

      if (user.kycStatus !== 'PENDING') {
        throw new ValidationException(
          `KYC đang ở trạng thái ${user.kycStatus}, chỉ có thể từ chối KYC đang chờ`,
          { currentStatus: user.kycStatus },
        );
      }

      user.updateKycStatus('REJECTED');
      await this.userRepo.update(user);

      this.eventBus.publish(new KycRejectedEvent(user.id, command.adminId, command.reason));

      return {
        userId: user.id,
        kycStatus: 'REJECTED',
        message: 'KYC đã bị từ chối',
      };
    } catch (error) {
      if (error instanceof DomainException) throw error;
      this.logger.error(
        `Failed to reject KYC for user ${command.userId}: ${error instanceof Error ? error.message : String(error)}`,
        error instanceof Error ? error.stack : undefined,
        'RejectKycHandler',
      );
      throw new InternalServerErrorException('Lỗi khi từ chối KYC');
    }
  }
}
