import { Module } from '@nestjs/common';
import { CqrsModule } from '@nestjs/cqrs';
import { PAYMENT_INITIATOR } from '@modules/shared';
import { CancelOrderHandler } from './application/commands/cancel-order/cancel-order.handler';
import { ConfirmBankTransferHandler } from './application/commands/confirm-bank-transfer/confirm-bank-transfer.handler';
import { CreateOrderHandler } from './application/commands/create-order/create-order.handler';
import { CreatePaymentHandler } from './application/commands/create-payment/create-payment.handler';
import { HandleCallbackHandler } from './application/commands/handle-callback/handle-callback.handler';
import { HoldEscrowHandler } from './application/commands/hold-escrow/hold-escrow.handler';
import { RefundPaymentHandler } from './application/commands/refund-payment/refund-payment.handler';
import { ReleaseEscrowHandler } from './application/commands/release-escrow/release-escrow.handler';
import { GetOrderStatusHandler } from './application/queries/get-order-status/get-order-status.handler';
import { GetPaymentStatusHandler } from './application/queries/get-payment-status/get-payment-status.handler';
import { ListTransactionsHandler } from './application/queries/list-transactions/list-transactions.handler';
import { ESCROW_REPOSITORY } from './domain/repositories/escrow.repository';
import { ORDER_REPOSITORY } from './domain/repositories/order.repository';
import { PAYMENT_REPOSITORY } from './domain/repositories/payment.repository';
import { PrismaEscrowRepository } from './infrastructure/repositories/prisma-escrow.repository';
import { PrismaOrderRepository } from './infrastructure/repositories/prisma-order.repository';
import { PrismaPaymentRepository } from './infrastructure/repositories/prisma-payment.repository';
import { CommandBusPaymentInitiator } from './infrastructure/adapters/command-bus-payment-initiator.adapter';
import { BankTransferService } from './infrastructure/services/bank-transfer.service';
import { MomoService } from './infrastructure/services/momo.service';
import { PaymentGatewayFactory } from './infrastructure/services/payment-gateway.factory';
import { PAYMENT_GATEWAY_FACTORY } from './infrastructure/services/payment-gateway.interface';
import { VnpayService } from './infrastructure/services/vnpay.service';
import { ZalopayService } from './infrastructure/services/zalopay.service';
import { OrdersController } from './presentation/controllers/orders.controller';
import { PaymentsController } from './presentation/controllers/payments.controller';

const CommandHandlers = [
  CancelOrderHandler,
  ConfirmBankTransferHandler,
  CreateOrderHandler,
  CreatePaymentHandler,
  HandleCallbackHandler,
  HoldEscrowHandler,
  RefundPaymentHandler,
  ReleaseEscrowHandler,
];

const QueryHandlers = [
  GetOrderStatusHandler,
  GetPaymentStatusHandler,
  ListTransactionsHandler,
];

@Module({
  imports: [CqrsModule],
  controllers: [OrdersController, PaymentsController],
  providers: [
    // Repositories
    { provide: ESCROW_REPOSITORY, useClass: PrismaEscrowRepository },
    { provide: ORDER_REPOSITORY, useClass: PrismaOrderRepository },
    { provide: PAYMENT_REPOSITORY, useClass: PrismaPaymentRepository },

    // Gateway Services
    VnpayService,
    MomoService,
    ZalopayService,
    BankTransferService,
    { provide: PAYMENT_GATEWAY_FACTORY, useClass: PaymentGatewayFactory },

    // CQRS
    ...CommandHandlers,
    ...QueryHandlers,

    // Cross-module port adapter
    { provide: PAYMENT_INITIATOR, useClass: CommandBusPaymentInitiator },
  ],
  exports: [ESCROW_REPOSITORY, ORDER_REPOSITORY, PAYMENT_REPOSITORY, PAYMENT_GATEWAY_FACTORY, PAYMENT_INITIATOR],
})
export class PaymentsModule {}
