/**
 * 一次性 standalone smoke：用假 group ID 跑前 80% 链路，零副作用。
 *
 * 验证：
 *   1. EntraService 配置就绪（isEnabled / getSyncGroupId）
 *   2. Graph getUserByEmail 真实查询能拿到 user 对象
 *   3. evaluateGraphUserForAutoAdd 判定 eligible
 *   4. addUserToGroup 用假 group ID 因 404/400 抛业务异常 → 错误处理路径走通
 *
 * 不测：
 *   - audit 写入（要 DB 连接 + 装配 service 依赖图，靠 UAT 验证）
 *   - 真实 group 加成员成功（防污染生产组）
 *
 * 跑法：
 *   cd backend
 *   TS_NODE_COMPILER_OPTIONS='{"module":"commonjs","moduleResolution":"node","resolvePackageJsonExports":false}' \
 *     npx ts-node --transpile-only scripts/probes/auto-add-service-smoke.ts [email]
 *
 *   不传邮箱默认 itadmin@ff.com（FF 租户已知存在的真人 admin）
 */
import 'dotenv/config';
import { ConfigService } from '@nestjs/config';
import { EntraService } from '../../src/modules/organization/entra/entra.service';
import { evaluateGraphUserForAutoAdd } from '../../src/modules/meeting-attendance/services/outlook-attendee-auto-add-filter';

const FAKE_GROUP_ID = '00000000-0000-0000-0000-000000000000';
const TEST_EMAIL = process.argv[2] || 'itadmin@ff.com';

async function main() {
  // 强制覆盖为假 group ID，杜绝意外污染生产组
  process.env.AZURE_ENTRA_SYNC_GROUP_ID = FAKE_GROUP_ID;

  const configService = {
    get: <T = any>(key: string): T | undefined => process.env[key] as T,
  } as unknown as ConfigService;

  const entraService = new EntraService(configService);

  console.log('📋 步骤 0：配置检查');
  console.log(`   isEnabled = ${entraService.isEnabled()}`);
  console.log(`   syncGroupId = ${entraService.getSyncGroupId()}（已强制覆盖为假 ID）`);
  console.log(`   测试邮箱 = ${TEST_EMAIL}`);

  if (!entraService.isEnabled()) {
    console.error('❌ Entra 凭据未配置，检查 .env 是否有 AZURE_TENANT_ID / AZURE_CLIENT_ID / AZURE_CLIENT_SECRET');
    process.exit(1);
  }

  console.log('\n📥 步骤 1：Graph getUserByEmail');
  let user;
  try {
    user = await entraService.getUserByEmail(TEST_EMAIL);
  } catch (err: any) {
    console.error(`❌ getUserByEmail 抛错：${err.message} (statusCode=${err.statusCode})`);
    process.exit(1);
  }

  if (!user) {
    console.log(`   ❌ 该邮箱在 Graph 查不到（mail filter 不匹配，可能是 alias 邮箱）`);
    console.log('   提示：传一个真实存在的员工邮箱再试，比如 npx ts-node ... auto-add-service-smoke.ts xxx@ff.com');
    process.exit(1);
  }
  console.log('   ✅ 查到：');
  console.log(`      id            = ${user.id}`);
  console.log(`      displayName   = ${user.displayName}`);
  console.log(`      mail          = ${user.mail}`);
  console.log(`      mailNickname  = ${user.mailNickname}`);
  console.log(`      userType      = ${user.userType}`);
  console.log(`      accountEnabled= ${user.accountEnabled}`);

  console.log('\n🔍 步骤 2：evaluateGraphUserForAutoAdd');
  const filterResult = evaluateGraphUserForAutoAdd(user, TEST_EMAIL);
  console.log(`   decision    = ${filterResult.decision}`);
  if (filterResult.matchedRule) {
    console.log(`   matchedRule = ${filterResult.matchedRule}`);
  }
  if (filterResult.decision !== 'eligible') {
    console.log(`\n⚠️  本次 smoke 期望 eligible，但拿到 ${filterResult.decision}`);
    console.log('   到此结束（filter 拒绝路径已跑通；如需测加组失败路径，请改用真人邮箱）');
    process.exit(0);
  }

  console.log('\n🚀 步骤 3：addUserToGroup（用假 group ID，期望 404/400 抛错）');
  console.log(`   groupId = ${FAKE_GROUP_ID}（不存在）`);
  console.log(`   userId  = ${user.id}`);
  try {
    const result = await entraService.addUserToGroup(FAKE_GROUP_ID, user.id);
    console.log(`   ❌ 不应该成功！返回 ${JSON.stringify(result)}`);
    console.log('      —— 检查 FAKE_GROUP_ID 是不是恰好命中了真实组（极不可能但理论上不绝对）');
    process.exit(1);
  } catch (error: any) {
    // BusinessException 的 message 是包装过的 code，真实 Graph 信息在 details
    const detailsStatus = error?.details?.statusCode ?? error?.response?.details?.statusCode;
    const detailsBody = error?.details?.body ?? error?.response?.details?.body;
    const businessCode = error?.code ?? error?.response?.code;
    const sc = error?.statusCode ?? detailsStatus;
    const realMessage = error?.response?.message ?? error?.message ?? '';

    console.log(`      error class    = ${error.constructor?.name}`);
    console.log(`      business code  = ${businessCode}`);
    console.log(`      raw message    = ${realMessage}`);
    console.log(`      Graph statusCode (from details) = ${detailsStatus}`);
    if (detailsBody) {
      const bodyStr = typeof detailsBody === 'string' ? detailsBody : JSON.stringify(detailsBody);
      console.log(`      Graph body     = ${bodyStr.slice(0, 500)}`);
    }

    if (sc === 404 || detailsStatus === 404 || /not found|does not exist|invalid object id/i.test(realMessage)
        || (typeof detailsBody === 'string' && /not found|does not exist|invalid/i.test(detailsBody))) {
      console.log('   ✅ 按预期抛错（group 不存在/object id 无效）');
    } else {
      console.log('   ⚠️ 抛错但 Graph 状态码不是 404 — 看上面 raw message / Graph body 判断');
    }
  }

  console.log('\n✅ smoke 完成 — 前 80% 链路通过');
  console.log('   未覆盖（靠 UAT 验证）：audit 写入 + 真实 group 成员添加成功 + 完整 syncAttendees hook 触发');
}

main().catch((err) => {
  console.error('❌ smoke 抛出未捕获异常:', err);
  process.exit(1);
});
