/**
 * 검토 적체 모니터링 스케줄러 (Cloud Functions)
 *
 * 실행 주기: 6시간마다 (Asia/Seoul)
 * admin FCM 토큰 보유자에게 SLA 위반 알림 발송
 */

import * as functions from 'firebase-functions';
import * as admin from 'firebase-admin';
import { assessSLALevel, buildFCMPayload } from './backlogMonitoring';

export const monitorReviewerBacklog = functions.pubsub
  .schedule('every 6 hours')
  .timeZone('Asia/Seoul')
  .onRun(async (_context) => {
    const db = admin.firestore();

    // 1. documents 컬렉션에서 검토 대기 문서 조회
    const pendingSnapshot = await db
      .collection('documents')
      .where('status', 'in', ['in_review', 'needs_re_review'])
      .get();

    const pendingCount = pendingSnapshot.size;

    if (pendingCount === 0) {
      functions.logger.info('No pending documents. SLA check skipped.');
      return null;
    }

    // 2. 가장 오래된 updatedAt (또는 submittedForReviewAt) 계산
    let oldestTimestampMs = Date.now();
    pendingSnapshot.forEach((doc) => {
      const data = doc.data();
      const ts: admin.firestore.Timestamp | undefined =
        data.submittedForReviewAt ?? data.updatedAt;
      if (ts) {
        const ms = ts.toMillis();
        if (ms < oldestTimestampMs) {
          oldestTimestampMs = ms;
        }
      }
    });

    const oldestPendingAgeHours = Math.floor(
      (Date.now() - oldestTimestampMs) / (1000 * 60 * 60)
    );

    // 3. SLA 등급 판정
    const assessment = assessSLALevel({ pendingCount, oldestPendingAgeHours });

    if (assessment === null) {
      functions.logger.info('Backlog within SLA limits.', {
        pendingCount,
        oldestPendingAgeHours,
      });
      return null;
    }

    functions.logger.warn('SLA breach detected.', {
      level: assessment.level,
      pendingCount,
      oldestPendingAgeHours,
    });

    // 4. admin 역할 + fcmTokens 보유 유저 조회
    const adminSnapshot = await db
      .collection('users')
      .where('role', '==', 'admin')
      .get();

    const tokens: string[] = [];
    adminSnapshot.forEach((doc) => {
      const fcmTokens: string[] | undefined = doc.data().fcmTokens;
      if (Array.isArray(fcmTokens) && fcmTokens.length > 0) {
        tokens.push(...fcmTokens);
      }
    });

    if (tokens.length === 0) {
      functions.logger.warn('No admin FCM tokens found. Skipping notification.');
      return null;
    }

    // 5. FCM 페이로드 생성 및 멀티캐스트 발송
    const payload = buildFCMPayload(assessment);

    const message: admin.messaging.MulticastMessage = {
      tokens,
      notification: payload.notification,
      data: payload.data,
    };

    const response = await admin.messaging().sendEachForMulticast(message);

    functions.logger.info('FCM multicast result.', {
      successCount: response.successCount,
      failureCount: response.failureCount,
    });

    return null;
  });
