import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { PassportModule } from '@nestjs/passport';
import { JwtModule } from '@nestjs/jwt';

// Domain entities
import { Notification } from './domain/entities/notification.entity';
import { Announcement } from './domain/entities/announcement.entity';
import { AnnouncementRead } from './domain/entities/announcement-read.entity';
import { AnnouncementTagTarget } from './domain/entities/announcement-tag-target.entity';
import { AnnouncementUserTarget } from './domain/entities/announcement-user-target.entity';
import { UserTag } from './domain/entities/user-tag.entity';
import { DeviceToken } from './domain/entities/device-token.entity';

// Domain repository interfaces
import { NOTIFICATION_REPOSITORY } from './domain/repositories/notification.repository.interface';
import { ANNOUNCEMENT_REPOSITORY } from './domain/repositories/announcement.repository.interface';
import { USER_TAG_REPOSITORY } from './domain/repositories/user-tag.repository.interface';
import { DEVICE_TOKEN_REPOSITORY } from './domain/repositories/device-token.repository.interface';

// Infrastructure implementations
import { NotificationRepository } from './infrastructure/persistence/notification.repository';
import { AnnouncementRepositoryImpl } from './infrastructure/persistence/announcement.repository';
import { UserTagRepositoryImpl } from './infrastructure/persistence/user-tag.repository';
import { DeviceTokenRepositoryImpl } from './infrastructure/persistence/device-token.repository';

// Domain ports — notification channel providers
import {
  PUSH_NOTIFICATION_PROVIDER,
  SMS_NOTIFICATION_PROVIDER,
  EMAIL_NOTIFICATION_PROVIDER,
} from './domain/ports/notification-provider.interface';
import { PushNotificationProvider } from './infrastructure/providers/push-notification.provider';
import { SmsNotificationProvider } from './infrastructure/providers/sms-notification.provider';
import { EmailNotificationProvider } from './infrastructure/providers/email-notification.provider';

// Domain ports — push channel providers (FCM/APNs/HMS/Xiaomi/OPPO/vivo)
import {
  FCM_PUSH_PROVIDER,
  APNS_PUSH_PROVIDER,
  HMS_PUSH_PROVIDER,
  XIAOMI_PUSH_PROVIDER,
  OPPO_PUSH_PROVIDER,
  VIVO_PUSH_PROVIDER,
} from './domain/ports/push-channel-provider.interface';
import {
  FcmPushProvider,
  ApnsPushProvider,
  HmsPushProvider,
  XiaomiPushProvider,
  OppoPushProvider,
  VivoPushProvider,
} from './infrastructure/providers/push-channels';

// Application services
import { NotificationService } from './application/services/notification.service';
import { EventConsumerService } from './application/services/event-consumer.service';
import { AdminNotificationService } from './application/services/admin-notification.service';
import { AnnouncementService } from './application/services/announcement.service';
import { UserTagService } from './application/services/user-tag.service';
import { PushDispatcherService } from './application/services/push-dispatcher.service';
import { DeviceTokenService } from './application/services/device-token.service';

// Interface controllers
import { NotificationController } from './interface/http/controllers/notification.controller';
import { AdminNotificationController } from './interface/http/controllers/admin-notification.controller';
import {
  AdminAnnouncementController,
  AdminUserTagController,
  UserAnnouncementController,
} from './interface/http/controllers/announcement.controller';
import { DeviceTokenController } from './interface/http/controllers/device-token.controller';

@Module({
  imports: [
    TypeOrmModule.forFeature([
      Notification,
      Announcement,
      AnnouncementRead,
      AnnouncementTagTarget,
      AnnouncementUserTarget,
      UserTag,
      DeviceToken,
    ]),
    PassportModule.register({ defaultStrategy: 'jwt' }),
    JwtModule.register({ secret: process.env.JWT_ACCESS_SECRET || 'dev-access-secret' }),
  ],
  controllers: [
    NotificationController,
    AdminNotificationController,
    AdminAnnouncementController,
    AdminUserTagController,
    UserAnnouncementController,
    DeviceTokenController,
  ],
  providers: [
    // Infrastructure -> Domain repository binding
    { provide: NOTIFICATION_REPOSITORY, useClass: NotificationRepository },
    { provide: ANNOUNCEMENT_REPOSITORY, useClass: AnnouncementRepositoryImpl },
    { provide: USER_TAG_REPOSITORY, useClass: UserTagRepositoryImpl },
    { provide: DEVICE_TOKEN_REPOSITORY, useClass: DeviceTokenRepositoryImpl },

    // Infrastructure -> Notification channel providers
    { provide: PUSH_NOTIFICATION_PROVIDER, useClass: PushNotificationProvider },
    { provide: SMS_NOTIFICATION_PROVIDER, useClass: SmsNotificationProvider },
    { provide: EMAIL_NOTIFICATION_PROVIDER, useClass: EmailNotificationProvider },

    // Infrastructure -> Push channel providers (multi-vendor)
    { provide: FCM_PUSH_PROVIDER, useClass: FcmPushProvider },
    { provide: APNS_PUSH_PROVIDER, useClass: ApnsPushProvider },
    { provide: HMS_PUSH_PROVIDER, useClass: HmsPushProvider },
    { provide: XIAOMI_PUSH_PROVIDER, useClass: XiaomiPushProvider },
    { provide: OPPO_PUSH_PROVIDER, useClass: OppoPushProvider },
    { provide: VIVO_PUSH_PROVIDER, useClass: VivoPushProvider },

    // Application services
    NotificationService,
    EventConsumerService,
    AdminNotificationService,
    AnnouncementService,
    UserTagService,
    PushDispatcherService,
    DeviceTokenService,
  ],
  exports: [NotificationService, AnnouncementService, PushDispatcherService],
})
export class NotificationModule {}
