/**
 * Domain Entity: Track
 *
 * Represents a racing track/circuit in the GridPilot platform.
 * Immutable entity with factory methods and domain validation.
 */

import { Entity } from '@core/shared/domain/Entity';
import { RacingDomainValidationError } from '../errors/RacingDomainError';
import { TrackCountry } from '../value-objects/TrackCountry';
import { TrackGameId } from '../value-objects/TrackGameId';
import { TrackImageUrl } from '../value-objects/TrackImageUrl';
import { TrackLength } from '../value-objects/TrackLength';
import { TrackName } from '../value-objects/TrackName';
import { TrackShortName } from '../value-objects/TrackShortName';
import { TrackTurns } from '../value-objects/TrackTurns';

export type TrackCategory = 'oval' | 'road' | 'street' | 'dirt';
export type TrackDifficulty = 'beginner' | 'intermediate' | 'advanced' | 'expert';

export class Track extends Entity<string> {
  readonly name: TrackName;
  readonly shortName: TrackShortName;
  readonly country: TrackCountry;
  readonly category: TrackCategory;
  readonly difficulty: TrackDifficulty;
  readonly lengthKm: TrackLength;
  readonly turns: TrackTurns;
  readonly imageUrl: TrackImageUrl;
  readonly gameId: TrackGameId;

  private constructor(props: {
    id: string;
    name: TrackName;
    shortName: TrackShortName;
    country: TrackCountry;
    category: TrackCategory;
    difficulty: TrackDifficulty;
    lengthKm: TrackLength;
    turns: TrackTurns;
    imageUrl: TrackImageUrl;
    gameId: TrackGameId;
  }) {
    super(props.id);
    
    this.name = props.name;
    this.shortName = props.shortName;
    this.country = props.country;
    this.category = props.category;
    this.difficulty = props.difficulty;
    this.lengthKm = props.lengthKm;
    this.turns = props.turns;
    this.imageUrl = props.imageUrl;
    this.gameId = props.gameId;
  }

  /**
   * Factory method to create a new Track entity
   */
  static create(props: {
    id: string;
    name: string;
    shortName?: string;
    country: string;
    category?: TrackCategory;
    difficulty?: TrackDifficulty;
    lengthKm: number;
    turns: number;
    imageUrl?: string;
    gameId: string;
  }): Track {
    if (!props.id || props.id.trim().length === 0) {
      throw new RacingDomainValidationError('Track ID is required');
    }

    const shortNameValue = props.shortName ?? props.name.slice(0, 3).toUpperCase();

    return new Track({
      id: props.id,
      name: TrackName.create(props.name),
      shortName: TrackShortName.create(shortNameValue),
      country: TrackCountry.create(props.country),
      category: props.category ?? 'road',
      difficulty: props.difficulty ?? 'intermediate',
      lengthKm: TrackLength.create(props.lengthKm),
      turns: TrackTurns.create(props.turns),
      imageUrl: TrackImageUrl.create(props.imageUrl),
      gameId: TrackGameId.create(props.gameId),
    });
  }
}