/**
 * Domain Entity: Car
 *
 * Represents a racing car/vehicle 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 { CarClass, CarClassType } from './CarClass';
import { CarId } from './CarId';
import { CarLicense, CarLicenseType } from './CarLicense';
import { CarName } from './CarName';
import { GameId } from './GameId';
import { Horsepower } from './Horsepower';
import { ImageUrl } from './ImageUrl';
import { Manufacturer } from './Manufacturer';
import { Weight } from './Weight';
import { Year } from './Year';

export class Car extends Entity<CarId> {
  readonly name: CarName;
  readonly shortName: string;
  readonly manufacturer: Manufacturer;
  readonly carClass: CarClass;
  readonly license: CarLicense;
  readonly year: Year;
  readonly horsepower: Horsepower | undefined;
  readonly weight: Weight | undefined;
  readonly imageUrl: ImageUrl | undefined;
  readonly gameId: GameId;

  private constructor(props: {
    id: CarId;
    name: CarName;
    shortName: string;
    manufacturer: Manufacturer;
    carClass: CarClass;
    license: CarLicense;
    year: Year;
    horsepower?: Horsepower;
    weight?: Weight;
    imageUrl?: ImageUrl;
    gameId: GameId;
  }) {
    super(props.id);
    
    this.name = props.name;
    this.shortName = props.shortName;
    this.manufacturer = props.manufacturer;
    this.carClass = props.carClass;
    this.license = props.license;
    this.year = props.year;
    this.horsepower = props.horsepower;
    this.weight = props.weight;
    this.imageUrl = props.imageUrl;
    this.gameId = props.gameId;
  }

  /**
   * Factory method to create a new Car entity
   */
  static create(props: {
    id: string;
    name: string;
    shortName?: string;
    manufacturer: string;
    carClass?: CarClassType;
    license?: CarLicenseType;
    year?: number;
    horsepower?: number;
    weight?: number;
    imageUrl?: string;
    gameId: string;
  }): Car {
    this.validate(props);

    return new Car({
      id: CarId.create(props.id),
      name: CarName.create(props.name),
      shortName: props.shortName ?? props.name.slice(0, 10),
      manufacturer: Manufacturer.create(props.manufacturer),
      carClass: CarClass.create(props.carClass ?? 'gt'),
      license: CarLicense.create(props.license ?? 'D'),
      year: Year.create(props.year ?? new Date().getFullYear()),
      ...(props.horsepower !== undefined ? { horsepower: Horsepower.create(props.horsepower) } : {}),
      ...(props.weight !== undefined ? { weight: Weight.create(props.weight) } : {}),
      ...(props.imageUrl !== undefined ? { imageUrl: ImageUrl.create(props.imageUrl) } : {}),
      gameId: GameId.create(props.gameId),
    });
  }

  /**
   * Domain validation logic
   */
  private static validate(props: {
    id: string;
    name: string;
    manufacturer: string;
    gameId: string;
  }): void {
    if (!props.id || props.id.trim().length === 0) {
      throw new RacingDomainValidationError('Car ID is required');
    }

    if (!props.name || props.name.trim().length === 0) {
      throw new RacingDomainValidationError('Car name is required');
    }

    if (!props.manufacturer || props.manufacturer.trim().length === 0) {
      throw new RacingDomainValidationError('Car manufacturer is required');
    }

    if (!props.gameId || props.gameId.trim().length === 0) {
      throw new RacingDomainValidationError('Game ID is required');
    }
  }

}