import { Module } from '@nestjs/common';
import { CqrsModule } from '@nestjs/cqrs';
import { AuthModule } from '@modules/auth';
import { MetricsModule } from '@modules/metrics';
import { SendNotificationHandler } from './application/commands/send-notification/send-notification.handler';
import { AgentVerifiedListener } from './application/listeners/agent-verified.listener';
import { EmailChangeRequestedListener } from './application/listeners/email-change-requested.listener';
import { InquiryReceivedListener } from './application/listeners/inquiry-received.listener';
import { ListingApprovedListener } from './application/listeners/listing-approved.listener';
import { ListingExpiringListener } from './application/listeners/listing-expiring.listener';
import { ListingRejectedListener } from './application/listeners/listing-rejected.listener';
import { ListingSoldListener } from './application/listeners/listing-sold.listener';
import { PasswordResetRequestedListener } from './application/listeners/password-reset-requested.listener';
import { PaymentCompletedListener } from './application/listeners/payment-completed.listener';
import { PaymentFailedListener } from './application/listeners/payment-failed.listener';
import { PaymentRefundedListener } from './application/listeners/payment-refunded.listener';
import { PhoneChangeRequestedListener } from './application/listeners/phone-change-requested.listener';
import { PhoneLoginOtpRequestedListener } from './application/listeners/phone-login-otp-requested.listener';
import { QuotaExceededListener } from './application/listeners/quota-exceeded.listener';
import {
  ResidentialInquiryReplyListener,
  ResidentialNewListingInProjectListener,
  ResidentialPriceDropListener,
} from './application/listeners/residential-events.listener';
import { SubscriptionExpiredListener } from './application/listeners/subscription-expired.listener';
import { SubscriptionExpiringListener } from './application/listeners/subscription-expiring.listener';
import { SubscriptionRenewedListener } from './application/listeners/subscription-renewed.listener';
import { UserKycUpdatedListener } from './application/listeners/user-kyc-updated.listener';
import { UserRegisteredListener } from './application/listeners/user-registered.listener';
import { SMS_NOTIFICATION_CHANNEL } from './domain/ports/notification-channel.port';
import { NOTIFICATION_PREFERENCE_REPOSITORY } from './domain/repositories/notification-preference.repository';
import { NOTIFICATION_REPOSITORY } from './domain/repositories/notification.repository';
import { PrismaNotificationPreferenceRepository } from './infrastructure/repositories/prisma-notification-preference.repository';
import { PrismaNotificationRepository } from './infrastructure/repositories/prisma-notification.repository';
import { EmailService } from './infrastructure/services/email.service';
import { FcmService } from './infrastructure/services/fcm.service';
import { SmsRateLimiterService } from './infrastructure/services/sms-rate-limiter.service';
import { StringeeSmsService } from './infrastructure/services/stringee-sms.service';
import { TemplateService } from './infrastructure/services/template.service';
import { ZaloOaService } from './infrastructure/services/zalo-oa.service';
import { NotificationsController } from './presentation/controllers/notifications.controller';
import { ZaloOaLinkController } from './presentation/controllers/zalo-oa-link.controller';
import { ZaloOaWebhookController } from './presentation/controllers/zalo-oa-webhook.controller';
import { NotificationsGateway } from './presentation/gateways/notifications.gateway';

const CommandHandlers = [SendNotificationHandler];

const EventListeners = [
  UserRegisteredListener,
  AgentVerifiedListener,
  QuotaExceededListener,
  ListingApprovedListener,
  ListingExpiringListener,
  ListingRejectedListener,
  PaymentCompletedListener,
  PaymentFailedListener,
  PaymentRefundedListener,
  SubscriptionExpiringListener,
  SubscriptionExpiredListener,
  SubscriptionRenewedListener,
  InquiryReceivedListener,
  ListingSoldListener,
  UserKycUpdatedListener,
  EmailChangeRequestedListener,
  PhoneChangeRequestedListener,
  PhoneLoginOtpRequestedListener,
  PasswordResetRequestedListener,
  ResidentialPriceDropListener,
  ResidentialNewListingInProjectListener,
  ResidentialInquiryReplyListener,
];

@Module({
  imports: [CqrsModule, AuthModule, MetricsModule],
  controllers: [NotificationsController, ZaloOaWebhookController, ZaloOaLinkController],
  providers: [
    // Repositories
    { provide: NOTIFICATION_REPOSITORY, useClass: PrismaNotificationRepository },
    { provide: NOTIFICATION_PREFERENCE_REPOSITORY, useClass: PrismaNotificationPreferenceRepository },

    // Services
    EmailService,
    FcmService,
    SmsRateLimiterService,
    StringeeSmsService,
    { provide: SMS_NOTIFICATION_CHANNEL, useExisting: StringeeSmsService },
    ZaloOaService,
    TemplateService,

    // WebSocket Gateway
    NotificationsGateway,

    // CQRS
    ...CommandHandlers,

    // Event Listeners
    ...EventListeners,
  ],
  exports: [
    EmailService,
    FcmService,
    SmsRateLimiterService,
    StringeeSmsService,
    SMS_NOTIFICATION_CHANNEL,
    ZaloOaService,
    TemplateService,
    NotificationsGateway,
  ],
})
export class NotificationsModule {}
