import { Module } from "@nestjs/common";
import { ConfigModule, ConfigService } from "@nestjs/config";
import { TypeOrmModule } from "@nestjs/typeorm";
import { CredentialsCryptoService } from "./credentials-crypto.service";
import { IdentityService } from "./identity.service";
import { TenantConfigService } from "./tenant-config.service";
import { TenantRecordsService } from "./tenant-records.service";
import { Auditoria } from "./entities/auditoria.entity";
import { Identidad } from "./entities/identidad.entity";
import { MigrationJobStep } from "./entities/migration-job-step.entity";
import { MigrationJob } from "./entities/migration-job.entity";
import { SchemaDeviation } from "./entities/schema-deviation.entity";
import { TenantConfig } from "./entities/tenant-config.entity";
import { TenantMembership } from "./entities/tenant-membership.entity";
import { TenantMigrationLock } from "./entities/tenant-migration-lock.entity";
import { Tenant } from "./entities/tenant.entity";

export const CONTROL_PLANE_CONNECTION = "controlPlane";

const ENTITIES = [
  Tenant,
  Identidad,
  TenantMembership,
  TenantConfig,
  Auditoria,
  MigrationJob,
  MigrationJobStep,
  SchemaDeviation,
  TenantMigrationLock,
];

// Conexion NestJS nombrada y estatica al plano de control (mbinvtaller) —
// distinta de las conexiones a tenants, que son dinamicas y viven en
// TenantConnectionRegistry (tenancy module), no en el sistema de modulos de
// Nest, porque su cantidad no se conoce en tiempo de arranque.
@Module({
  imports: [
    TypeOrmModule.forRootAsync({
      name: CONTROL_PLANE_CONNECTION,
      imports: [ConfigModule],
      inject: [ConfigService],
      useFactory: (configService: ConfigService) => ({
        type: "mysql",
        name: CONTROL_PLANE_CONNECTION,
        host: configService.getOrThrow("CONTROL_PLANE_DB_HOST"),
        port: configService.get<number>("CONTROL_PLANE_DB_PORT", 3306),
        username: configService.getOrThrow("CONTROL_PLANE_DB_USERNAME"),
        password: configService.getOrThrow("CONTROL_PLANE_DB_PASSWORD"),
        database: configService.getOrThrow("CONTROL_PLANE_DB_DATABASE"),
        entities: ENTITIES,
        synchronize: false,
        logging: configService.get("NODE_ENV") === "development",
      }),
    }),
    TypeOrmModule.forFeature(ENTITIES, CONTROL_PLANE_CONNECTION),
  ],
  providers: [
    CredentialsCryptoService,
    IdentityService,
    TenantRecordsService,
    TenantConfigService,
  ],
  exports: [
    TypeOrmModule,
    CredentialsCryptoService,
    IdentityService,
    TenantRecordsService,
    TenantConfigService,
  ],
})
export class ControlPlaneModule {}
