import * as functions from 'firebase-functions';
import * as admin from 'firebase-admin';

/**
 * 기존 유저 전원의 Firestore role → Custom Claims 백필
 * Admin만 호출 가능한 HTTPS Callable Function
 */

const VALID_ROLES = ['admin', 'reviewer', 'member', 'guest'] as const;
type Role = (typeof VALID_ROLES)[number];

function resolveRole(rawRole: unknown): Role {
  if (typeof rawRole === 'string' && (VALID_ROLES as readonly string[]).includes(rawRole)) {
    return rawRole as Role;
  }
  return 'guest';
}

export const backfillCustomClaims = functions.https.onCall(async (data, context) => {
  // Admin 권한 확인
  if (!context.auth) {
    throw new functions.https.HttpsError('unauthenticated', 'Authentication required');
  }

  // Firestore에서 호출자의 role 확인
  const callerDoc = await admin.firestore().collection('users').doc(context.auth.uid).get();
  const callerRole = callerDoc.data()?.role;

  if (callerRole !== 'admin') {
    throw new functions.https.HttpsError('permission-denied', 'Admin access required');
  }

  const usersSnapshot = await admin.firestore().collection('users').get();

  let processed = 0;
  let skipped = 0;
  let errors = 0;
  const results: Array<{ uid: string; role: Role; status: string }> = [];

  // 배치 처리 (Firebase Auth API rate limit 방지)
  const batchSize = 10;
  const users = usersSnapshot.docs;

  for (let i = 0; i < users.length; i += batchSize) {
    const batch = users.slice(i, i + batchSize);

    await Promise.all(
      batch.map(async (userDoc) => {
        const uid = userDoc.id;
        const role = resolveRole(userDoc.data()?.role);

        try {
          await admin.auth().getUser(uid);
          await admin.auth().setCustomUserClaims(uid, { role });
          processed++;
          results.push({ uid, role, status: 'success' });
        } catch (error: any) {
          if (error.code === 'auth/user-not-found') {
            skipped++;
            results.push({ uid, role, status: 'skipped_no_user' });
          } else {
            errors++;
            results.push({ uid, role, status: `error: ${error.message}` });
            functions.logger.error(`Failed to set claims for ${uid}:`, error);
          }
        }
      })
    );
  }

  functions.logger.info(`Backfill complete: ${processed} processed, ${skipped} skipped, ${errors} errors`);

  return {
    total: users.length,
    processed,
    skipped,
    errors,
    results: data?.verbose ? results : undefined,
  };
});
