import { MiddlewareConsumer, Module, NestModule } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import { ScheduleModule } from '@nestjs/schedule';
import { ThrottlerModule } from '@nestjs/throttler';
import { rubroContextMiddleware } from './utils/rubro-context';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { AiDashboardModule } from './ai-dashboard/ai-dashboard.module';
import { ImagenesIaModule } from './imagenes-ia/imagenes-ia.module';
import { AiConfigModule } from './ai-dashboard/ai-config/ai-config.module';
import { AyudaIaModule } from './ayuda-ia/ayuda-ia.module';
import { ConciliacionBancariaIaModule } from './conciliacion-bancaria-ia/conciliacion-bancaria-ia.module';
import { AiHoldingModule } from './ai-holding/ai-holding.module';
import { AsignacionesSucursalModule } from './asignaciones-sucursal/asignaciones-sucursal.module';
import { AuditModule } from './audit/audit.module';
import { SeguridadModule } from './seguridad/seguridad.module';
import { AuthModule } from './auth/auth.module';
import { AutorizacionesCajaModule } from './autorizaciones-caja/autorizaciones-caja.module';
import { CajasModule } from './cajas/cajas.module';
import { CategoriasModule } from './categorias/categorias.module';
import { RubrosModule } from './rubros/rubros.module';
import { AlertasEmpresaModule } from './alertas-empresa/alertas-empresa.module';
import { AgentesTransporteModule } from './agentes-transporte/agentes-transporte.module';
import { BancardModule } from './bancard/bancard.module';
import { MarangatuModule } from './marangatu/marangatu.module';
import { NovasisPayModule } from './novasis-pay/novasis-pay.module';
import { ConsultaRucModule } from './consulta-ruc/consulta-ruc.module';
import { CompraAsistidaModule } from './compra-asistida/compra-asistida.module';
import { ChofereModule } from './choferes/choferes.module';
import { ClientesModule } from './clientes/clientes.module';
import { TransportistasModule } from './transportistas/transportistas.module';
import { VehiculosModule } from './vehiculos/vehiculos.module';
import { CobrosModule } from './cobros/cobros.module';
import { CodigosVerificacionModule } from './codigos-verificacion/codigos-verificacion.module';
import { ComprasModule } from './compras/compras.module';
import { NotaCreditoComprasModule } from './nota-credito-compras/nota-credito-compras.module';
import { CondicionesPagoModule } from './condiciones-pago/condiciones-pago.module';
import { GastosModule } from './gastos/gastos.module';
import { GastosImportadorModule } from './gastos/importador/gastos-importador.module';
import { DepositosModule } from './depositos/depositos.module';
import { EmpresasModule } from './empresas/empresas.module';
import { FacturasModule } from './facturas/facturas.module';
import { PresupuestosModule } from './presupuestos/presupuestos.module';
import { KudeModule } from './kude/kude.module';
import { ListaPreciosModule } from './lista-precios/lista-precios.module';
import { ReglasPrecioModule } from './reglas-precio/reglas-precio.module';
import { CostosOperacionCreditoModule } from './costos-operacion-credito/costos-operacion-credito.module';
import { LotesModule } from './lotes/lotes.module';
import { MailModule } from './mail/mail.module';
import { MarcasModule } from './marcas/marcas.module';
import { MedioPagoModule } from './medio-pago/medio-pago.module';
import { MiddlewareSifenModule } from './middleware-sifen/middleware-sifen.module';
import { CrmModule } from './crm/crm.module';
import { ModulosModule } from './modulos/modulos.module';
import { MonedasModule } from './monedas/monedas.module';
import { MovimientosInventarioModule } from './movimientos-inventario/movimientos-inventario.module';
import { InventarioFisicoModule } from './inventario-fisico/inventario-fisico.module';
import { ImportacionesModule } from './importaciones/importaciones.module';
import { ContabilidadModule } from './contabilidad/contabilidad.module';
import { ContabilidadConciliacionModule } from './contabilidad-conciliacion/contabilidad-conciliacion.module';
import { RrhhModule } from './rrhh/rrhh.module';
import { NotaCreditosModule } from './nota-creditos/nota-creditos.module';
import { NotaRemisionModule } from './nota-remision/nota-remision.module';
import { NotificacionesModule } from './notificaciones/notificaciones.module';
import { NumeracionesModule } from './numeraciones/numeraciones.module';
import { OfertasModule } from './ofertas/ofertas.module';
import { PedidosModule } from './pedidos/pedidos.module';
import { PerfilesModule } from './perfiles/perfiles.module';
import { PersonasModule } from './personas/personas.module';
import { PlanLimitsModule } from './plan-limits/plan-limits.module';
import { PlanesCuotasModule } from './planes-cuotas/planes-cuotas.module';
import { PlanesModule } from './planes/planes.module';
import { PagosProveedorModule } from './pagos-proveedor/pagos-proveedor.module';
import { PosConfigModule } from './pos-config/pos-config.module';
import { PosGatewayModule } from './pos-gateway/pos-gateway.module';
import { PrismaModule } from './prisma/prisma.module';
import { PrivilegiosModule } from './privilegios/privilegios.module';
import { ProductoAtributosModule } from './producto-atributos/producto-atributos.module';
import { ProductoEspecificacionesModule } from './producto-especificaciones/producto-especificaciones.module';
import { ProductoPrecioCuotasModule } from './producto-precio-cuotas/producto-precio-cuotas.module';
import { ProductoPresentacionesModule } from './producto-presentaciones/producto-presentaciones.module';
import { ProductosModule } from './productos/productos.module';
import { ProveedoresModule } from './proveedores/proveedores.module';
import { ProveedorMarcaModule } from './proveedor-marca/proveedor-marca.module';
import { ReportesProveedorModule } from './reportes-proveedor/reportes-proveedor.module';
import { ReportesRemisionModule } from './reportes-remision/reportes-remision.module';
import { PuntoExpedicionesModule } from './punto-expediciones/punto-expediciones.module';
import { QueuesModule } from './queues/queues.module';
import { QzModule } from './qz/qz.module';
import { RedisModule } from './redis/redis.module';
import { ReferencialesModule } from './referenciales/referenciales.module';
import { RecepcionesCompraModule } from './recepciones-compra/recepciones-compra.module';
import { ReportesRentabilidadModule } from './reportes-rentabilidad/reportes-rentabilidad.module';
import { RequisicionesModule } from './requisiciones/requisiciones.module';
import { RendicionesModule } from './rendiciones/rendiciones.module';
import { OrdenesCompraModule } from './ordenes-compra/ordenes-compra.module';
import { StockModule } from './stock/stock.module';
import { SucursalesModule } from './sucursales/sucursales.module';
import { SuscripcionesModule } from './suscripciones/suscripciones.module';
import { SyncModule } from './sync/sync.module';
import { TesoreriaModule } from './tesoreria/tesoreria.module';
import { TwilioModule } from './twilio/twilio.module';
import { UsersModule } from './users/users.module';
import { CobranzasModule } from './cobranzas/cobranzas.module';
import { CarteraModule } from './cartera/cartera.module';
import { RecibosModule } from './recibos/recibos.module';
import { SolicitudesCreditoModule } from './solicitudes-credito/solicitudes-credito.module';
import { VendedoresCobradoresModule } from './vendedores-cobradores/vendedores-cobradores.module';
import { RendicionViaticosModule } from './rendicion-viaticos/rendicion-viaticos.module';
import { MobileV1Module } from './mobile/v1/mobile-v1.module';
import { SupervisoresModule } from './supervisores/supervisores.module';
import { StorePublicModule } from './store-public/store-public.module';
import { StoreAuthModule } from './store-auth/store-auth.module';
import { EcommerceModule } from './ecommerce/ecommerce.module';
import { EcommercePagosModule } from './ecommerce/pagos/ecommerce-pagos.module';

