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

export type SeasonDropStrategy = 'none' | 'bestNResults' | 'dropWorstN';

export interface SeasonDropPolicyProps {
  strategy: SeasonDropStrategy;
  /**
   * Number of results to consider for strategies that require a count.
   * - bestNResults: keep best N
   * - dropWorstN: drop worst N
   */
  n?: number;
}

export class SeasonDropPolicy implements IValueObject<SeasonDropPolicyProps> {
  readonly strategy: SeasonDropStrategy;
  readonly n?: number;

  constructor(props: SeasonDropPolicyProps) {
    if (!props.strategy) {
      throw new RacingDomainValidationError(
        'SeasonDropPolicy.strategy is required',
      );
    }

    if (props.strategy === 'bestNResults' || props.strategy === 'dropWorstN') {
      if (props.n === undefined || !Number.isInteger(props.n) || props.n <= 0) {
        throw new RacingDomainValidationError(
          'SeasonDropPolicy.n must be a positive integer when using bestNResults or dropWorstN',
        );
      }
    }

    if (props.strategy === 'none' && props.n !== undefined) {
      throw new RacingDomainValidationError(
        'SeasonDropPolicy.n must be undefined when strategy is none',
      );
    }

    this.strategy = props.strategy;
    if (props.n !== undefined) {
      this.n = props.n;
    }
  }

  get props(): SeasonDropPolicyProps {
    return {
      strategy: this.strategy,
      ...(this.n !== undefined ? { n: this.n } : {}),
    };
  }

  equals(other: IValueObject<SeasonDropPolicyProps>): boolean {
    const a = this.props;
    const b = other.props;
    return a.strategy === b.strategy && a.n === b.n;
  }
}