import { Injectable, Logger } from "@nestjs/common";
import { Nack, RabbitSubscribe } from "@golevelup/nestjs-rabbitmq";
import { Public } from "@edr/api-common";
import {
    PAYMENT_EVENTS_DLX,
    PAYMENT_EVENTS_EXCHANGE,
    PAYMENT_QUEUES,
    PaymentEvent,
    PaymentService,
    paymentServiceBindingPattern,
} from "@edr/types";
import { PaymentEventDto } from "./internal-payment.dto";
import { PaymentService as PaymentSvc } from "./payment.service";

const FREIGHT_QUEUE = PAYMENT_QUEUES[PaymentService.FREIGHT];

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

    constructor(private readonly paymentService: PaymentSvc) { }

    @Public()
    @RabbitSubscribe({
        exchange: PAYMENT_EVENTS_EXCHANGE,
        routingKey: paymentServiceBindingPattern(PaymentService.FREIGHT),
        queue: FREIGHT_QUEUE.main,
        queueOptions: {
            durable: true,
            deadLetterExchange: PAYMENT_EVENTS_DLX,
        },
    })
    async handle(event: PaymentEvent): Promise<Nack | void> {
        try {
            const result = await this.paymentService.handlePaymentEvent(
                event as unknown as PaymentEventDto,
            );
            this.logger.log(
                `processed ${event.eventType} (${event.eventId}) ref=${event.referenceId}: ${JSON.stringify(result)}`,
            );
        } catch (err) {
            const message = err instanceof Error ? err.message : String(err);
            this.logger.error(
                `DEAD-LETTERING ${event.eventType} (${event.eventId}) ref=${event.referenceId}: ${message}`,
            );
            return new Nack(false);
        }
    }
}