@Module({
  imports: [
    ConfigModule.forRoot({
      isGlobal: true,
    }),
    ScheduleModule.forRoot(),
    // Rate limiting. NO se registra como guard global (evita afectar la alta
    // frecuencia del POS): se aplica selectivamente con @UseGuards(ThrottlerGuard)
    // + @Throttle sólo en endpoints sensibles (login, OTP, pagos públicos).
    // Almacenamiento en memoria (por instancia); para despliegue multi-instancia,
    // migrar a storage compartido en Redis.
    ThrottlerModule.forRoot({
      throttlers: [{ ttl: 60_000, limit: 30 }],
      errorMessage:
        'Demasiados intentos en poco tiempo. Por seguridad, esperá un momento antes de volver a intentar.',
    }),
    PrismaModule,
    AuditModule,
    SeguridadModule,
    PlanLimitsModule,
    RedisModule,
    QueuesModule,
    MailModule,
    EmpresasModule,
    AuthModule,
    UsersModule,
    CodigosVerificacionModule,
    ComprasModule,
    NotaCreditoComprasModule,
    RequisicionesModule,
    OrdenesCompraModule,
    RecepcionesCompraModule,
    GastosModule,
    GastosImportadorModule,
    ReferencialesModule,
    ReportesRentabilidadModule,
    SuscripcionesModule,
    TwilioModule,
    NotificacionesModule,
    SucursalesModule,
    ClientesModule,
    ProveedoresModule,
    ProductosModule,
    PersonasModule,
    FacturasModule,
    PresupuestosModule,
    CategoriasModule,
    RubrosModule,
    AlertasEmpresaModule,
    MiddlewareSifenModule,
    CrmModule,
    PlanesModule,
    NotaCreditosModule,
    NotaRemisionModule,
    AsignacionesSucursalModule,
    DepositosModule,
    StockModule,
    MovimientosInventarioModule,
    InventarioFisicoModule,
    ImportacionesModule,
    ContabilidadModule,
    ContabilidadConciliacionModule,
    RrhhModule,
    CajasModule,
    PuntoExpedicionesModule,
    NumeracionesModule,
    MarcasModule,
    ProveedorMarcaModule,
    ReportesProveedorModule,
    ReportesRemisionModule,
    MonedasModule,
    TesoreriaModule,
    PerfilesModule,
    ModulosModule,
    PrivilegiosModule,
    CondicionesPagoModule,
    MedioPagoModule,
    PosConfigModule,
    CobrosModule,
    VendedoresCobradoresModule,
    RendicionViaticosModule,
    SupervisoresModule,
    RendicionesModule,
    ListaPreciosModule,
    ReglasPrecioModule,
    CostosOperacionCreditoModule,
    LotesModule,
    PlanesCuotasModule,
    OfertasModule,
    SyncModule,
    KudeModule,
    QzModule,
    AutorizacionesCajaModule,
    PosGatewayModule,
    ProductoAtributosModule,
    ProductoPresentacionesModule,
    ProductoPrecioCuotasModule,
    ProductoEspecificacionesModule,
    PedidosModule,
    PagosProveedorModule,
    SolicitudesCreditoModule,
    CobranzasModule,
    CarteraModule,
    RecibosModule,
    AiDashboardModule,
    ImagenesIaModule,
    AiConfigModule,
    AyudaIaModule,
    ConciliacionBancariaIaModule,
    AiHoldingModule,
    TransportistasModule,
    ChofereModule,
    VehiculosModule,
    AgentesTransporteModule,
    BancardModule,
    CompraAsistidaModule,
    MarangatuModule,
    NovasisPayModule,
    ConsultaRucModule,
    MobileV1Module,
    StorePublicModule,
    StoreAuthModule,
    EcommerceModule,
    EcommercePagosModule,
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    // Rubro elegido en el selector (header x-rubro-id) → contexto del request,
    // para que el alcance por sucursal lo respete en todos los módulos.
    consumer.apply(rubroContextMiddleware).forRoutes('*');
  }
}
