import type { IValueObject } from '@core/shared/domain';
import { IdentityDomainValidationError } from '../errors/IdentityDomainError';

export type RatingReferenceType = 'race' | 'penalty' | 'vote' | 'adminAction';

export interface RatingReferenceProps {
  type: RatingReferenceType;
  id: string;
}

const VALID_TYPES: RatingReferenceType[] = ['race', 'penalty', 'vote', 'adminAction'];

export class RatingReference implements IValueObject<RatingReferenceProps> {
  readonly type: RatingReferenceType;
  readonly id: string;

  private constructor(type: RatingReferenceType, id: string) {
    this.type = type;
    this.id = id;
  }

  static create(type: RatingReferenceType, id: string): RatingReference {
    if (!type || !VALID_TYPES.includes(type)) {
      throw new IdentityDomainValidationError(
        `Invalid rating reference type: ${type}. Valid types: ${VALID_TYPES.join(', ')}`
      );
    }

    if (!id || id.trim().length === 0) {
      throw new IdentityDomainValidationError('Rating reference ID cannot be empty');
    }

    const trimmedId = id.trim();
    return new RatingReference(type, trimmedId);
  }

  get props(): RatingReferenceProps {
    return { type: this.type, id: this.id };
  }

  equals(other: IValueObject<RatingReferenceProps>): boolean {
    return this.type === other.props.type && this.id === other.props.id;
  }

  toString(): string {
    return `${this.type}:${this.id}`;
  }

  isRace(): boolean {
    return this.type === 'race';
  }

  isPenalty(): boolean {
    return this.type === 'penalty';
  }

  isVote(): boolean {
    return this.type === 'vote';
  }

  isAdminAction(): boolean {
    return this.type === 'adminAction';
  }
}