import { Module, type DynamicModule, type Type } from "@nestjs/common";
import { APP_INTERCEPTOR, APP_PIPE, RouterModule } from "@nestjs/core";
import { ConfigModule } from "@nestjs/config";
import { ScheduleModule } from "@nestjs/schedule";
import { EventEmitterModule } from "@nestjs/event-emitter";
import { ZodSerializerInterceptor, ZodValidationPipe } from "nestjs-zod";

// Configuration
import { appConfig } from "@bff/core/config/app.config.js";
import { apiRoutes } from "@bff/core/config/router.config.js";

// Vault (conditional — only when VAULT_ADDR is set)
import { VaultModule } from "@bff/core/vault/index.js";

// Core Modules
import { LoggingModule } from "@bff/core/logging/logging.module.js";
import { SecurityModule } from "@bff/core/security/security.module.js";
import { RateLimitModule } from "@bff/core/rate-limiting/index.js";
import { PrismaModule } from "@bff/infra/database/prisma.module.js";
import { RedisModule } from "@bff/infra/redis/redis.module.js";
import { CacheModule } from "@bff/infra/cache/cache.module.js";
import { RealtimePubSubModule } from "@bff/infra/realtime/realtime.module.js";
import { QueueModule } from "@bff/infra/queue/queue.module.js";
import { AuditModule } from "@bff/infra/audit/audit.module.js";
import { EmailModule } from "@bff/infra/email/email.module.js";

// External Integration Modules
import { IntegrationsModule } from "@bff/integrations/integrations.module.js";
import { SalesforceEventsModule } from "@bff/integrations/salesforce/events/events.module.js";

// Feature Modules
import { AuthModule } from "@bff/modules/auth/auth.module.js";
import { GetStartedModule } from "@bff/modules/auth/get-started/get-started.module.js";
import { UsersModule } from "@bff/modules/users/users.module.js";
import { MeStatusModule } from "@bff/modules/me-status/me-status.module.js";
import { MappingsModule } from "@bff/modules/id-mappings/mappings.module.js";
import { ServicesModule } from "@bff/modules/services/services.module.js";
import { OrdersModule } from "@bff/modules/orders/orders.module.js";
import { BillingModule } from "@bff/modules/billing/billing.module.js";
import { SubscriptionsModule } from "@bff/modules/subscriptions/subscriptions.module.js";
import { SimManagementModule } from "@bff/modules/subscriptions/sim-management/sim-management.module.js";
import { InternetManagementModule } from "@bff/modules/subscriptions/internet-management/internet-management.module.js";
import { CallHistoryModule } from "@bff/modules/subscriptions/call-history/call-history.module.js";
import { CurrencyModule } from "@bff/modules/currency/currency.module.js";
import { SupportModule } from "@bff/modules/support/support.module.js";
import { RealtimeApiModule } from "@bff/modules/realtime/realtime.module.js";
import { VerificationModule } from "@bff/modules/verification/verification.module.js";
import { NotificationsModule } from "@bff/modules/notifications/notifications.module.js";
import { AddressModule } from "@bff/modules/address/address.module.js";

// System Modules
import { HealthModule } from "@bff/modules/health/health.module.js";

function conditionalVaultImports(): Array<DynamicModule | Type> {
  const addr = process.env["VAULT_ADDR"];
  const roleId = process.env["VAULT_ROLE_ID"];
  const secretId = process.env["VAULT_SECRET_ID"];
  const secretPath = process.env["VAULT_SECRET_PATH"] ?? "kv/data/services/portal-backend";

  if (!addr || !roleId || !secretId) {
    return [];
  }

  return [
    EventEmitterModule.forRoot(),
    VaultModule.forRoot({ address: addr, roleId, secretId, secretPath }),
  ];
}

/**
 * Main application module
 *
 * Architecture:
 * - Core infrastructure modules provide foundational services
 * - External integration modules handle third-party services
 * - Feature modules implement business logic
 * - System modules provide monitoring and health checks
 *
 * All feature modules are grouped under "/api" prefix via RouterModule
 * Health endpoints remain at root level for monitoring tools
 */
@Module({
  imports: [
    // === CONFIGURATION ===
    ConfigModule.forRoot(appConfig),
    ScheduleModule.forRoot(),

    // === VAULT (conditional) ===
    ...conditionalVaultImports(),

    // === INFRASTRUCTURE ===
    LoggingModule,
    SecurityModule,
    RateLimitModule,

    // === CORE SERVICES ===
    PrismaModule,
    RedisModule,
    CacheModule,
    RealtimePubSubModule,
    QueueModule,
    AuditModule,
    EmailModule,

    // === EXTERNAL INTEGRATIONS ===
    IntegrationsModule,
    SalesforceEventsModule,

    // === FEATURE MODULES ===
    AuthModule,
    GetStartedModule,
    UsersModule,
    MeStatusModule,
    MappingsModule,
    ServicesModule,
    OrdersModule,
    BillingModule,
    SubscriptionsModule,
    SimManagementModule,
    InternetManagementModule,
    CallHistoryModule,
    CurrencyModule,
    SupportModule,
    RealtimeApiModule,
    VerificationModule,
    NotificationsModule,
    AddressModule,

    // === SYSTEM MODULES ===
    HealthModule,

    // === ROUTING ===
    RouterModule.register(apiRoutes),
  ],
  providers: [
    {
      provide: APP_PIPE,
      useClass: ZodValidationPipe,
    },
    {
      provide: APP_INTERCEPTOR,
      useClass: ZodSerializerInterceptor,
    },
  ],
})
export class AppModule {}
