/**
 * Domain Value Object: MaxParticipants
 * 
 * Represents the maximum number of participants allowed in a league or race.
 * Enforces reasonable limits and constraints.
 */

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

export interface MaxParticipantsProps {
  value: number;
}

export class MaxParticipants implements IValueObject<MaxParticipantsProps> {
  readonly value: number;

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

  static create(value: number): MaxParticipants {
    if (!Number.isInteger(value) || value <= 0) {
      throw new RacingDomainValidationError('Max participants must be a positive integer');
    }
    
    // Enforce reasonable upper limit to prevent system abuse
    if (value > 100) {
      throw new RacingDomainValidationError('Max participants cannot exceed 100');
    }

    return new MaxParticipants(value);
  }

  /**
   * Validate that max participants meets minimum requirements for ranked leagues
   */
  validateForRankedLeague(): { valid: boolean; error?: string } {
    if (this.value < 10) {
      return {
        valid: false,
        error: 'Ranked leagues must allow at least 10 participants'
      };
    }
    return { valid: true };
  }

  /**
   * Validate that max participants meets minimum requirements for unranked leagues
   */
  validateForUnrankedLeague(): { valid: boolean; error?: string } {
    if (this.value < 2) {
      return {
        valid: false,
        error: 'Unranked leagues must allow at least 2 participants'
      };
    }
    return { valid: true };
  }

  /**
   * Check if max participants is sufficient for the given participant count
   */
  canAccommodate(participantCount: number): boolean {
    return participantCount <= this.value;
  }

  /**
   * Check if max participants is at least the given minimum
   */
  isAtLeast(min: number): boolean {
    return this.value >= min;
  }

  /**
   * Check if max participants is exactly the given value
   */
  isExactly(value: number): boolean {
    return this.value === value;
  }

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

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

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

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