/**
 * 버전 보존 정책 스케줄러 (Cloud Functions)
 *
 * 실행 주기: 매 24시간 (Asia/Seoul)
 * 각 documents 서브컬렉션 versions에서 삭제 대상 버전을 batch delete
 */

import * as functions from 'firebase-functions';
import * as admin from 'firebase-admin';
import { getVersionsToDelete } from './versionRetention';
import { DEFAULT_RETENTION_CONFIG, VersionInfo } from './types/version';

const BATCH_SIZE = 500; // Firestore batch write 최대 500건

export const cleanupOldVersions = functions.pubsub
  .schedule('every 24 hours')
  .timeZone('Asia/Seoul')
  .onRun(async (_context) => {
    const db = admin.firestore();
    const now = new Date();
    let totalDeleted = 0;

    // 커서 기반으로 documents 컬렉션 순회
    let lastDoc: admin.firestore.QueryDocumentSnapshot | null = null;

    // eslint-disable-next-line no-constant-condition
    while (true) {
      let query = db.collection('documents').orderBy('__name__').limit(100);
      if (lastDoc) {
        query = query.startAfter(lastDoc);
      }

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

      for (const docSnap of snapshot.docs) {
        const versionsSnap = await docSnap.ref.collection('versions').get();
        if (versionsSnap.empty) continue;

        const versions: VersionInfo[] = versionsSnap.docs.map((v) => {
          const data = v.data();
          const createdAt: admin.firestore.Timestamp | undefined = data.createdAt;
          return {
            id: v.id,
            version: data.version ?? 0,
            createdAt: createdAt ? createdAt.toDate() : new Date(0),
          };
        });

        const toDeleteIds = getVersionsToDelete(versions, DEFAULT_RETENTION_CONFIG, now);
        if (toDeleteIds.length === 0) continue;

        // batch delete (500건 단위)
        for (let i = 0; i < toDeleteIds.length; i += BATCH_SIZE) {
          const batch = db.batch();
          const chunk = toDeleteIds.slice(i, i + BATCH_SIZE);
          chunk.forEach((id) => {
            batch.delete(docSnap.ref.collection('versions').doc(id));
          });
          await batch.commit();
          totalDeleted += chunk.length;
        }
      }

      lastDoc = snapshot.docs[snapshot.docs.length - 1];
      if (snapshot.docs.length < 100) break;
    }

    functions.logger.info(`Version cleanup complete. Deleted ${totalDeleted} versions.`, {
      totalDeleted,
    });

    return null;
  });
