import { CfnModule } from '@lib/cloudfront/cfn.module';
import { CryptoModule } from '@lib/crypto/src';
import { DrizzleModule } from '@lib/drizzle/src';
import { PdfModule } from '@lib/pdf/src';
import { S3Module } from '@lib/s3/src';
import { YoutubeModule } from '@lib/youtube/src/youtube.module';
import { Module, RequestMethod } from '@nestjs/common';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { APP_PIPE } from '@nestjs/core';
import { EventEmitterModule } from '@nestjs/event-emitter';
import { JwtModule } from '@nestjs/jwt';
import { ScheduleModule } from '@nestjs/schedule';
import { LoggerModule } from 'nestjs-pino';
import { join } from 'path';
import { AppController } from './app.controller';
import configuration from './config/configuration';
import { AdminModule } from './modules/admin/admin.module';
import { SuperAdminModule } from './modules/admin/super-admin.module';
import { AdvertisementModule } from './modules/advertisement/advertisement.module';
import { AgencyModule } from './modules/agency/agency/agency.module';
import { AgencyContractModule } from './modules/agency/contract/contract.module';
import { AgencyOrganizationModule } from './modules/agency/organization/organization.module';
import { AgencySettlementModule } from './modules/agency/settlement/settlement.module';
import { AgencyTermsModule } from './modules/agency/terms/terms.module';
import { AgencyPolicyModule } from './modules/agency/policy/policy.module';
import { AlarmModule } from './modules/alarm/alarm.module';
import { AlimtalkModule } from './modules/alimtalk/alimtalk.module';
import { AllowIpModule } from './modules/allow-ip/allow-ip.module';
import { AnalyzeModule } from './modules/analyze/analyze.module';
import { AuthModule } from './modules/auth/auth.module';
import { AuthGuardModule } from './modules/auth/user/auth-guard.module';
import { AuthorityModule } from './modules/authority/authority.module';
import { B2cAnalyzeModule } from './modules/b2c/analyze/b2c-analyze.module';
import { BannerModule } from './modules/banner/banner.module';
import { BoardModule } from './modules/board/board/board.module';
import { BoardCategoryModule } from './modules/board/category/board-category.module';
import { BoardCommentModule } from './modules/board/comment/board-comment.module';
import { CardModule } from './modules/card/card.module';
import { ClientAnalyzeModule } from './modules/client/analyze/client-analyze.module';
import { ClientModule } from './modules/client/client/client.module';
import { ClientContractModule } from './modules/client/contract/client-contract.module';
import { ClientSettlementModule } from './modules/client/settlement/settlement.module';
import { ClinicalResultModule } from './modules/clinical-result/clinical-result.module';
import { CompareBasicModule } from './modules/compare/basic/compare-basic.module';
import { CompareDetailModule } from './modules/compare/detail/compare-detail.module';
import { CoursesBookmarkModule } from './modules/courses/bookmark/courses-bookmark.module';
import { CoursesCategoryModule } from './modules/courses/category/courses-category.module';
import { CoursesModule } from './modules/courses/courses/courses.module';
import { CoursesEnrollmentsModule } from './modules/courses/enrollments/courses-enrollments.module';
import { CoursesProgressModule } from './modules/courses/progress/courses-progress.module';
import { CoursesReviewsModule } from './modules/courses/reviews/courses-reviews.module';
import { DiseaseModule } from './modules/disease/disease.module';
import { FaxModule } from './modules/fax/fax.module';
import { FcModule } from './modules/fc/fc.module';
import { InstitutionBlockModule } from './modules/institution-block/institution-block.module';
import { InvoiceModule } from './modules/invoice/invoice.module';
import { LossAdjustmentCategoryModule } from './modules/loss-adjustment/loss-adjustment-category/loss-adjustment-category.module';
import { LossAdjustmentCommentModule } from './modules/loss-adjustment/loss-adjustment-comment/loss-adjustment-comment.module';
import { LossAdjustmentModule } from './modules/loss-adjustment/loss-adjustment/loss-adjustment.module';
import { MedicalModule } from './modules/medical/medical.module';
import { MedicationStandardModule } from './modules/medication-standard/medication-standard.module';
import { LossAnalysisModule } from './modules/loss-analysis/loss-analysis.module';
import { MenuModule } from './modules/menu/menu.module';
import { MoneyModule } from './modules/money/money.module';
import { OrderDetailModule } from './modules/order/order-detail/order-detail.module';
import { OrderModule } from './modules/order/order/order.module';
import { PaymentModule } from './modules/payment/payment.module';
import { PopupModule } from './modules/popup/popup.module';
import { ProductModule } from './modules/product/product.module';
import { PushModule } from './modules/push/push.module';
import { ReferralModule } from './modules/referral/referral.module';
import { RefundModule } from './modules/refund/refund.module';
import { SalesAgencyChannelModule } from './modules/sales-agency/channel/sales-agency-channel.module';
import { SalesAgencyModule } from './modules/sales-agency/sales-agency.module';
import { SalesCommissionModule } from './modules/sales-commission/sales-commission.module';
import { SearchModule } from './modules/search/search.module';
import { StatisticsModule } from './modules/statistics/statistics.module';
import { SubscribeFailedModule } from './modules/subscribe/subscribe-failed/subscribe-failed.module';
import { SubscribeModule } from './modules/subscribe/subscribe/subscribe.module';
import { LogTreatModule } from './modules/treat/log/log-treat.module';
import { TreatModule } from './modules/treat/treat.module';
import { AlertModule } from './modules/alert/alert.module';
import { AuditModule } from './modules/audit/audit.module';
import { AuditLogModule } from './modules/audit-log/audit-log.module';
import { TreatTestModule } from './modules/treat-test/treat-test.module';
import { UserModule } from './modules/user/user.module';
import { AdminViewTokenModule } from './modules/admin-view-token/admin-view-token.module';
import { pinoHttpOptions } from './pino';
import { ClassValidatorPipe } from './pipes/validation.pipe';

