/**
 * Domain Value Object: RaceStatus
 * 
 * Represents the status of a race with strict lifecycle rules.
 */

import type { ValueObject } from '@core/shared/domain/ValueObject';
import { RacingDomainValidationError } from '../errors/RacingDomainError';

export type RaceStatusValue = 'scheduled' | 'running' | 'completed' | 'cancelled';

export interface RaceStatusProps {
  value: RaceStatusValue;
}

export class RaceStatus implements ValueObject<RaceStatusProps> {
  readonly value: RaceStatusValue;

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

  static create(value: RaceStatusValue): RaceStatus {
    if (!value) {
      throw new RacingDomainValidationError('Race status is required');
    }
    return new RaceStatus(value);
  }

  /**
   * Check if race can be started
   */
  canStart(): boolean {
    return this.value === 'scheduled';
  }

  /**
   * Check if race can be completed
   */
  canComplete(): boolean {
    return this.value === 'running';
  }

  /**
   * Check if race can be cancelled
   */
  canCancel(): boolean {
    return this.value === 'scheduled' || this.value === 'running';
  }

  /**
   * Check if race can be reopened
   */
  canReopen(): boolean {
    return this.value === 'completed' || this.value === 'cancelled';
  }

  /**
   * Check if race is in a terminal state
   */
  isTerminal(): boolean {
    return this.value === 'completed' || this.value === 'cancelled';
  }

  /**
   * Check if race is running
   */
  isRunning(): boolean {
    return this.value === 'running';
  }

  /**
   * Check if race is completed
   */
  isCompleted(): boolean {
    return this.value === 'completed';
  }

  /**
   * Check if race is scheduled
   */
  isScheduled(): boolean {
    return this.value === 'scheduled';
  }

  /**
   * Check if race is cancelled
   */
  isCancelled(): boolean {
    return this.value === 'cancelled';
  }

  /**
   * Validate transition from current status to target status
   */
  canTransitionTo(target: RaceStatusValue): { valid: boolean; error?: string } {
    const current = this.value;

    // Define allowed transitions
    const allowedTransitions: Record<RaceStatusValue, RaceStatusValue[]> = {
      scheduled: ['running', 'cancelled'],
      running: ['completed', 'cancelled'],
      completed: ['scheduled'],
      cancelled: ['scheduled'],
    };

    if (!allowedTransitions[current].includes(target)) {
      return {
        valid: false,
        error: `Cannot transition from ${current} to ${target}`
      };
    }

    return { valid: true };
  }

  get props(): RaceStatusProps {
    return { value: this.value };
  }

  equals(other: ValueObject<RaceStatusProps>): boolean {
    return this.value === other.props.value;
  }

  toString(): RaceStatusValue {
    return this.value;
  }
}