import { RacingDomainValidationError } from '../../errors/RacingDomainError';

export type PenaltyTypeValue =
  | 'time_penalty'
  | 'grid_penalty'
  | 'points_deduction'
  | 'disqualification'
  | 'warning'
  | 'license_points'
  | 'probation'
  | 'fine'
  | 'race_ban';

export const PENALTY_TYPE_VALUES: PenaltyTypeValue[] = [
  'time_penalty',
  'grid_penalty',
  'points_deduction',
  'disqualification',
  'warning',
  'license_points',
  'probation',
  'fine',
  'race_ban',
];

export type PenaltyValueKind = 'seconds' | 'grid_positions' | 'points' | 'races' | 'none';

export function getPenaltyValueKind(type: PenaltyTypeValue): PenaltyValueKind {
  switch (type) {
    case 'time_penalty':
      return 'seconds';
    case 'grid_penalty':
      return 'grid_positions';
    case 'points_deduction':
    case 'license_points':
    case 'fine':
      return 'points';
    case 'race_ban':
      return 'races';
    case 'disqualification':
    case 'warning':
    case 'probation':
      return 'none';
  }
}

export class PenaltyType {
  private constructor(private readonly value: PenaltyTypeValue) {}

  static create(value: string): PenaltyType {
    if (!PENALTY_TYPE_VALUES.includes(value as PenaltyTypeValue)) {
      throw new RacingDomainValidationError(`Invalid penalty type: ${value}`);
    }

    return new PenaltyType(value as PenaltyTypeValue);
  }

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

  equals(other: PenaltyType): boolean {
    return this.value === other.value;
  }
}