/**
 * 오류 신고(Error Report) Rate Limiter
 *
 * - 문서 레벨: 동일 사용자가 동일 문서에 24시간 내 1회 초과 신고 불가
 * - 글로벌 레벨: 동일 사용자가 24시간 내 10건 초과 신고 불가
 */

import * as FirebaseFirestore from '@google-cloud/firestore';

/**
 * 문서 레벨 rate limit 체크.
 * documents/{docId}/reports에서 reporterId == userId AND createdAt > 24시간 전 조회.
 * 존재하면 allowed: false + retryAfterMs 반환.
 */
export async function checkDocumentRateLimit(
  userId: string,
  docId: string,
  db: FirebaseFirestore.Firestore
): Promise<{ allowed: boolean; retryAfterMs?: number }> {
  const twentyFourHoursAgo = new Date(Date.now() - 24 * 60 * 60 * 1000);

  const snapshot = await db
    .collection('documents')
    .doc(docId)
    .collection('reports')
    .where('reporterId', '==', userId)
    .where('createdAt', '>', twentyFourHoursAgo)
    .get();

  if (!snapshot.empty) {
    // 가장 최근 신고의 createdAt 기준으로 남은 시간 계산
    const latestReport = snapshot.docs.reduce((latest, doc) => {
      const docCreatedAt = doc.data().createdAt?.toDate?.() ?? new Date(0);
      const latestCreatedAt = latest.data().createdAt?.toDate?.() ?? new Date(0);
      return docCreatedAt > latestCreatedAt ? doc : latest;
    });

    const latestCreatedAt: Date =
      latestReport.data().createdAt?.toDate?.() ?? new Date(0);
    const retryAfterMs =
      latestCreatedAt.getTime() + 24 * 60 * 60 * 1000 - Date.now();

    return { allowed: false, retryAfterMs: Math.max(0, retryAfterMs) };
  }

  return { allowed: true };
}

/**
 * 글로벌 rate limit 체크.
 * collectionGroup('reports')에서 reporterId == userId AND createdAt > 24시간 전 조회 (limit 11).
 * 10건 이상이면 allowed: false, remaining: 0.
 * 미만이면 allowed: true, remaining: 10 - count.
 */
export async function checkGlobalRateLimit(
  userId: string,
  db: FirebaseFirestore.Firestore
): Promise<{ allowed: boolean; remaining: number }> {
  const twentyFourHoursAgo = new Date(Date.now() - 24 * 60 * 60 * 1000);

  const snapshot = await db
    .collectionGroup('reports')
    .where('reporterId', '==', userId)
    .where('createdAt', '>', twentyFourHoursAgo)
    .limit(11)
    .get();

  const count = snapshot.size;

  if (count >= 10) {
    return { allowed: false, remaining: 0 };
  }

  return { allowed: true, remaining: 10 - count };
}
