import type {
  ClusterId,
  ConnectionId,
  CredentialReferenceId,
  MachineCapabilityId,
  MachineEnrollmentId,
  MachineId,
  MachinePreflightReport,
  OperationId,
} from "@awp/contracts";

export type ClusterStatus = "active" | "degraded" | "disabled";
export interface Cluster {
  readonly id: ClusterId;
  readonly name: string;
  readonly apiServerUrl: string;
  readonly joinCredentialReferenceId: CredentialReferenceId;
  readonly status: ClusterStatus;
  readonly revision: number;
}

export type MachineStatus = "onboarding" | "enrolling" | "ready" | "degraded" | "removed";
export interface Machine {
  readonly id: MachineId;
  readonly clusterId: ClusterId;
  readonly name: string;
  readonly address: string;
  readonly sshUser: string;
  readonly sshConnectionId: ConnectionId;
  readonly sshCredentialReferenceId: CredentialReferenceId;
  readonly labels: Readonly<Record<string, string>>;
  readonly status: MachineStatus;
  readonly providerNodeName?: string;
  readonly failureReason?: string;
  readonly lastObservedAt?: string;
  readonly revision: number;
}

export interface MachineCapability {
  readonly id: MachineCapabilityId;
  readonly machineId: MachineId;
  readonly key: string;
  readonly value: string;
  readonly source: "preflight" | "kubernetes";
  readonly observedAt: string;
}

export interface MachineEnrollment {
  readonly id: MachineEnrollmentId;
  readonly operationId: OperationId;
  readonly machineId: MachineId;
  readonly phase:
    | "requested"
    | "preflight"
    | "awaiting-confirmation"
    | "installing"
    | "joining"
    | "verifying"
    | "discovering"
    | "completed"
    | "failed";
  readonly preflight?: MachinePreflightReport;
  readonly failureReason?: string;
  readonly requestedAt: string;
  readonly updatedAt: string;
  readonly revision: number;
}

export function assertEnrollmentMayApply(enrollment: MachineEnrollment): MachinePreflightReport {
  const report = enrollment.preflight;
  if (!report) throw new Error("Machine enrollment has no preflight result");
  if (enrollment.phase !== "awaiting-confirmation")
    throw new Error(`Machine enrollment is not awaiting confirmation: ${enrollment.phase}`);
  if (report.state === "foreign" || report.state === "partial" || report.state === "unsupported")
    throw new Error(`Machine enrollment preflight blocks mutation: ${report.state}`);
  if (!report.reachable) throw new Error("Machine enrollment target is not reachable");
  return report;
}
