/**
 * import-real-phones — 用外部对照表(病历号 → 真实手机号)替换库里的造数假号。
 *
 * 背景:测试库 phone 全是造数假号;业务给了 1500 个患者的真实号码(按病历号对照)。
 * 行为:按 medical_record_number 匹配 → phone 改为真号 + phoneVerified=true(列表"真实号码"筛选用)。
 * 匹配不到的病历号原样跳过(本地数据不全属预期);号码做基本卫生(去空格/非数字字符)。
 *
 * 跑:
 *   pnpm --filter pac-service exec ts-node -r tsconfig-paths/register src/cli/import-real-phones.cli.ts -- --csv=/tmp/phone_match.csv
 *   # 或编译后: node dist/cli/import-real-phones.cli.js --csv=...
 * CSV 格式(带表头): file_num,client_phone
 *   --dry-run 只统计不写库
 */
import { readFileSync } from 'node:fs';
import { NestFactory } from '@nestjs/core';
import { Logger } from '@nestjs/common';
import { AppModule } from '../app.module';
import { PrismaService } from '../prisma/prisma.service';

interface Row {
  fileNum: string;
  phone: string;
}

function parseCsv(path: string): Row[] {
  const lines = readFileSync(path, 'utf8').split(/\r?\n/).filter((l) => l.trim());
  const out: Row[] = [];
  for (const [i, line] of lines.entries()) {
    if (i === 0 && /file_num/i.test(line)) continue; // 表头
    const [fileNum, phone] = line.split(',').map((s) => s?.trim() ?? '');
    if (!fileNum || !phone) continue;
    const digits = phone.replace(/\D/g, '');
    if (digits.length < 7) continue; // 垃圾行防御
    out.push({ fileNum, phone: digits });
  }
  return out;
}

async function main(): Promise<void> {
  const logger = new Logger('ImportRealPhones');
  const csvArg = process.argv.find((a) => a.startsWith('--csv='))?.slice('--csv='.length);
  const dryRun = process.argv.includes('--dry-run');
  if (!csvArg) {
    logger.error('用法: --csv=<对照表.csv>(列: file_num,client_phone)[--dry-run]');
    process.exit(1);
  }

  const rows = parseCsv(csvArg);
  logger.log(`对照表 ${rows.length} 行(去表头/垃圾后)`);

  const app = await NestFactory.createApplicationContext(AppModule, { logger: ['error', 'warn'] });
  const prisma = app.get(PrismaService);
  try {
    let matched = 0;
    let updated = 0;
    const sample: string[] = [];
    // 1500 行量级,逐行 updateMany 即可(病历号可能跨患者重复 → updateMany 全更)
    for (const r of rows) {
      const hit = await prisma.patient.findMany({
        where: { medicalRecordNumber: r.fileNum },
        select: { id: true },
      });
      if (hit.length === 0) continue;
      matched += 1;
      if (!dryRun) {
        const res = await prisma.patient.updateMany({
          where: { medicalRecordNumber: r.fileNum },
          data: { phone: r.phone, phoneVerified: true },
        });
        updated += res.count;
      } else {
        updated += hit.length;
      }
      if (sample.length < 5) sample.push(`${r.fileNum} → ${r.phone.slice(0, 3)}****${r.phone.slice(-4)}`);
    }
    logger.log(
      `${dryRun ? '[dry-run] ' : ''}匹配病历号 ${matched}/${rows.length},更新患者 ${updated} 名`,
    );
    if (sample.length) logger.log(`样例: ${sample.join(' | ')}`);

    const verifiedTotal = await prisma.patient.count({ where: { phoneVerified: true } });
    logger.log(`库内 phoneVerified=true 总数: ${verifiedTotal}`);
  } finally {
    await app.close();
  }
}

void main();
