import type { AppraisalStatus, Role } from "@prisma/client";

// Appraisal lifecycle (Crewing-Implementation-Spec §5.4) — mirrors the other
// crewing state machines. A PM raises the appraisal directly into SUBMITTED; this
// machine governs the two review advances. Rejection is orthogonal (handled in
// the actions: an MPO or Manager declines → REJECTED with remarks).

export type AppraisalAction = "verify" | "approve";

interface Transition {
  to: AppraisalStatus;
  allowedRoles: Role[];
}

const VERIFY_ROLES: Role[] = ["MANNING", "MANAGER", "SUPERUSER"]; // verify_appraisal
const APPROVE_ROLES: Role[] = ["MANAGER", "SUPERUSER"]; // approve_appraisal

const TRANSITIONS: Partial<Record<AppraisalStatus, Partial<Record<AppraisalAction, Transition>>>> = {
  SUBMITTED: {
    verify: { to: "MPO_VERIFIED", allowedRoles: VERIFY_ROLES },
  },
  MPO_VERIFIED: {
    approve: { to: "MANAGER_APPROVED", allowedRoles: APPROVE_ROLES },
  },
};

export function getTransition(from: AppraisalStatus, action: AppraisalAction): Transition | null {
  return TRANSITIONS[from]?.[action] ?? null;
}

export function canPerformAction(from: AppraisalStatus, action: AppraisalAction, role: Role): boolean {
  return getTransition(from, action)?.allowedRoles.includes(role) ?? false;
}

// A review may be declined while the appraisal is still in flight.
const REJECTABLE_FROM: AppraisalStatus[] = ["SUBMITTED", "MPO_VERIFIED"];

export function canReject(from: AppraisalStatus): boolean {
  return REJECTABLE_FROM.includes(from);
}
