import { Schema } from "effect";

export const WorkStatus = Schema.Literals([
  "proposed",
  "defining",
  "awaiting-definition-approval",
  "designing",
  "awaiting-design-approval",
  "ready",
  "executing",
  "needs-input",
  "blocked",
  "completed",
  "failed",
  "cancelled",
]);
export type WorkStatus = typeof WorkStatus.Type;

export const WORK_TRANSITIONS: Readonly<
  Record<WorkStatus, readonly WorkStatus[]>
> = {
  "awaiting-definition-approval": ["designing", "defining"],
  "awaiting-design-approval": ["ready", "designing"],
  blocked: ["ready", "executing", "cancelled"],
  cancelled: ["ready"],
  completed: [],
  defining: ["awaiting-definition-approval", "proposed"],
  designing: ["awaiting-design-approval", "awaiting-definition-approval"],
  executing: [
    "ready",
    "needs-input",
    "blocked",
    "completed",
    "failed",
    "cancelled",
  ],
  failed: ["ready", "executing", "cancelled"],
  "needs-input": ["ready", "executing", "cancelled"],
  proposed: ["defining"],
  ready: ["executing", "designing", "cancelled"],
};

export const canTransitionWork = (from: WorkStatus, to: WorkStatus): boolean =>
  WORK_TRANSITIONS[from].includes(to);

export const assertWorkTransition = (
  from: WorkStatus,
  to: WorkStatus
): void => {
  if (!canTransitionWork(from, to)) {
    throw new Error(`Invalid Work transition: ${from} -> ${to}`);
  }
};

export const definitionRevisionInvalidation = {
  definitionApproval: "invalidate" as const,
  dependentDesign: "invalidate" as const,
  designApproval: "invalidate" as const,
  workStatus: "defining" as const,
};

export const designRevisionInvalidation = {
  designApproval: "invalidate" as const,
  workStatus: "designing" as const,
};
