import { Module } from '@nestjs/common';
import { APP_GUARD } from '@nestjs/core';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { EventEmitterModule } from '@nestjs/event-emitter';
import { TypeOrmModule, type TypeOrmModuleOptions } from '@nestjs/typeorm';
import { ThrottlerModule, ThrottlerGuard } from '@nestjs/throttler';
import { ScheduleModule } from '@nestjs/schedule';
import {
  Student,
  Room,
  Occupancy,
  Bed,
  Locker,
  RoomExpense,
  PersonalExpense,
  Bill,
  BillItem,
  User,
  OperationLog,
  RoomInspection,
  RoomInspectionDetail,
  Deposit,
  DepositInstallment,
  Classroom,
  Organization,
  ClassroomRental,
  Permission,
  Role,
  Class,
  ClassStudent,
  ClassTeacher,
  ClassSchedule,
  AttendanceRecord,
  AttendanceSession,
  AttendanceDevice,
  AttendancePeriodConfig,
  DingAttendanceRaw,
  SyncLog,
  SyncState,
  Notification,
  StudentProfile,
  StudentEnrollment,
  ExamScore,
  Exam,
  LearningRecord,
  ExpenseType,
  ResultArchive,
  ArchiveAttachment,
  StudentDingMapping,
  JinshujuMatchRule,
  AiConfig,
  StudentWallet,
  WalletTransaction,
  FinancialOperation,
} from './entities';
import { AuthModule } from './auth/auth.module';
import { InitialSchema1784520727860 } from './migrations/1784520727860-InitialSchema';
import { AddExamManagement1784600000000 } from './migrations/1784600000000-AddExamManagement';
import { AddRoomInspections1784680000000 } from './migrations/1784680000000-AddRoomInspections';
import { AddJinshujuMatchRules1784700000000 } from './migrations/1784700000000-AddJinshujuMatchRules';
const allMigrations = [
  InitialSchema1784520727860,
  AddExamManagement1784600000000,
  AddRoomInspections1784680000000,
  AddJinshujuMatchRules1784700000000,
];
import { AuthorizationModule } from './authorization';
import { RbacModule } from './rbac/rbac.module';
import { StudentsModule } from './students/students.module';
import { PermissionGuard } from './auth/guards/permission.guard';
import { PoliciesGuard } from './authorization/guards/policies.guard';
import { JwtAuthGuard } from './auth/guards/jwt-auth.guard';
import { RoomsModule } from './rooms/rooms.module';
import { OccupanciesModule } from './occupancies/occupancies.module';
import { ExpensesModule } from './expenses/expenses.module';
import { BillsModule } from './bills/bills.module';
import { DashboardModule } from './dashboard/dashboard.module';
import { OperationLogsModule } from './operation-logs/operation-logs.module';
import { DepositsModule } from './deposits/deposits.module';
import { ClassroomsModule } from './classrooms/classrooms.module';
import { ClassesModule } from './classes/classes.module';
import { OrganizationsModule } from './organizations/organizations.module';
import { AttendanceModule } from './attendance/attendance.module';
import { AttendanceDevicesModule } from './attendance-devices/attendance-devices.module';
import { SchedulesModule } from './schedules/schedules.module';
import { ClassroomRentalsModule } from './classroom-rentals/classroom-rentals.module';
import { SyncModule } from './sync/sync.module';
import { NotificationsModule } from './notifications/notifications.module';
import { ArchiveModule } from './archive/archive.module';
import { ExpenseTypesModule } from './expense-types/expense-types.module';
import { DatabaseMigrationsModule } from './database/database-migrations.module';
import { AgentToolsModule } from './agent-tools';
import { AiConfigModule } from './ai-config/ai-config.module';
import { WalletsModule } from './wallets/wallets.module';
import { FinancialOperationsModule } from './financial-operations/financial-operations.module';
import { ExamsModule } from './exams/exams.module';

