/**
 * Domain Value Object: StrengthOfField
 * 
 * Represents the strength of field (SOF) rating for a race or league.
 * Enforces valid range and provides domain-specific operations.
 */

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

export interface StrengthOfFieldProps {
  value: number;
}

export class StrengthOfField implements ValueObject<StrengthOfFieldProps> {
  readonly value: number;

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

  static create(value: number): StrengthOfField {
    if (!Number.isInteger(value)) {
      throw new RacingDomainValidationError('Strength of field must be an integer');
    }

    // SOF represents iRating-like values (commonly ~0-10k), not a 0-100 percentage.
    if (value < 0 || value > 10_000) {
      throw new RacingDomainValidationError(
        'Strength of field must be between 0 and 10000',
      );
    }

    return new StrengthOfField(value);
  }

  /**
   * Get the strength category
   */
  getCategory(): 'beginner' | 'intermediate' | 'advanced' | 'expert' {
    if (this.value < 1500) return 'beginner';
    if (this.value < 2500) return 'intermediate';
    if (this.value < 4000) return 'advanced';
    return 'expert';
  }

  /**
   * Check if this SOF is suitable for the given participant count
   */
  isSuitableForParticipants(count: number): boolean {
    // Higher SOF should generally have more participants.
    const minExpected = Math.floor(this.value / 500);
    return count >= minExpected;
  }

  /**
   * Calculate difference from another SOF
   */
  differenceFrom(other: StrengthOfField): number {
    return Math.abs(this.value - other.value);
  }

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

  toNumber(): number {
    return this.value;
  }

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

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