import { Module } from '@nestjs/common';
import { PlanController } from './plan.controller';
import { PlanService } from './plan.service';
import { AssignmentController } from './assignment.controller';
import { RearrangeController } from './rearrange.controller';
import { PlanRearrangeService } from './plan-rearrange.service';
import { PlanAssignmentService } from './plan-assignment.service';
import { AgentRosterService } from './agent-roster.service';
import { AssignmentProposalService } from './assignment-proposal.service';
import { CohortAttributesService } from './cohort-attributes.service';
import { ExecutionService } from './execution.service';
import { ExecutionCallbackService } from './execution-callback.service';
import { RecycleSchedulerService } from './recycle-scheduler.service';
import { PlanEngineService } from './engine/plan-engine.service';
import { ChainComposerService } from './engine/chain-composer.service';
import { TreatmentInitiationRecallScenario } from './engine/scenarios/treatment-initiation-recall.scenario';
import { RecallDebugController } from './recall-debug/recall-debug.controller';
import { PlanLabelService } from './plan-label.service';
import { RecallDebugService } from './recall-debug/recall-debug.service';

/**
 * v2.1:plan 一期只跑潜在治疗新链召回(treatment_initiation_recall)。
 * 链已完成召回(aftercare)留后续,文件已删。
 */
/**
 * 🔴 **`AssignmentExpiryScheduler` 已删（2026-08-19 产品定）** —— ⛔ 别加回来。
 *
 * 它做的事是「时限一到，把单子从客服手上收回召回池」。产品改判，理由是**分配的语义**：
 *   · **主管分配的意思是有始有终** —— 他决定了这批人交给谁，那这批人就该在他手上走完；
 *     回池等于把这个决定作废，再重新分一次。
 *   · **容许客服短时超期** —— 没按时打完是常态不是异常，给缓冲让他继续跟进。
 *   · **减少客服之间的调度** —— 回池再分会让同一批患者在人之间来回换手，
 *     而换手本身有成本（客户关系断掉、新接手的人要重新熟悉）。
 * ⇒ **时限到了什么都不发生**：状态不变、归属不变，只是从此算「超期」，
 *   超期由主管在工作台上看见并处理，⛔ 不由系统替他收单。
 *
 * ⚠️ ⛔ **别用测试服的落人分布来给这条决定"补证据"**（我试过，被驳回）：
 *   那是种子数据跑出来的批次，它的 `assign_strategy` 分布说明不了真实运营会怎样。
 *   这条决定站在**语义**上，不站在概率上 —— 而语义不会因为换一批数据就变。
 *
 * ⚠️ 连带成立的两件事（⛔ 别当成 bug 去"修"）：
 *   ① 「在手」只增不减 —— 那是**真的**还压在他手上，产品要看的就是整体负载；
 *   ② 「最忙的那位」会常亮 —— 它本来就是工作量预估不是异常告警（见 assignment-signals）。
 * ⚠️ 单子回池仍有两条路，都是**人主动做的**：客服退回、主管撤销（限时 30 分钟）。
 *
 * 原实现与那 10 条用例在 git 里：`git show HEAD~1 -- apps/pac-service/src/modules/plan/assignment-expiry.scheduler.ts`
 */
@Module({
  // ⚠️⚠️ **AssignmentController 必须排在 PlanController 之前**,顺序不是随意的。
  //   两者的路由前缀都是 `plans`,而 PlanController 有一条裸 `@Get(':id')`(plan.controller:94)。
  //   Nest 按**注册顺序**匹配 → 反过来的话 `GET /plans/assignments` 会被当成
  //   `GET /plans/:id`(id='assignments'),然后去查一个不存在的 plan,
  //   报的还是 Prisma 的 uuid 解析错(90000),完全看不出是路由撞了。
  //   实测踩过一次。同类先例见 plan.controller:80 的 `doctors` 那条注释。
  // ⚠️ 顺序有意义:RearrangeController / AssignmentController 必须排在 PlanController
  //   **之前** —— 后者挂在 `plans` 上且有裸 `@Get(':id')`,Nest 按注册顺序匹配,
  //   排在它后面的话 `/plans/rearrange` 会被当成 planId='rearrange'(实测踩过)。
  controllers: [RearrangeController, AssignmentController, PlanController, RecallDebugController],
  providers: [
    PlanService,
    PlanAssignmentService,
    PlanRearrangeService,
    AgentRosterService,
    AssignmentProposalService,
    CohortAttributesService,
    ExecutionService,
    ExecutionCallbackService,
    RecycleSchedulerService,
    PlanEngineService,
    ChainComposerService,
    TreatmentInitiationRecallScenario,
    RecallDebugService,
    PlanLabelService,
  ],
  // MCP 的主管工具直接用这两个 service(条件注册,见 mcp-server.factory)
  exports: [PlanService, PlanLabelService, PlanAssignmentService, PlanRearrangeService, AgentRosterService, AssignmentProposalService, CohortAttributesService, ExecutionService, ExecutionCallbackService, PlanEngineService, ChainComposerService],
})
export class PlanModule {}
