export type SessionStateValue =
  | 'PENDING'
  | 'IN_PROGRESS'
  | 'PAUSED'
  | 'COMPLETED'
  | 'FAILED'
  | 'STOPPED_AT_STEP_18';

const VALID_STATES: SessionStateValue[] = [
  'PENDING',
  'IN_PROGRESS',
  'PAUSED',
  'COMPLETED',
  'FAILED',
  'STOPPED_AT_STEP_18',
];

const VALID_TRANSITIONS: Record<SessionStateValue, SessionStateValue[]> = {
  PENDING: ['IN_PROGRESS', 'FAILED'],
  IN_PROGRESS: ['PAUSED', 'COMPLETED', 'FAILED', 'STOPPED_AT_STEP_18'],
  PAUSED: ['IN_PROGRESS', 'FAILED'],
  COMPLETED: [],
  FAILED: [],
  STOPPED_AT_STEP_18: [],
};

export class SessionState {
  private readonly _value: SessionStateValue;

  private constructor(value: SessionStateValue) {
    this._value = value;
  }

  static create(value: SessionStateValue): SessionState {
    if (!VALID_STATES.includes(value)) {
      throw new Error('Invalid session state');
    }
    return new SessionState(value);
  }

  get value(): SessionStateValue {
    return this._value;
  }

  equals(other: SessionState): boolean {
    return this._value === other._value;
  }

  isPending(): boolean {
    return this._value === 'PENDING';
  }

  isInProgress(): boolean {
    return this._value === 'IN_PROGRESS';
  }

  isCompleted(): boolean {
    return this._value === 'COMPLETED';
  }

  isFailed(): boolean {
    return this._value === 'FAILED';
  }

  isStoppedAtStep18(): boolean {
    return this._value === 'STOPPED_AT_STEP_18';
  }

  canTransitionTo(targetState: SessionState): boolean {
    const allowedTransitions = VALID_TRANSITIONS[this._value];
    return allowedTransitions.includes(targetState._value);
  }

  isTerminal(): boolean {
    return (
      this._value === 'COMPLETED' ||
      this._value === 'FAILED' ||
      this._value === 'STOPPED_AT_STEP_18'
    );
  }
}