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

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

export type SeasonStatusValue = 'planned' | 'active' | 'completed' | 'archived' | 'cancelled';

export interface SeasonStatusProps {
  value: SeasonStatusValue;
}

export class SeasonStatus implements IValueObject<SeasonStatusProps> {
  readonly value: SeasonStatusValue;

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

  static create(value: SeasonStatusValue): SeasonStatus {
    if (!value) {
      throw new RacingDomainValidationError('Season status is required');
    }
    return new SeasonStatus(value);
  }

  /**
   * Check if season can be activated
   */
  canActivate(): boolean {
    return this.value === 'planned';
  }

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

  /**
   * Check if season can be archived
   */
  canArchive(): boolean {
    return this.value === 'completed';
  }

  /**
   * Check if season can be cancelled
   */
  canCancel(): boolean {
    return this.value === 'planned' || this.value === 'active';
  }

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

  /**
   * Check if season is active
   */
  isActive(): boolean {
    return this.value === 'active';
  }

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

  /**
   * Check if season is planned
   */
  isPlanned(): boolean {
    return this.value === 'planned';
  }

  /**
   * Check if season is archived
   */
  isArchived(): boolean {
    return this.value === 'archived';
  }

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

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

    // Define allowed transitions
    const allowedTransitions: Record<SeasonStatusValue, SeasonStatusValue[]> = {
      planned: ['active', 'cancelled'],
      active: ['completed', 'cancelled'],
      completed: ['archived'],
      archived: [],
      cancelled: [],
    };

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

    return { valid: true };
  }

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

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

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