/**
 * Domain Entity: JoinRequest
 *
 * Represents a request to join a league.
 */

import type { IEntity } from '@core/shared/domain';
import { RacingDomainValidationError } from '../errors/RacingDomainError';
import { LeagueId } from './LeagueId';
import { LeagueOwnerId } from './LeagueOwnerId';
import { JoinedAt } from '../value-objects/JoinedAt';

export interface JoinRequestProps {
  id?: string;
  leagueId: string;
  driverId: string;
  requestedAt?: Date;
  message?: string;
}

export class JoinRequest implements IEntity<string> {
  readonly id: string;
  readonly leagueId: LeagueId;
  readonly driverId: LeagueOwnerId;
  readonly requestedAt: JoinedAt;
  readonly message: string | undefined;

  private constructor(props: { id: string; leagueId: string; driverId: string; requestedAt: Date; message?: string }) {
    this.id = props.id;
    this.leagueId = LeagueId.create(props.leagueId);
    this.driverId = LeagueOwnerId.create(props.driverId);
    this.requestedAt = JoinedAt.create(props.requestedAt);
    this.message = props.message;
  }

  static create(props: JoinRequestProps): JoinRequest {
    this.validate(props);

    const id = props.id && props.id.trim().length > 0 ? props.id : `${props.leagueId}:${props.driverId}`;
    const requestedAt = props.requestedAt ?? new Date();

    return new JoinRequest({
      id,
      leagueId: props.leagueId,
      driverId: props.driverId,
      requestedAt,
      message: props.message,
    });
  }

  private static validate(props: JoinRequestProps): void {
    if (!props.leagueId || props.leagueId.trim().length === 0) {
      throw new RacingDomainValidationError('League ID is required');
    }

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