import type { Logger } from '@core/shared/domain/Logger';
import { Result } from '@core/shared/domain/Result';
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
import { LeagueMembership } from '../../domain/entities/LeagueMembership';
import { LeagueMembershipRepository } from '../../domain/repositories/LeagueMembershipRepository';

export type JoinLeagueErrorCode = 'ALREADY_MEMBER' | 'REPOSITORY_ERROR';

export interface JoinLeagueInput {
  leagueId: string;
  driverId: string;
}

export interface JoinLeagueResult {
  membership: LeagueMembership;
}

export class JoinLeagueUseCase {
  constructor(
    private readonly membershipRepository: LeagueMembershipRepository,
    private readonly logger: Logger,
  ) {}

  async execute(command: JoinLeagueInput): Promise<Result<JoinLeagueResult, ApplicationErrorCode<JoinLeagueErrorCode, { message: string }>>> {
    this.logger.debug('Attempting to join league', { command });
    const { leagueId, driverId } = command;

    try {
      const existing = await this.membershipRepository.getMembership(leagueId, driverId);
      if (existing) {
        this.logger.warn('Driver already a member or has pending request', { leagueId, driverId });
        return Result.err({
          code: 'ALREADY_MEMBER',
          details: { message: 'Driver is already a member of this league or has a pending membership.' },
        });
      }

      const membership = LeagueMembership.create({
        leagueId,
        driverId,
        role: 'member',
        status: 'active',
      });

      const savedMembership = await this.membershipRepository.saveMembership(membership);
      this.logger.info('Successfully joined league', { membershipId: savedMembership.id });

      return Result.ok({
        membership: savedMembership,
      });
    } catch (error) {
      const err = error instanceof Error ? error : new Error('Unknown error');
      this.logger.error('Failed to join league due to an unexpected error', err);
      return Result.err({
        code: 'REPOSITORY_ERROR',
        details: { message: err.message ?? 'Failed to join league' },
      });
    }
  }
}
