import * as functions from 'firebase-functions';
import * as admin from 'firebase-admin';
import { ReviewDocumentStatus, Review } from './types/review';
import { transitionStatus, canApprove, assessRiskLevel } from './reviewStateMachine';
import { writeAuditLog } from './auditLog';

export const onReviewCreate = functions.firestore
  .document('documents/{docId}/reviews/{reviewId}')
  .onCreate(async (snap, context) => {
    const { docId, reviewId } = context.params;
    const reviewData = snap.data() as Review;
    const db = admin.firestore();

    // 1. 문서 조회
    const docRef = db.collection('documents').doc(docId);
    const docSnap = await docRef.get();
    if (!docSnap.exists) {
      functions.logger.error(`Document ${docId} not found for review ${reviewId}`);
      return;
    }

    const docData = docSnap.data()!;
    const currentStatus = (docData.status ?? 'published') as ReviewDocumentStatus;
    const sourceType = docData.sourceType;
    const riskLevel = assessRiskLevel(sourceType);

    // 2. 결정에 따른 상태 전이
    let newStatus: ReviewDocumentStatus | null = null;

    if (reviewData.decision === 'reject') {
      // 거절 → rejected
      try {
        newStatus = transitionStatus(currentStatus, 'rejected');
      } catch (e) {
        functions.logger.warn(`Cannot transition ${currentStatus} → rejected: ${e}`);
        return;
      }
    } else if (reviewData.decision === 'request_revision') {
      // 수정 요청 → revision_requested
      try {
        newStatus = transitionStatus(currentStatus, 'revision_requested');
      } catch (e) {
        functions.logger.warn(`Cannot transition ${currentStatus} → revision_requested: ${e}`);
        return;
      }
    } else if (reviewData.decision === 'approve') {
      // 승인 — 기존 리뷰를 조회하여 canApprove 판단
      const reviewsSnap = await docRef.collection('reviews').get();
      const allReviews = reviewsSnap.docs.map(d => ({
        decision: d.data().decision as string,
        reviewerId: d.data().reviewerId as string,
      }));

      // 각 approval 리뷰어의 역할 조회 (고위험 2단계 판정에 필요)
      const allReviewsWithRoles = await Promise.all(
        allReviews.map(async (r) => {
          const userDoc = await db.collection('users').doc(r.reviewerId).get();
          return { ...r, reviewerRole: userDoc.data()?.role ?? 'reviewer' };
        })
      );

      if (canApprove(riskLevel, allReviewsWithRoles)) {
        try {
          newStatus = transitionStatus(currentStatus, 'approved');
        } catch (e) {
          functions.logger.warn(`Cannot transition ${currentStatus} → approved: ${e}`);
          return;
        }
      } else {
        functions.logger.info(
          `Review ${reviewId} approved but waiting for additional approvals ` +
          `(risk: ${riskLevel}, approvals: ${allReviews.filter(r => r.decision === 'approve').length})`
        );
      }
    }

    // 3. 상태 업데이트 + 감사 로그
    if (newStatus) {
      await docRef.update({
        status: newStatus,
        riskLevel: riskLevel,
        updatedAt: admin.firestore.FieldValue.serverTimestamp(),
      });

      await writeAuditLog({
        docId,
        action: 'review_submitted',
        actorId: reviewData.reviewerId,
        actorName: reviewData.reviewerName,
        previousStatus: currentStatus,
        newStatus,
        metadata: {
          reviewId,
          decision: reviewData.decision,
          riskLevel,
        },
      });
    }

    // 4. riskLevel 아직 없으면 설정
    if (!docData.riskLevel) {
      await docRef.update({ riskLevel });
      await writeAuditLog({
        docId,
        action: 'risk_level_assessed',
        actorId: 'system',
        metadata: { riskLevel, sourceType },
      });
    }
  });
