/**
 * verify-messagerecords-archive.ts
 *
 * 校验 messagerecords_archive_YYYYMM 归档集合与热表的数据完整性。
 * 对每个已存在的归档集合，按月比较热表与归档的记录数。
 *
 * 用法：
 *   npx ts-node src/scripts/verify-messagerecords-archive.ts             # 检查所有归档月份
 *   npx ts-node src/scripts/verify-messagerecords-archive.ts --month 2024-06  # 仅检查指定月份
 *
 * 输出：
 *   每月打印 hotCount / archiveCount 以及 PASS / FAIL
 *   最终汇总 PASS 月数 / FAIL 月数
 *   如有 FAIL，退出码为 1（供脚本链式调用判断）
 */

import mongoose, { Connection } from "mongoose";

const MONGO_URI = process.env.MONGO_URI || "mongodb://oms:oms123.@localhost:27717/omsdb?authSource=admin";

const monthArg = (() => {
  const idx = process.argv.indexOf("--month");
  return idx !== -1 ? process.argv[idx + 1] : null;
})();

function parseArchiveMonthFromName(name: string): string | null {
  const m = name.match(/^messagerecords_archive_(\d{6})$/);
  return m ? m[1] : null;
}

function yyyymmToRange(yyyymm: string): { start: Date; end: Date } {
  const year = parseInt(yyyymm.slice(0, 4), 10);
  const month = parseInt(yyyymm.slice(4, 6), 10) - 1; // 0-indexed
  return {
    start: new Date(year, month, 1),
    end: new Date(year, month + 1, 1),
  };
}

async function run() {
  console.log("[Verify] Connecting to MongoDB...");
  const conn = await mongoose.createConnection(MONGO_URI).asPromise();
  console.log("[Verify] Connected.");

  const hotCol = conn.collection("messagerecords");

  // 获取所有 archive 集合
  const allCollections = await conn.db.listCollections().toArray();
  let archiveCollections = allCollections
    .map((c) => c.name)
    .filter((name) => parseArchiveMonthFromName(name) !== null)
    .sort();

  if (archiveCollections.length === 0) {
    console.log("[Verify] No archive collections found. Run archive-messagerecords.ts --execute first.");
    await conn.close();
    process.exit(0);
  }

  // 过滤单月
  if (monthArg) {
    const yyyymm = monthArg.replace("-", "");
    archiveCollections = archiveCollections.filter((name) => name.endsWith(yyyymm));
    if (archiveCollections.length === 0) {
      console.error(`[Verify] ERROR: No archive collection found for month ${monthArg}`);
      await conn.close();
      process.exit(1);
    }
  }

  console.log(`[Verify] Checking ${archiveCollections.length} archive collection(s)...\n`);

  let passCount = 0;
  let failCount = 0;
  const failMonths: string[] = [];

  for (const colName of archiveCollections) {
    const yyyymm = parseArchiveMonthFromName(colName)!;
    const { start, end } = yyyymmToRange(yyyymm);

    const [hotCount, archiveCount] = await Promise.all([
      hotCol.countDocuments({ createdAt: { $gte: start, $lt: end } }),
      conn.collection(colName).countDocuments({ createdAt: { $gte: start, $lt: end } }),
    ]);

    const status = archiveCount >= hotCount ? "PASS" : "FAIL";
    const diff = archiveCount - hotCount;
    const diffStr = diff >= 0 ? `+${diff}` : `${diff}`;

    console.log(`[Verify] ${yyyymm}: hot=${hotCount.toLocaleString().padStart(10)} archive=${archiveCount.toLocaleString().padStart(10)} diff=${diffStr.padStart(7)} → ${status}`);

    if (status === "PASS") {
      passCount++;
    } else {
      failCount++;
      failMonths.push(yyyymm);
    }
  }

  console.log(`\n[Verify] SUMMARY: PASS=${passCount} FAIL=${failCount}`);
  if (failMonths.length > 0) {
    console.log(`[Verify] FAILED months: ${failMonths.join(", ")}`);
    console.log("[Verify] Re-run archive-messagerecords.ts --execute for failed months before purging.");
  } else {
    console.log("[Verify] All archive collections are complete. Safe to run purge-messagerecords-hot.ts.");
  }

  await conn.close();
  process.exit(failCount > 0 ? 1 : 0);
}

run().catch((err) => {
  console.error("[Verify] FATAL:", err);
  process.exit(1);
});
