import { InjectQueue } from '@nestjs/bullmq';
import { Injectable, Logger } from '@nestjs/common';
import { Queue } from 'bullmq';
import { PrismaService } from '../../prisma/prisma.service';
import type { EventoCarteraValor } from './webhook-events';

export interface WebhookDeliveryJob {
  delivery_id: string;
}

export const WEBHOOK_QUEUE = 'cartera-webhooks';

@Injectable()
export class WebhookService {
  private readonly logger = new Logger(WebhookService.name);

  constructor(
    private readonly prisma: PrismaService,
    @InjectQueue(WEBHOOK_QUEUE) private readonly queue: Queue<WebhookDeliveryJob>,
  ) {}

  /**
   * Publica un evento: encuentra todos los endpoints suscritos para esta
   * empresa+evento, crea una `webhook_deliveries` por cada uno y encola
   * un job de delivery en BullMQ. No bloquea al caller.
   *
   * Si no hay endpoints suscritos, no hace nada (silent no-op).
   */
  async publicar(empresa_id: string, evento: EventoCarteraValor, payload: unknown): Promise<void> {
    const endpoints = await this.prisma.tenant_webhook_endpoints.findMany({
      where: { empresa_id, evento, activo: true },
      select: { id: true },
    });
    if (endpoints.length === 0) return;

    const deliveries = await this.prisma.$transaction(
      endpoints.map((ep) =>
        this.prisma.webhook_deliveries.create({
          data: {
            empresa_id,
            endpoint_id: ep.id,
            evento,
            payload: payload as object,
          },
          select: { id: true },
        }),
      ),
    );

    for (const d of deliveries) {
      try {
        await this.queue.add(
          'deliver',
          { delivery_id: d.id },
          {
            attempts: 3,
            backoff: { type: 'exponential', delay: 30_000 }, // 30s, 60s, 120s
            removeOnComplete: 100,
            removeOnFail: 500,
          },
        );
      } catch (err: any) {
        this.logger.error(
          `No se pudo encolar webhook delivery ${d.id}: ${err?.message ?? err}`,
        );
      }
    }
  }
}
