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

export interface SeasonScheduleProps {
  startDate: Date;
  timeOfDay: RaceTimeOfDay;
  timezone: LeagueTimezone;
  recurrence: RecurrenceStrategy;
  plannedRounds: number;
}

export class SeasonSchedule implements ValueObject<SeasonScheduleProps> {
  readonly startDate: Date;
  readonly timeOfDay: RaceTimeOfDay;
  readonly timezone: LeagueTimezone;
  readonly recurrence: RecurrenceStrategy;
  readonly plannedRounds: number;

  constructor(params: {
    startDate: Date;
    timeOfDay: RaceTimeOfDay;
    timezone: LeagueTimezone;
    recurrence: RecurrenceStrategy;
    plannedRounds: number;
  }) {
    if (!(params.startDate instanceof Date) || Number.isNaN(params.startDate.getTime())) {
      throw new RacingDomainValidationError('SeasonSchedule.startDate must be a valid Date');
    }
    if (!Number.isInteger(params.plannedRounds) || params.plannedRounds <= 0) {
      throw new RacingDomainValidationError('SeasonSchedule.plannedRounds must be a positive integer');
    }

    this.startDate = new Date(
      params.startDate.getFullYear(),
      params.startDate.getMonth(),
      params.startDate.getDate(),
    );
    this.timeOfDay = params.timeOfDay;
    this.timezone = params.timezone;
    this.recurrence = params.recurrence;
    this.plannedRounds = params.plannedRounds;
  }

  get props(): SeasonScheduleProps {
    return {
      startDate: this.startDate,
      timeOfDay: this.timeOfDay,
      timezone: this.timezone,
      recurrence: this.recurrence,
      plannedRounds: this.plannedRounds,
    };
  }

  equals(other: ValueObject<SeasonScheduleProps>): boolean {
    const a = this.props;
    const b = other.props;
    return (
      a.startDate.getTime() === b.startDate.getTime() &&
      a.timeOfDay.equals(b.timeOfDay) &&
      a.timezone.equals(b.timezone) &&
      a.recurrence.props.kind === b.recurrence.props.kind &&
      a.plannedRounds === b.plannedRounds
    );
  }
}