import { InternalServerErrorException } from '@nestjs/common';
import { CommandHandler, CommandBus, type ICommandHandler } from '@nestjs/cqrs';
import { LoggerService, PrismaService, DomainException } from '@modules/shared';
import { ForceDeleteUserCommand } from '../force-delete-user/force-delete-user.command';
import { ProcessScheduledDeletionsCommand } from './process-scheduled-deletions.command';

@CommandHandler(ProcessScheduledDeletionsCommand)
export class ProcessScheduledDeletionsHandler implements ICommandHandler<ProcessScheduledDeletionsCommand> {
  constructor(
    private readonly prisma: PrismaService,
    private readonly commandBus: CommandBus,
    private readonly logger: LoggerService,
  ) {}

  async execute(): Promise<{ processedCount: number }> {
    try {
      const now = new Date();

      const usersToDelete = await this.prisma.user.findMany({
        where: {
          deletionScheduledAt: { lte: now },
          deletedAt: null,
        },
        select: { id: true },
      });

      this.logger.log(
        `Processing ${usersToDelete.length} scheduled deletions`,
        'ProcessScheduledDeletionsHandler',
      );

      let processedCount = 0;
      for (const user of usersToDelete) {
        try {
          await this.commandBus.execute(
            new ForceDeleteUserCommand(user.id, 'SYSTEM', 'Scheduled GDPR deletion after 30-day grace period'),
          );
          processedCount++;
        } catch (error) {
          this.logger.error(
            `Failed to process deletion for user ${user.id}: ${error}`,
            undefined,
            'ProcessScheduledDeletionsHandler',
          );
        }
      }

      return { processedCount };
    } catch (error) {
      if (error instanceof DomainException) throw error;
      this.logger.error(
        `Failed to process scheduled deletions: ${error instanceof Error ? error.message : error}`,
        error instanceof Error ? error.stack : undefined,
        this.constructor.name,
      );
      throw new InternalServerErrorException('Không thể xử lý các yêu cầu xóa tài khoản theo lịch');
    }
  }
}
