import { Entity } from '@core/shared/domain/Entity';
import { RacingDomainValidationError } from '../../errors/RacingDomainError';
import type { ParticipantRef } from '../../types/ParticipantRef';
import { Points } from '../../value-objects/Points';
import { Position } from './Position';
import { ResultsCount } from './ResultsCount';

export class ChampionshipStanding extends Entity<string> {
  readonly seasonId: string;
  readonly championshipId: string;
  readonly participant: ParticipantRef;
  readonly totalPoints: Points;
  readonly resultsCounted: ResultsCount;
  readonly resultsDropped: ResultsCount;
  readonly position: Position;

  private constructor(props: {
    seasonId: string;
    championshipId: string;
    participant: ParticipantRef;
    totalPoints: number;
    resultsCounted: number;
    resultsDropped: number;
    position: number;
  }) {
    const id = `${props.seasonId}-${props.championshipId}-${props.participant.id}`;
    super(id);
    this.seasonId = props.seasonId;
    this.championshipId = props.championshipId;
    this.participant = props.participant;
    this.totalPoints = Points.create(props.totalPoints);
    this.resultsCounted = ResultsCount.create(props.resultsCounted);
    this.resultsDropped = ResultsCount.create(props.resultsDropped);
    this.position = Position.create(props.position);
  }

  static create(props: {
    seasonId: string;
    championshipId: string;
    participant: ParticipantRef;
    totalPoints: number;
    resultsCounted: number;
    resultsDropped: number;
    position: number;
  }): ChampionshipStanding {
    if (!props.seasonId || props.seasonId.trim().length === 0) {
      throw new RacingDomainValidationError('Season ID is required');
    }
    if (!props.championshipId || props.championshipId.trim().length === 0) {
      throw new RacingDomainValidationError('Championship ID is required');
    }
    if (!props.participant || !props.participant.id || props.participant.id.trim().length === 0) {
      throw new RacingDomainValidationError('Participant is required');
    }
    return new ChampionshipStanding(props);
  }

  withPosition(position: number): ChampionshipStanding {
    return ChampionshipStanding.create({
      seasonId: this.seasonId,
      championshipId: this.championshipId,
      participant: this.participant,
      totalPoints: this.totalPoints.toNumber(),
      resultsCounted: this.resultsCounted.toNumber(),
      resultsDropped: this.resultsDropped.toNumber(),
      position,
    });
  }
}