/**
 * 검토 시스템 상태 머신
 *
 * 순수 함수로만 구성 (Firebase 의존 없음 → 단위 테스트 용이)
 */

import {
  ReviewDocumentStatus,
  RiskLevel,
  VALID_TRANSITIONS,
  HIGH_RISK_SOURCE_TYPES,
} from './types/review';

/**
 * 상태 전이 유효성 검사
 * VALID_TRANSITIONS 테이블 기반
 */
export function isValidTransition(
  from: ReviewDocumentStatus,
  to: ReviewDocumentStatus
): boolean {
  const allowed = VALID_TRANSITIONS[from];
  return allowed.includes(to);
}

/**
 * 상태 전이 실행
 * 유효하면 targetStatus 반환, 무효하면 Error throw
 */
export function transitionStatus(
  currentStatus: ReviewDocumentStatus,
  targetStatus: ReviewDocumentStatus
): ReviewDocumentStatus {
  if (!isValidTransition(currentStatus, targetStatus)) {
    throw new Error(
      `Invalid status transition: ${currentStatus} → ${targetStatus}. ` +
      `Allowed transitions from '${currentStatus}': [${VALID_TRANSITIONS[currentStatus].join(', ')}]`
    );
  }
  return targetStatus;
}

/**
 * 리스크 레벨 판정
 * HIGH_RISK_SOURCE_TYPES에 포함되면 'high', 아니면 'low'
 */
export function assessRiskLevel(
  sourceType?: string,
  _category?: string
): RiskLevel {
  if (sourceType && (HIGH_RISK_SOURCE_TYPES as readonly string[]).includes(sourceType)) {
    return 'high';
  }
  return 'low';
}

/**
 * 승인 요건 조회
 * low: { reviewerCount: 1, requiresAdmin: false }
 * high: { reviewerCount: 1, requiresAdmin: true } (2단계: reviewer + admin)
 */
export function getRequiredApprovals(
  riskLevel: RiskLevel
): { reviewerCount: number; requiresAdmin: boolean } {
  if (riskLevel === 'high') {
    return { reviewerCount: 1, requiresAdmin: true };
  }
  return { reviewerCount: 1, requiresAdmin: false };
}

/**
 * 승인 가능 여부 판단
 *
 * 저위험: approve 1건 이상이면 OK
 * 고위험: reviewer approve + admin approve 모두 필요 (순서 무관).
 *
 * @param riskLevel       문서의 리스크 레벨
 * @param existingReviews 검토 목록 (decision + reviewerRole 포함)
 */
export function canApprove(
  riskLevel: RiskLevel,
  existingReviews: Array<{ decision: string; reviewerId: string; reviewerRole?: string }>,
  _currentReviewerRole?: string
): boolean {
  const approvals = existingReviews.filter((r) => r.decision === 'approve');

  if (riskLevel === 'low') {
    return approvals.length >= 1;
  }

  // 고위험: reviewer + admin 각각 1건 이상 approve 필요 (순서 무관)
  const hasReviewerApproval = approvals.some((r) => r.reviewerRole === 'reviewer');
  const hasAdminApproval = approvals.some((r) => r.reviewerRole === 'admin');
  return hasReviewerApproval && hasAdminApproval;
}
