import { Module, forwardRef } from "@nestjs/common";
import { TypeOrmModule } from "@nestjs/typeorm";
import { HttpModule } from "@nestjs/axios";
import { ConfigModule, ConfigService } from "@nestjs/config";
import { RabbitMQModule } from "@golevelup/nestjs-rabbitmq";
import {
    PAYMENT_EVENTS_DLX,
    PAYMENT_EVENTS_EXCHANGE,
    PAYMENT_QUEUES,
    PaymentService as PaymentServiceEnum,
    paymentServiceBindingPattern,
} from "@edr/types";
import { PaymentService } from "./payment.service";
import { PaymentClientService } from "./payment-client.service";
import { PaymentController } from "./payment.controller";
import { PaymentRepository } from "./payment.repository";
import { PaymentEventsConsumer } from "./payment-events.consumer";
import { InternalPaymentController } from "./internal-payment.controller";
import { ServiceAuthGuard } from "../../common/guards/service-auth.guard";
import { TrainSchedulingModule } from "../train-scheduling/train-scheduling.module";
import { DropdownSettingsModule } from "../dropdown-settings/dropdown-settings.module";
import { PaymentWebhookEventEntity } from "./entities/payment-webhook-event.entity";
import { PaymentRefundEntity } from "./entities/payment-refund.entity";

const FREIGHT_QUEUE = PAYMENT_QUEUES[PaymentServiceEnum.FREIGHT];

@Module({
    imports: [
        HttpModule.register({ timeout: 10_000 }),
        ConfigModule,
        DropdownSettingsModule,
        forwardRef(() => TrainSchedulingModule),
        TypeOrmModule.forFeature([PaymentWebhookEventEntity, PaymentRefundEntity]),
        RabbitMQModule.forRootAsync({
            inject: [ConfigService],
            useFactory: (config: ConfigService) => ({
                uri: config.get<string>("rabbitmq.url") as string,
                exchanges: [
                    { name: PAYMENT_EVENTS_EXCHANGE, type: "topic", options: { durable: true } },
                    { name: PAYMENT_EVENTS_DLX, type: "topic", options: { durable: true } },
                ],
                queues: [
                    {
                        name: FREIGHT_QUEUE.dlq,
                        exchange: PAYMENT_EVENTS_DLX,
                        routingKey: paymentServiceBindingPattern(PaymentServiceEnum.FREIGHT),
                        options: { durable: true },
                    },
                ],
                prefetchCount: config.get<number>("rabbitmq.prefetch") ?? 10,
                connectionInitOptions: { wait: false },
            }),
        }),
    ],
    providers: [
        PaymentRepository,
        PaymentService,
        PaymentClientService,
        PaymentEventsConsumer,
        ServiceAuthGuard,
    ],
    controllers: [PaymentController, InternalPaymentController],
    exports: [PaymentService],
})
export class PaymentModule { }
