import { Global, Module } from '@nestjs/common';
import { BullModule } from '@nestjs/bullmq';
import { ConfigModule, ConfigService } from '@nestjs/config';
import type { AppConfig } from '../config/configuration';
import { AuthModule } from '../modules/auth/auth.module';
import { PersonaModule } from '../modules/persona/persona.module';
import { PlanModule } from '../modules/plan/plan.module';
import { SyncModule } from '../modules/sync/sync.module';
import { QueueName } from './queue-names';
import { QueueProducer } from './queue-producer.service';
import { StaleScanService } from './stale-scan.service';
import { SyncIncrementalSchedulerService } from './sync-incremental.scheduler';
import { DwLagMonitorService } from './dw-lag-monitor.service';
import { InvocationRetentionService, PlanLabelRefreshService } from './invocation-retention.service';
import { DailyHealthReportService } from './daily-health-report.service';
import { DailyHealthReportController } from './daily-health-report.controller';
import { PersonaRecomputeProcessor } from './processors/persona-recompute.processor';
import { PlanRecomputeProcessor } from './processors/plan-recompute.processor';
import { PlanAssetGenerateProcessor } from './processors/plan-asset-generate.processor';
import { ExecutionCallbackProcessor } from './processors/execution-callback.processor';
import { ColdImportProcessor } from './processors/cold-import.processor';

/**
 * Queues — BullMQ 三个队列的统一注册入口。
 *
 * 触发链路(详见 apps/pac-docs/content/docs/architecture/three-layer-model.mdx):
 *   pipeline-dispatcher 写完 transaction
 *      → enqueue persona-recompute (jobName=patientId)
 *      → worker 串行跑 → 完成时
 *      → enqueue plan-recompute (jobName=patientId)
 *      → worker 跑出新 plan → 每条新 plan
 *      → enqueue plan-asset-generate (jobName=planId)
 *
 * 兜底:
 *   - 每日凌晨 @Cron(EVERY_DAY_AT_2AM) 扫 stale persona 重新 enqueue
 *   - sync.service @Cron(EVERY_HOUR) 拉数据,事件触发自动跟进
 *
 * Redis 连接:复用 ConfigService.redis.url。BullMQ 要求
 * `maxRetriesPerRequest=null` + `enableReadyCheck=false`(其他设置 ioredis 会报错)。
 */
@Global()
@Module({
  imports: [
    BullModule.forRootAsync({
      imports: [ConfigModule],
      inject: [ConfigService],
      useFactory: (config: ConfigService<AppConfig, true>) => ({
        connection: {
          // ioredis 接受 URL,但 BullMQ 要求几个特殊 flag
          url: config.get('redis', { infer: true }).url,
          maxRetriesPerRequest: null,
          enableReadyCheck: false,
        },
      }),
    }),
    BullModule.registerQueue(
      { name: QueueName.PERSONA_RECOMPUTE },
      { name: QueueName.PLAN_RECOMPUTE },
      { name: QueueName.PLAN_ASSET_GENERATE },
      { name: QueueName.EXECUTION_CALLBACK },
      { name: QueueName.COLD_IMPORT },
    ),
    PersonaModule,
    PlanModule,
    SyncModule, // 给 SyncIncrementalSchedulerService 注入 ColdImportService
    AuthModule, // 给 SyncIncrementalSchedulerService 注入 OrgTreeService(同步后预热)
  ],
  controllers: [DailyHealthReportController],
  providers: [
    QueueProducer,
    StaleScanService,
    SyncIncrementalSchedulerService,
    DwLagMonitorService,
    DailyHealthReportService,
    InvocationRetentionService,
    PlanLabelRefreshService,
    PersonaRecomputeProcessor,
    PlanRecomputeProcessor,
    PlanAssetGenerateProcessor,
    ExecutionCallbackProcessor,
    ColdImportProcessor,
  ],
  exports: [BullModule, QueueProducer, StaleScanService, SyncIncrementalSchedulerService],
})
export class QueuesModule {}
