import { Processor, WorkerHost } from '@nestjs/bullmq';
import { Logger } from '@nestjs/common';
import { Job } from 'bullmq';
import { PrismaService } from '../../prisma/prisma.service';
import { TwilioService } from '../../twilio/twilio.service';
import { CAMPANAS_QUEUE, CampanaJob, CampanasService } from './campanas.service';

@Processor(CAMPANAS_QUEUE)
export class CampanasProcessor extends WorkerHost {
  private readonly logger = new Logger(CampanasProcessor.name);

  constructor(
    private readonly prisma: PrismaService,
    private readonly twilio: TwilioService,
    private readonly campanas: CampanasService,
  ) {
    super();
  }

  async process(job: Job<CampanaJob>): Promise<void> {
    const envio = await this.prisma.cartera_campana_envios.findUnique({
      where: { id: job.data.envio_id },
    });
    if (!envio) {
      this.logger.warn(`Envío ${job.data.envio_id} no existe, descarto`);
      return;
    }
    if (envio.estado === 'enviado' || envio.estado === 'cancelado') {
      return;
    }

    try {
      const resp = await this.twilio.sendSMS(envio.telefono, envio.mensaje_renderizado);
      await this.prisma.cartera_campana_envios.update({
        where: { id: envio.id },
        data: {
          estado: 'enviado',
          provider_id: resp?.sid ?? null,
          sent_at: new Date(),
          error: null,
        },
      });
      await this.campanas.tickAvance(envio.id, true);
    } catch (err: any) {
      const esUltimoIntento = job.attemptsMade + 1 >= (job.opts?.attempts ?? 3);
      if (esUltimoIntento) {
        await this.prisma.cartera_campana_envios.update({
          where: { id: envio.id },
          data: {
            estado: 'fallido',
            error: String(err?.message ?? err).slice(0, 500),
          },
        });
        await this.campanas.tickAvance(envio.id, false);
      }
      this.logger.warn(
        `Envío ${envio.id} fallo (intento ${job.attemptsMade + 1}): ${err?.message ?? err}`,
      );
      throw err;
    }
  }
}