import {
  IntegrationConfig,
  IntegrationConfigDetail,
} from './integration/entities/integration-config.entity';
import { IntegrationConfigModule } from './integration/config/config.module';

@Module({
  imports: [
    AuthorizationModule,
    ConfigModule.forRoot({ isGlobal: true }),
    ThrottlerModule.forRoot([
      {
        ttl: 60000, // 60秒窗口
        limit: 100, // 普通接口每分钟100次
      },
    ]),
    EventEmitterModule.forRoot(),
    ScheduleModule.forRoot(),
    TypeOrmModule.forRootAsync({
      imports: [ConfigModule],
      inject: [ConfigService],
      useFactory: (config: ConfigService): TypeOrmModuleOptions => {
        const dbType = config.get('DB_TYPE', 'sqlite');
        const allEntities = [
          Student,
          Room,
          Occupancy,
          Bed,
          Locker,
          RoomExpense,
          PersonalExpense,
          Bill,
          BillItem,
          User,
          OperationLog,
          RoomInspection,
          RoomInspectionDetail,
          Deposit,
          DepositInstallment,
          Classroom,
          Organization,
          ClassroomRental,
          Class,
          ClassStudent,
          ClassTeacher,
          Permission,
          Role,
          ClassSchedule,
          AttendanceRecord,
          AttendanceSession,
          AttendanceDevice,
          AttendancePeriodConfig,
          DingAttendanceRaw,
          Notification,
          StudentProfile,
          StudentEnrollment,
          ExamScore,
          Exam,
          LearningRecord,
          StudentDingMapping,
          JinshujuMatchRule,
          ExpenseType,
          ArchiveAttachment,
          ResultArchive,
          SyncLog,
          SyncState,
          StudentDingMapping,
          IntegrationConfig,
          IntegrationConfigDetail,
          AiConfig,
          StudentWallet,
          WalletTransaction,
          FinancialOperation,
        ];
        if (dbType === 'mysql') {
          return {
            type: 'mysql' as const,
            host: config.get('DB_HOST', 'localhost'),
            port: config.get<number>('DB_PORT', 3306),
            username: config.get('DB_USERNAME', 'root'),
            password: config.get<string>('DB_PASSWORD', ''),
            database: config.get<string>('DB_DATABASE', 'dorm_billing'),
            entities: allEntities,
            migrations: allMigrations,
            synchronize: config.get('DB_SYNCHRONIZE', 'true') !== 'false',
            charset: 'utf8mb4',
          };
        }
        return {
          type: 'better-sqlite3' as const,
          database: config.get<string>('DB_DATABASE', 'dorm_billing.db'),
          migrations: allMigrations,
          entities: allEntities,
          synchronize: config.get('DB_SYNCHRONIZE', 'true') !== 'false',
        };
      },
    }),
    DatabaseMigrationsModule,
    AuthModule,
    RbacModule,
    StudentsModule,
    ExamsModule,
    RoomsModule,
    OccupanciesModule,
    ExpensesModule,
    BillsModule,
    DashboardModule,
    OperationLogsModule,
    DepositsModule,
    WalletsModule,
    FinancialOperationsModule,
    ClassroomsModule,
    AttendanceModule,
    AttendanceDevicesModule,
    ClassesModule,
    OrganizationsModule,
    SchedulesModule,
    ClassroomRentalsModule,
    SyncModule,
    NotificationsModule,
    ArchiveModule,
    IntegrationConfigModule,
    AgentToolsModule,
    ExpenseTypesModule,
    AiConfigModule,
  ],
  providers: [
    { provide: APP_GUARD, useClass: ThrottlerGuard },
    { provide: APP_GUARD, useClass: JwtAuthGuard },
    { provide: APP_GUARD, useClass: PermissionGuard },
    { provide: APP_GUARD, useClass: PoliciesGuard },
  ],
})
export class AppModule {}