@Module({
  imports: [
    ConfigModule.forRoot({
      isGlobal: true,
      cache: true,
      load: [configuration],
      envFilePath: [join(process.cwd(), `apps/api/.env`)],
    }),
    LoggerModule.forRoot({
      pinoHttp: pinoHttpOptions,
      exclude: [
        { method: RequestMethod.GET, path: 'health' },
        { method: RequestMethod.GET, path: 'favicon.ico' },
      ],
    }),
    EventEmitterModule.forRoot({
      verboseMemoryLeak: true,
      ignoreErrors: false,
    }),
    JwtModule.registerAsync({
      inject: [ConfigService],
      global: true,
      useFactory: (configService: ConfigService) => ({
        secret: configService.get('jwt.secret'),
        signOptions: {
          expiresIn: configService.get('jwt.accessTokenExpiry'),
        },
      }),
    }),
    ScheduleModule.forRoot({}),
    TreatModule,
    AlertModule,
    AuditModule, //* 관리자 행위 감사(T1·T2·T4) — main.ts 의 인터셉터·예외 필터가 app.get() 으로 꺼낸다
    AuditLogModule,
    TreatTestModule,
    AnalyzeModule,
    B2cAnalyzeModule,
    AuthModule,
    AgencyModule,
    AgencyContractModule,
    AgencyOrganizationModule,
    AgencyTermsModule,
    AgencyPolicyModule,
    FcModule,
    AlarmModule,
    SearchModule,
    DrizzleModule,
    CryptoModule,
    ProductModule,
    MedicalModule,
    CardModule,
    SubscribeModule,
    SubscribeFailedModule,
    PaymentModule,
    InvoiceModule,
    OrderModule,
    RefundModule,
    S3Module,
    PdfModule,
    UserModule,
    ReferralModule,
    AllowIpModule,
    CompareBasicModule,
    CompareDetailModule,
    AuthorityModule,
    BoardCategoryModule,
    BoardCommentModule,
    BoardModule,
    ClientModule,
    ClientAnalyzeModule,
    ClientContractModule,
    ClientSettlementModule,
    OrderDetailModule,
    AlimtalkModule,
    BannerModule,
    PopupModule,
    AdminModule,
    SuperAdminModule, //* 전역 — 최고관리자 판정을 쓰는 가드가 어느 모듈에 달려도 주입된다
    StatisticsModule,
    AgencySettlementModule,
    CfnModule,
    LossAdjustmentCategoryModule,
    LossAdjustmentModule,
    LossAdjustmentCommentModule,
    MenuModule,
    AuthGuardModule,
    SalesAgencyModule,
    SalesCommissionModule,
    LogTreatModule,
    AdvertisementModule,
    CoursesCategoryModule,
    CoursesModule,
    CoursesReviewsModule,
    CoursesProgressModule,
    CoursesEnrollmentsModule,
    CoursesBookmarkModule,
    SalesAgencyChannelModule,
    YoutubeModule,
    PushModule,
    DiseaseModule,
    ClinicalResultModule,
    MedicationStandardModule,
    LossAnalysisModule,
    FaxModule,
    MoneyModule,
    InstitutionBlockModule,
    AdminViewTokenModule,
  ],
  controllers: [AppController],
  providers: [{ provide: APP_PIPE, useClass: ClassValidatorPipe }],
})
export class AppModule {}
