/**
 * Domain Entity: LeagueMembership
 *
 * Represents a driver's membership in a league.
 */

import type { IEntity } from '@core/shared/domain';
import { RacingDomainValidationError } from '../errors/RacingDomainError';
import { LeagueId } from './LeagueId';
import { MembershipRole, MembershipRoleValue } from './MembershipRole';
import { MembershipStatus, MembershipStatusValue } from './MembershipStatus';
import { JoinedAt } from '../value-objects/JoinedAt';
import { DriverId } from './DriverId';

export interface LeagueMembershipProps {
  id?: string;
  leagueId: string;
  driverId: string;
  role: string;
  status?: string;
  joinedAt?: Date;
}

export class LeagueMembership implements IEntity<string> {
  readonly id: string;
  readonly leagueId: LeagueId;
  readonly driverId: DriverId;
  readonly role: MembershipRole;
  readonly status: MembershipStatus;
  readonly joinedAt: JoinedAt;

  private constructor(props: {
    id: string;
    leagueId: LeagueId;
    driverId: DriverId;
    role: MembershipRole;
    status: MembershipStatus;
    joinedAt: JoinedAt;
  }) {
    this.id = props.id;
    this.leagueId = props.leagueId;
    this.driverId = props.driverId;
    this.role = props.role;
    this.status = props.status;
    this.joinedAt = props.joinedAt;
  }

  static create(props: LeagueMembershipProps): LeagueMembership {
    this.validate(props);

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

    const leagueId = LeagueId.create(props.leagueId);
    const driverId = DriverId.create(props.driverId);
    const role = MembershipRole.create(props.role as MembershipRoleValue);
    const status = MembershipStatus.create((props.status ?? 'pending') as MembershipStatusValue);
    const joinedAt = JoinedAt.create(props.joinedAt ?? new Date());

    return new LeagueMembership({
      id,
      leagueId,
      driverId,
      role,
      status,
      joinedAt,
    });
  }

  private static validate(props: LeagueMembershipProps): 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');
    }

    if (!props.role) {
      throw new RacingDomainValidationError('Membership role is required');
    }
  }
}