/**
 * 数据迁移脚本：将撤回操作的流程实例状态从 TERMINATED 改为 WITHDRAWN
 * 
 * 问题：
 * - 旧版本代码将撤回操作设置为 TERMINATED 状态
 * - 新版本区分 WITHDRAWN（撤回）和 TERMINATED（强制终止）
 * 
 * 迁移逻辑：
 * - 查找所有 status = TERMINATED 且 endReason = 'WITHDRAWN' 或包含 'Withdrawn' 的记录
 * - 或者查找有 WITHDRAW 操作日志的 TERMINATED 流程
 * - 将这些记录的 status 更新为 WITHDRAWN
 */

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

const prisma = new PrismaClient();

async function main() {
  console.log('='.repeat(80));
  console.log('📊 数据迁移：TERMINATED → WITHDRAWN');
  console.log('='.repeat(80));

  try {
    // 1️⃣ 查找需要迁移的记录
    console.log('\n1️⃣ 查找需要迁移的记录...');
    
    // 方法1：通过 endReason 判断
    const instancesByReason = await prisma.approvalInstance.findMany({
      where: {
        status: 'TERMINATED',
        OR: [
          { endReason: { contains: 'Withdrawn', mode: 'insensitive' } },
          { endReason: 'WITHDRAWN' },
        ],
      },
      select: {
        id: true,
        title: true,
        status: true,
        endReason: true,
        initiatorId: true,
        startTime: true,  // ⭐ 使用 startTime 而不是 createdAt
      },
    });

    console.log(`   通过 endReason 找到 ${instancesByReason.length} 条记录`);

    // 方法2：通过操作日志判断（查找有 WITHDRAW 操作的 TERMINATED 流程）
    const withdrawLogs = await prisma.approvalTaskLog.findMany({
      where: {
        action: 'WITHDRAW',
      },
      select: {
        instanceId: true,
      },
      distinct: ['instanceId'],
    });

    const withdrawInstanceIds = withdrawLogs.map(log => log.instanceId);

    const instancesByLog = await prisma.approvalInstance.findMany({
      where: {
        status: 'TERMINATED',
        id: { in: withdrawInstanceIds },
      },
      select: {
        id: true,
        title: true,
        status: true,
        endReason: true,
        initiatorId: true,
        startTime: true,
      },
    });

    console.log(`   通过操作日志找到 ${instancesByLog.length} 条记录`);

    // 合并两种方法的结果（去重）
    const allInstanceIds = new Set([
      ...instancesByReason.map(i => i.id),
      ...instancesByLog.map(i => i.id),
    ]);

    const allInstances = await prisma.approvalInstance.findMany({
      where: {
        id: { in: Array.from(allInstanceIds) },
      },
      include: {
        initiator: {
          select: {
            displayName: true,
          },
        },
      },
    });

    // 获取撤回日志
    const withdrawLogsMap = new Map<string, Date>();
    const allWithdrawLogs = await prisma.approvalTaskLog.findMany({
      where: {
        instanceId: { in: Array.from(allInstanceIds) },
        action: 'WITHDRAW',
      },
      select: {
        instanceId: true,
        actionTime: true,  // ⭐ 使用 actionTime 而不是 createdAt
      },
      orderBy: {
        actionTime: 'asc',  // ⭐ 使用 actionTime
      },
    });

    allWithdrawLogs.forEach(log => {
      if (!withdrawLogsMap.has(log.instanceId)) {
        withdrawLogsMap.set(log.instanceId, log.actionTime);
      }
    });

    console.log(`\n   ✅ 共找到 ${allInstances.length} 条需要迁移的记录：\n`);

    if (allInstances.length === 0) {
      console.log('   没有需要迁移的记录，退出。');
      return;
    }

    // 显示详情
    allInstances.forEach((instance, index) => {
      console.log(`   ${index + 1}. [${instance.id.slice(0, 8)}] ${instance.title}`);
      console.log(`      发起人: ${instance.initiator?.displayName || '未知'}`);
      console.log(`      当前状态: ${instance.status}`);
      console.log(`      结束原因: ${instance.endReason || '无'}`);
      console.log(`      创建时间: ${instance.startTime.toLocaleString('zh-CN')}`);
      const withdrawTime = withdrawLogsMap.get(instance.id);
      if (withdrawTime) {
        console.log(`      撤回时间: ${withdrawTime.toLocaleString('zh-CN')}`);
      }
      console.log('');
    });

    // 2️⃣ 执行迁移
    console.log('='.repeat(80));
    console.log('2️⃣ 开始迁移...\n');

    const result = await prisma.approvalInstance.updateMany({
      where: {
        id: { in: Array.from(allInstanceIds) },
      },
      data: {
        status: 'WITHDRAWN',
      },
    });

    console.log(`   ✅ 成功更新 ${result.count} 条记录\n`);

    // 3️⃣ 验证结果
    console.log('='.repeat(80));
    console.log('3️⃣ 验证迁移结果...\n');

    const verifyInstances = await prisma.approvalInstance.findMany({
      where: {
        id: { in: Array.from(allInstanceIds) },
      },
      select: {
        id: true,
        title: true,
        status: true,
      },
    });

    const successCount = verifyInstances.filter(i => i.status === 'WITHDRAWN').length;
    console.log(`   ✅ 验证通过：${successCount}/${verifyInstances.length} 条记录状态为 WITHDRAWN\n`);

    if (successCount === verifyInstances.length) {
      console.log('='.repeat(80));
      console.log('✅ 迁移成功！');
      console.log('='.repeat(80));
    } else {
      console.error('❌ 部分记录迁移失败，请检查日志');
    }

  } catch (error) {
    console.error('\n❌ 迁移失败：', error);
    throw error;
  } finally {
    await prisma.$disconnect();
  }
}

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

