import type { ILeagueMembershipRepository } from '../../domain/repositories/ILeagueMembershipRepository'; import type { IRaceRepository } from '../../domain/repositories/IRaceRepository'; import { Result } from '@core/shared/application/Result'; import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode'; import type { UseCaseOutputPort } from '@core/shared/application/UseCaseOutputPort'; export interface GetLeagueStatsInput { leagueId: string; } export interface GetLeagueStatsResult { leagueId: string; driverCount: number; raceCount: number; averageRating: number; } export type GetLeagueStatsErrorCode = 'LEAGUE_NOT_FOUND' | 'REPOSITORY_ERROR'; export class GetLeagueStatsUseCase { constructor( private readonly leagueMembershipRepository: ILeagueMembershipRepository, private readonly raceRepository: IRaceRepository, private readonly getDriverRating: (input: { driverId: string; }) => Promise<{ rating: number | null; ratingChange: number | null }>, private readonly output: UseCaseOutputPort, ) {} async execute( input: GetLeagueStatsInput, ): Promise>> { try { const memberships = await this.leagueMembershipRepository.getLeagueMembers(input.leagueId); if (memberships.length === 0) { return Result.err({ code: 'LEAGUE_NOT_FOUND', details: { message: 'League not found' }, }); } const races = await this.raceRepository.findByLeagueId(input.leagueId); const driverIds = memberships.map(membership => String(membership.driverId)); const ratingPromises = driverIds.map(driverId => this.getDriverRating({ driverId })); const ratingResults = await Promise.all(ratingPromises); const validRatings = ratingResults .map(result => result.rating) .filter((rating): rating is number => rating !== null); const averageRating = validRatings.length > 0 ? Math.round(validRatings.reduce((sum, rating) => sum + rating, 0) / validRatings.length) : 0; const result: GetLeagueStatsResult = { leagueId: input.leagueId, driverCount: memberships.length, raceCount: races.length, averageRating, }; this.output.present(result); return Result.ok(undefined); } catch (error) { const message = error instanceof Error && error.message ? error.message : 'Failed to fetch league stats'; return Result.err({ code: 'REPOSITORY_ERROR', details: { message }, }); } } }