import { Module } from '@nestjs/common';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { ThrottlerModule, ThrottlerGuard } from '@nestjs/throttler';
import { BullModule } from '@nestjs/bull';
import { APP_GUARD } from '@nestjs/core';

// Configuration
import {
  appConfig,
  appConfigValidationSchema,
  databaseConfig,
  blockchainConfig,
  storageConfig,
  redisConfig,
  jwtConfig,
  minioConfig,
} from './config';

// Database
import { DatabaseModule } from './database/database.module';

// Modules
import { AuthModule } from './modules/auth/auth.module';
import { ApplicantsModule } from './modules/applicants/applicants.module';
import { DepartmentsModule } from './modules/departments/departments.module';
import { RequestsModule } from './modules/requests/requests.module';
import { DocumentsModule } from './modules/documents/documents.module';
import { ApprovalsModule } from './modules/approvals/approvals.module';
import { WorkflowsModule } from './modules/workflows/workflows.module';
import { WebhooksModule } from './modules/webhooks/webhooks.module';
import { BlockchainModule } from './modules/blockchain/blockchain.module';
import { AdminModule } from './modules/admin/admin.module';
import { AuditModule } from './modules/audit/audit.module';
import { HealthModule } from './modules/health/health.module';
import { UsersModule } from './modules/users/users.module';

@Module({
  imports: [
    // Configuration
    ConfigModule.forRoot({
      isGlobal: true,
      load: [
        appConfig,
        databaseConfig,
        blockchainConfig,
        storageConfig,
        redisConfig,
        jwtConfig,
        minioConfig,
      ],
      validationSchema: appConfigValidationSchema,
      validationOptions: {
        abortEarly: false,
      },
    }),

    // Database (Knex + Objection.js)
    DatabaseModule,

    // Rate Limiting
    ThrottlerModule.forRootAsync({
      imports: [ConfigModule],
      inject: [ConfigService],
      useFactory: (configService: ConfigService) => {
        const nodeEnv = configService.get<string>('NODE_ENV', 'development');
        const isDevelopment = nodeEnv === 'development' || nodeEnv === 'test';

        return [
          {
            ttl: isDevelopment ? 1000 : configService.get<number>('RATE_LIMIT_TTL', 60) * 1000,
            limit: isDevelopment ? 10000 : configService.get<number>('RATE_LIMIT_GLOBAL', 100),
          },
        ];
      },
    }),

    // Bull Queue (Redis)
    BullModule.forRootAsync({
      imports: [ConfigModule],
      inject: [ConfigService],
      useFactory: (configService: ConfigService) => ({
        redis: {
          host: configService.get<string>('redis.host'),
          port: configService.get<number>('redis.port'),
          password: configService.get<string>('redis.password') || undefined,
          db: configService.get<number>('redis.db'),
        },
      }),
    }),

    // Feature Modules
    AuthModule,
    ApplicantsModule,
    DepartmentsModule,
    RequestsModule,
    DocumentsModule,
    ApprovalsModule,
    WorkflowsModule,
    WebhooksModule,
    BlockchainModule,
    AdminModule,
    AuditModule,
    HealthModule,
    UsersModule,
  ],
  providers: [
    {
      provide: APP_GUARD,
      useClass: ThrottlerGuard,
    },
  ],
})
export class AppModule {}
