/**
 * Backfill Plan Labels CLI —— 回填 / 重算 `plan_reasons.potential_labels`。
 *
 * 初选矩阵靠这一列（改造后不再回查 `patient_facts`，958ms → 110ms）。
 *
 * 🔴 **上线后必须立刻跑一次**：迁移只是加了列，全表都是 NULL，而矩阵
 *   `unnest(potential_labels)` 遇到 NULL 什么都不出 ⇒ **这段时间矩阵会全是 0**。
 *   ⛔ 别指望夜间任务兜 —— 那要等到次日 03:30。
 *
 * ⚠️ ⛔ 不要为了填这一列去「重算 plan」：重算会升版本、关闭无信号的 plan、
 *   `auto_release` 释放客服手上的单 —— 为一个派生列去动召回池，代价完全不对等。
 *   （重算收尾确实也会补齐，但那是顺带，不是手段。）
 *
 * Usage:
 *   pnpm backfill-plan-labels              # 只补没算过的（上线后跑这个）
 *   pnpm backfill-plan-labels -- --all     # 连算过的一起重算（改了标签规则后跑）
 *   pnpm backfill-plan-labels -- --check   # 只报还差多少，不写库
 */
import { NestFactory } from '@nestjs/core';
import { Logger } from '@nestjs/common';
import { AppModule } from '../app.module';
import { PlanLabelService } from '../modules/plan/plan-label.service';

async function main(): Promise<void> {
  const log = new Logger('backfill-plan-labels');
  const argv = process.argv.slice(2);
  const all = argv.includes('--all');
  const checkOnly = argv.includes('--check');

  const app = await NestFactory.createApplicationContext(AppModule, {
    logger: ['error', 'warn', 'log'],
  });
  try {
    const svc = app.get(PlanLabelService);
    const before = await svc.countMissing();
    log.log(`还没算过的依据：${before} 条`);
    if (checkOnly) return;

    const t0 = Date.now();
    const written = all ? await svc.refreshAll() : await svc.backfillMissing();
    const after = await svc.countMissing();
    log.log(
      `${all ? '全量重算' : '回填'}完成：写入 ${written} 条，` +
        `耗时 ${((Date.now() - t0) / 1000).toFixed(1)}s，剩余未算 ${after} 条`,
    );
    // ⚠️ 回填完还有剩 = 有条写入路径没被覆盖到，值得当场查，⛔ 别等矩阵少人了才发现
    if (!all && after > 0) {
      log.error(`⚠️ 回填后仍有 ${after} 条没算过 —— 检查是否有新写入路径没接上补齐`);
      process.exitCode = 1;
    }
  } finally {
    await app.close();
  }
}

main().catch((e) => {
  console.error(e);
  process.exit(1);
});
