import * as admin from 'firebase-admin';

// Initialize Firebase Admin (Make sure your GOOGLE_APPLICATION_CREDENTIALS is set)
// Usage (dry-run): ts-node scripts/migrate-review-fields.ts
// Usage (execute): ts-node scripts/migrate-review-fields.ts --execute

if (!admin.apps.length) {
  admin.initializeApp();
}

const db = admin.firestore();

// ── 상수 ──────────────────────────────────────────────────────────────────────
const BATCH_SIZE = 500;
const HIGH_RISK_SOURCE_TYPES = ['court_ruling', 'regulation', 'policy_pdf'] as const;

// ── 타입 정의 ─────────────────────────────────────────────────────────────────

interface MigrateResult {
  total: number;
  statusAdded: number;
  riskLevelAdded: number;
  revisionsConsolidated: number;
  errors: number;
}

// ── 순수 함수 ─────────────────────────────────────────────────────────────────

function getRiskLevel(sourceType: string | null | undefined): 'high' | 'low' {
  if (!sourceType) return 'low';
  return (HIGH_RISK_SOURCE_TYPES as readonly string[]).includes(sourceType) ? 'high' : 'low';
}

// ── 핵심 함수 ─────────────────────────────────────────────────────────────────

async function migrateDocument(
  docRef: FirebaseFirestore.DocumentReference,
  docData: FirebaseFirestore.DocumentData,
  dryRun: boolean,
): Promise<{ statusAdded: boolean; riskLevelAdded: boolean }> {
  const updates: Record<string, unknown> = {};
  let statusAdded = false;
  let riskLevelAdded = false;

  // status가 없으면 'published' 추가
  if (!docData.status) {
    updates.status = 'published';
    statusAdded = true;
  }

  // riskLevel이 없으면 sourceType 기반 계산
  if (!docData.riskLevel) {
    updates.riskLevel = getRiskLevel(docData.sourceType ?? null);
    riskLevelAdded = true;
  }

  if (!dryRun && Object.keys(updates).length > 0) {
    await docRef.update(updates);
  }

  return { statusAdded, riskLevelAdded };
}

async function consolidateRevisions(
  docRef: FirebaseFirestore.DocumentReference,
  dryRun: boolean,
): Promise<number> {
  const revisionsSnap = await docRef.collection('revisions').get();
  if (revisionsSnap.empty) return 0;

  const versionsSnap = await docRef.collection('versions').get();
  const existingVersionIds = new Set(versionsSnap.docs.map((d) => d.id));

  let consolidated = 0;

  for (const revDoc of revisionsSnap.docs) {
    if (existingVersionIds.has(revDoc.id)) {
      console.log(`[WARN] ${docRef.id}/revisions/${revDoc.id}는 versions에 이미 존재합니다. 스킵.`);
      continue;
    }

    if (!dryRun) {
      // versions/{id}로 복사
      await docRef.collection('versions').doc(revDoc.id).set(revDoc.data());
      // 원본 revisions에 _migrated: true 마킹 (삭제하지 않음)
      await revDoc.ref.update({ _migrated: true });
    }

    consolidated++;
  }

  return consolidated;
}

async function migrateReviewFields(dryRun: boolean): Promise<MigrateResult> {
  console.log(`[INFO] 리뷰 필드 마이그레이션 시작 (dryRun=${dryRun})`);

  const result: MigrateResult = {
    total: 0,
    statusAdded: 0,
    riskLevelAdded: 0,
    revisionsConsolidated: 0,
    errors: 0,
  };

  const snapshot = await db.collection('documents').get();
  result.total = snapshot.docs.length;

  console.log(`[INFO] 전체 문서 수: ${result.total}`);

  for (let i = 0; i < snapshot.docs.length; i += BATCH_SIZE) {
    const batchDocs = snapshot.docs.slice(i, i + BATCH_SIZE);
    const batchNum = Math.floor(i / BATCH_SIZE) + 1;
    const totalBatches = Math.ceil(snapshot.docs.length / BATCH_SIZE);

    console.log(`[INFO] 배치 ${batchNum}/${totalBatches} 처리 중 (${batchDocs.length}건)...`);

    for (const doc of batchDocs) {
      try {
        const data = doc.data();

        // 1. status / riskLevel 마이그레이션
        const { statusAdded, riskLevelAdded } = await migrateDocument(doc.ref, data, dryRun);
        if (statusAdded) result.statusAdded++;
        if (riskLevelAdded) result.riskLevelAdded++;

        // 2. revisions → versions 서브컬렉션 통합
        const consolidated = await consolidateRevisions(doc.ref, dryRun);
        result.revisionsConsolidated += consolidated;
      } catch (err) {
        console.error(`[ERROR] 문서 처리 중 오류 발생 (id=${doc.id}):`, err);
        result.errors++;
      }
    }
  }

  return result;
}

async function main() {
  const dryRun = !process.argv.includes('--execute');

  if (dryRun) {
    console.log('[DRY-RUN] --execute 플래그 없이 실행 중입니다. 실제 쓰기는 발생하지 않습니다.');
    console.log('[DRY-RUN] 실제 실행: ts-node scripts/migrate-review-fields.ts --execute\n');
  } else {
    console.log('[EXECUTE] 실제 Firestore 쓰기가 실행됩니다.\n');
  }

  const result = await migrateReviewFields(dryRun);

  console.log('\n========== 마이그레이션 완료 요약 ==========');
  console.log(`전체 문서 수           : ${result.total}`);
  console.log(`status 추가 수         : ${result.statusAdded}${dryRun ? ' (dry-run)' : ''}`);
  console.log(`riskLevel 추가 수      : ${result.riskLevelAdded}${dryRun ? ' (dry-run)' : ''}`);
  console.log(`revisions 통합 수      : ${result.revisionsConsolidated}${dryRun ? ' (dry-run)' : ''}`);
  console.log(`오류 수                : ${result.errors}`);
  console.log('===========================================');
}

main().catch((err) => {
  console.error('[FATAL]', err);
  process.exit(1);
});
