import { Prisma, PrismaClient } from '@prisma/client';

type CliOptions = {
  mailboxEmail: string;
  apply: boolean;
  sampleSize: number;
};

function printHelp() {
  console.log(`
用法:
  npx ts-node ../scripts/backend/data/cleanup-outlook-event-snapshots.ts --mailbox-email <邮箱> [选项]

说明:
  - 默认是 dry-run，只预览，不删除
  - 只有加 --apply 才会执行删除
  - 执行删除时会默认删除该邮箱 cursor，触发后续初始化重拉快照

选项:
  --mailbox-email <邮箱>         必填，目标邮箱
  --sample-size <数字>           预览样本数量，默认 20
  --apply                        执行删除（危险）
  --help                         查看帮助

示例:
  # 1) 先预览（不删）
  npx ts-node ../scripts/backend/data/cleanup-outlook-event-snapshots.ts \\
    --mailbox-email hongwei.zhang@ff.com

  # 2) 执行清理（会同时重置 cursor）
  npx ts-node ../scripts/backend/data/cleanup-outlook-event-snapshots.ts \\
    --mailbox-email hongwei.zhang@ff.com \\
    --apply
`);
}

function parseArgs(argv: string[]): CliOptions {
  if (argv.includes('--help') || argv.includes('-h')) {
    printHelp();
    process.exit(0);
  }

  const getValue = (flag: string) => {
    const index = argv.indexOf(flag);
    if (index < 0) return undefined;
    return argv[index + 1];
  };

  const mailboxEmail = getValue('--mailbox-email')?.trim();
  if (!mailboxEmail) {
    throw new Error('缺少必填参数: --mailbox-email');
  }

  const sampleSizeRaw = getValue('--sample-size');
  const sampleSize = sampleSizeRaw ? Number(sampleSizeRaw) : 20;
  if (!Number.isInteger(sampleSize) || sampleSize <= 0) {
    throw new Error(`--sample-size 必须是正整数，当前: ${sampleSizeRaw}`);
  }

  return {
    mailboxEmail,
    apply: argv.includes('--apply'),
    sampleSize,
  };
}

function buildWhere(mailboxId: string): Prisma.OutlookEventSnapshotWhereInput {
  return { mailboxId };
}

async function main() {
  const options = parseArgs(process.argv.slice(2));
  const prisma = new PrismaClient();

  try {
    const mailbox = await prisma.outlookSyncMailbox.findUnique({
      where: { mailboxEmail: options.mailboxEmail },
      select: { id: true, mailboxEmail: true, isEnabled: true },
    });
    if (!mailbox) {
      throw new Error(`未找到邮箱: ${options.mailboxEmail}`);
    }

    const where = buildWhere(mailbox.id);
    const [total, samples] = await Promise.all([
      prisma.outlookEventSnapshot.count({ where }),
      prisma.outlookEventSnapshot.findMany({
        where,
        orderBy: [{ startTime: 'asc' }, { updatedAt: 'desc' }],
        take: options.sampleSize,
        select: {
          id: true,
          graphEventId: true,
          eventType: true,
          title: true,
          startTime: true,
          timezone: true,
          updatedAt: true,
        },
      }),
    ]);

    console.log('--- 清理参数 ---');
    console.log(`mailboxEmail: ${mailbox.mailboxEmail}`);
    console.log(`mailboxId: ${mailbox.id}`);
    console.log(`mailboxEnabled: ${mailbox.isEnabled}`);
    console.log('scope: 所有快照记录（按 mailboxId）');
    console.log(`matchedTotal: ${total}`);
    console.log(`mode: ${options.apply ? 'APPLY' : 'DRY-RUN'}`);
    console.log('cursorAction: 执行删除时默认同时清理');

    if (samples.length > 0) {
      console.log('\n--- 样本数据 ---');
      samples.forEach((item, index) => {
        console.log(
          `${index + 1}. id=${item.id}, graphEventId=${item.graphEventId}, type=${item.eventType}, `
          + `title=${JSON.stringify(item.title)}, startTime=${item.startTime?.toISOString() ?? 'null'}, `
          + `timezone=${item.timezone}, updatedAt=${item.updatedAt.toISOString()}`,
        );
      });
    }

    if (!options.apply) {
      console.log('\n当前为 dry-run，未执行删除。确认无误后加 --apply 再执行。');
      return;
    }

    const result = await prisma.$transaction(async (tx) => {
      const deletedSnapshots = await tx.outlookEventSnapshot.deleteMany({ where });
      const cursorResult = await tx.outlookSyncCursor.deleteMany({
        where: { mailboxId: mailbox.id },
      });
      return {
        deletedSnapshots: deletedSnapshots.count,
        deletedCursors: cursorResult.count,
      };
    });

    console.log('\n--- 执行结果 ---');
    console.log(`deletedSnapshots: ${result.deletedSnapshots}`);
    console.log(`deletedCursors: ${result.deletedCursors}`);

    console.log('\n已重置 cursor。下次打开 Outlook 同步页或触发同步时，会走初始化快照重拉。');
  } finally {
    await prisma.$disconnect();
  }
}

main().catch((error) => {
  console.error('脚本执行失败:', error);
  process.exit(1);
});
