import * as functions from 'firebase-functions';
import * as admin from 'firebase-admin';
import { computeCompositeReliabilityScore } from './reliabilityScoring';

const BATCH_SIZE = 100;
const FIRESTORE_BATCH_LIMIT = 500;

export const recalculateReliabilityScores = functions.pubsub
  .schedule('every 24 hours')
  .timeZone('Asia/Seoul')
  .onRun(async () => {
    const db = admin.firestore();
    const collection = db.collection('documents');

    let lastDocSnap: admin.firestore.QueryDocumentSnapshot | null = null;
    let totalProcessed = 0;
    let batchWrites: Array<{ ref: admin.firestore.DocumentReference; data: Record<string, unknown> }> = [];

    const flushBatch = async () => {
      if (batchWrites.length === 0) return;

      const batch = db.batch();
      for (const { ref, data } of batchWrites) {
        batch.update(ref, data);
      }
      await batch.commit();
      batchWrites = [];
    };

    // eslint-disable-next-line no-constant-condition
    while (true) {
      // 커서 기반 페이지네이션
      let query = collection.orderBy('__name__').limit(BATCH_SIZE);
      if (lastDocSnap) {
        query = query.startAfter(lastDocSnap);
      }

      const snapshot = await query.get();
      if (snapshot.empty) {
        break;
      }

      for (const docSnap of snapshot.docs) {
        const docData = docSnap.data();

        // reviews 서브컬렉션 count 조회
        const reviewsSnap = await docSnap.ref.collection('reviews').get();
        const reviewCount = reviewsSnap.size;

        // 승인 여부 확인
        const hasApproval = reviewsSnap.docs.some(
          (r) => r.data().decision === 'approve'
        );

        // sourceRef 존재 여부 조회
        const hasSourceRef = !!(docData.sourceRef || docData.sourceRefUrl);
        const sourceRefQuality = docData.sourceRefQuality as string | undefined;

        // updatedAt 처리 (Timestamp → Date)
        let updatedAt: Date;
        if (docData.updatedAt && typeof docData.updatedAt.toDate === 'function') {
          updatedAt = docData.updatedAt.toDate();
        } else {
          updatedAt = new Date();
        }

        const input = {
          verificationStatus: docData.verificationStatus as string | undefined,
          documentStatus: docData.status as string | undefined,
          authorityTier: docData.authorityTier as number | undefined,
          sourceType: docData.sourceType as string | undefined,
          reviewCount,
          hasApproval,
          hasSourceRef,
          sourceRefQuality,
          updatedAt,
        };

        const reliabilityScores = computeCompositeReliabilityScore(input);

        batchWrites.push({
          ref: docSnap.ref,
          data: { reliabilityScores },
        });

        totalProcessed++;

        // Firestore batch 한도(500건)에 가까워지면 flush
        if (batchWrites.length >= FIRESTORE_BATCH_LIMIT) {
          await flushBatch();
        }
      }

      lastDocSnap = snapshot.docs[snapshot.docs.length - 1];

      // 마지막 페이지면 종료
      if (snapshot.size < BATCH_SIZE) {
        break;
      }
    }

    // 남은 배치 flush
    await flushBatch();

    functions.logger.info(
      `[reliabilityBatchRecalc] 완료: ${totalProcessed}건 처리됨`
    );
  });
