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

export interface TeamDrivingReasonCodeProps {
  value: string;
}

/**
 * Valid reason codes for team driving rating events
 */
export const TEAM_DRIVING_REASON_CODES = [
  'RACE_PERFORMANCE',
  'RACE_GAIN_BONUS',
  'RACE_INCIDENTS',
  'RACE_DNF',
  'RACE_DSQ',
  'RACE_DNS',
  'RACE_AFK',
  'RACE_PACE',
  'RACE_DEFENSE',
  'RACE_OVERTAKE',
  'RACE_QUALIFYING',
  'RACE_CONSISTENCY',
  'RACE_TEAMWORK',
  'RACE_SPORTSMANSHIP',
] as const;

export type TeamDrivingReasonCodeValue = (typeof TEAM_DRIVING_REASON_CODES)[number];

/**
 * Value object representing a team driving reason code
 */
export class TeamDrivingReasonCode implements ValueObject<TeamDrivingReasonCodeProps> {
  readonly value: TeamDrivingReasonCodeValue;

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

  static create(value: string): TeamDrivingReasonCode {
    if (!value || value.trim().length === 0) {
      throw new RacingDomainValidationError('Team driving reason code cannot be empty');
    }

    // Strict validation: no leading/trailing whitespace allowed
    if (value !== value.trim()) {
      throw new RacingDomainValidationError(
        `Team driving reason code cannot have leading or trailing whitespace: "${value}"`
      );
    }

    if (!TEAM_DRIVING_REASON_CODES.includes(value as TeamDrivingReasonCodeValue)) {
      throw new RacingDomainValidationError(
        `Invalid team driving reason code: ${value}. Valid options: ${TEAM_DRIVING_REASON_CODES.join(', ')}`
      );
    }

    return new TeamDrivingReasonCode(value as TeamDrivingReasonCodeValue);
  }

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

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

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

  /**
   * Check if this is a performance-related reason
   */
  isPerformance(): boolean {
    return ['RACE_PERFORMANCE', 'RACE_GAIN_BONUS', 'RACE_PACE', 'RACE_QUALIFYING', 'RACE_CONSISTENCY'].includes(this.value);
  }

  /**
   * Check if this is a penalty-related reason
   */
  isPenalty(): boolean {
    return ['RACE_INCIDENTS', 'RACE_DNF', 'RACE_DSQ', 'RACE_DNS', 'RACE_AFK'].includes(this.value);
  }

  /**
   * Check if this is a positive reason
   */
  isPositive(): boolean {
    return ['RACE_PERFORMANCE', 'RACE_GAIN_BONUS', 'RACE_OVERTAKE', 'RACE_DEFENSE', 'RACE_TEAMWORK', 'RACE_SPORTSMANSHIP'].includes(this.value);
  }

  /**
   * Check if this is a negative reason
   */
  isNegative(): boolean {
    return ['RACE_INCIDENTS', 'RACE_DNF', 'RACE_DSQ', 'RACE_DNS', 'RACE_AFK'].includes(this.value);
  }
}