import { InjectQueue } from '@nestjs/bullmq';
import { Inject } from '@nestjs/common';
import { CommandHandler, type ICommandHandler } from '@nestjs/cqrs';
import { createId } from '@paralleldrive/cuid2';
import { Queue } from 'bullmq';
import { ReportEntity } from '../../../domain/entities/report.entity';
import { REPORT_REPOSITORY, type IReportRepository } from '../../../domain/repositories/report.repository';
import { GenerateReportCommand } from './generate-report.command';

export const REPORT_GENERATION_QUEUE = 'report-generation';

export interface GenerateReportResult {
  reportId: string;
}

@CommandHandler(GenerateReportCommand)
export class GenerateReportHandler implements ICommandHandler<GenerateReportCommand, GenerateReportResult> {
  constructor(
    @Inject(REPORT_REPOSITORY) private readonly reportRepo: IReportRepository,
    @InjectQueue(REPORT_GENERATION_QUEUE) private readonly reportQueue: Queue,
  ) {}

  async execute(command: GenerateReportCommand): Promise<GenerateReportResult> {
    const report = ReportEntity.createNew(
      createId(),
      command.userId,
      command.type,
      command.title,
      command.params,
    );

    await this.reportRepo.save(report);

    await this.reportQueue.add('generate', {
      reportId: report.id,
    }, {
      attempts: 2,
      backoff: { type: 'exponential', delay: 5000 },
      removeOnComplete: 100,
      removeOnFail: 50,
    });

    return { reportId: report.id };
  }
}
