import { Module } from '@nestjs/common';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { TypeOrmModule } from '@nestjs/typeorm';
import { ScheduleModule } from '@nestjs/schedule';
import { HttpModule } from '@nestjs/axios';
import { DatabaseModule } from '@it0/database';
import { RedisEventBus } from '@it0/events';
import { TaskController } from './interfaces/rest/controllers/task.controller';
import { ApprovalController } from './interfaces/rest/controllers/approval.controller';
import { RunbookController } from './interfaces/rest/controllers/runbook.controller';
import { StandingOrderController } from './interfaces/rest/controllers/standing-order.controller';
import { TaskRepository } from './infrastructure/repositories/task.repository';
import { ApprovalRepository } from './infrastructure/repositories/approval.repository';
import { RunbookRepository } from './infrastructure/repositories/runbook.repository';
import { StandingOrderRepository } from './infrastructure/repositories/standing-order.repository';
import { StandingOrderExecutionRepository } from './infrastructure/repositories/standing-order-execution.repository';
import { ApprovalWorkflowService } from './domain/services/approval-workflow.service';
import { StandingOrderExecutorService } from './domain/services/standing-order-executor.service';
import { SmartEscalationService } from './domain/services/smart-escalation.service';
import { AgentClientService } from './infrastructure/clients/agent-client.service';
import { CommClientService } from './infrastructure/clients/comm-client.service';
import { CreateInspectionTaskUseCase } from './application/use-cases/create-inspection-task.use-case';
import { CreateDeploymentTaskUseCase } from './application/use-cases/create-deployment-task.use-case';
import { ApproveTaskUseCase } from './application/use-cases/approve-task.use-case';
import { ScheduleRecurringTaskUseCase } from './application/use-cases/schedule-recurring-task.use-case';
import { ExecuteRunbookUseCase } from './application/use-cases/execute-runbook.use-case';
import { CreateStandingOrderUseCase } from './application/use-cases/create-standing-order.use-case';
import { UpdateStandingOrderUseCase } from './application/use-cases/update-standing-order.use-case';
import { ExecuteStandingOrderUseCase } from './application/use-cases/execute-standing-order.use-case';
import { OpsTask } from './domain/entities/ops-task.entity';
import { ApprovalRequest } from './domain/entities/approval-request.entity';
import { Runbook } from './domain/entities/runbook.entity';
import { StandingOrder } from './domain/entities/standing-order.entity';
import { StandingOrderExecution } from './domain/entities/standing-order-execution.entity';

@Module({
  imports: [
    ConfigModule.forRoot({ isGlobal: true }),
    DatabaseModule.forRoot(),
    TypeOrmModule.forFeature([OpsTask, ApprovalRequest, Runbook, StandingOrder, StandingOrderExecution]),
    ScheduleModule.forRoot(),
    HttpModule.register({ timeout: 30000, maxRedirects: 3 }),
  ],
  controllers: [TaskController, ApprovalController, RunbookController, StandingOrderController],
  providers: [
    // Repositories
    TaskRepository,
    ApprovalRepository,
    RunbookRepository,
    StandingOrderRepository,
    StandingOrderExecutionRepository,
    // Domain Services
    ApprovalWorkflowService,
    StandingOrderExecutorService,
    SmartEscalationService,
    // Infrastructure Clients
    AgentClientService,
    CommClientService,
    // Use Cases
    CreateInspectionTaskUseCase,
    CreateDeploymentTaskUseCase,
    ApproveTaskUseCase,
    ScheduleRecurringTaskUseCase,
    ExecuteRunbookUseCase,
    CreateStandingOrderUseCase,
    UpdateStandingOrderUseCase,
    ExecuteStandingOrderUseCase,
    // Event Bus
    {
      provide: RedisEventBus,
      useFactory: (configService: ConfigService) => {
        const redisUrl = configService.get<string>('REDIS_URL', 'redis://localhost:6379');
        return new RedisEventBus(redisUrl);
      },
      inject: [ConfigService],
    },
  ],
})
export class OpsModule {}
