import type { ITeamsLeaderboardPresenter, TeamsLeaderboardViewModel, TeamLeaderboardItemViewModel, SkillLevel, TeamsLeaderboardResultDTO, } from '@gridpilot/racing/application/presenters/ITeamsLeaderboardPresenter'; interface TeamLeaderboardInput { id: string; name: string; memberCount: number; rating: number | null; totalWins: number; totalRaces: number; performanceLevel: SkillLevel; isRecruiting: boolean; createdAt: Date; description?: string | null; specialization?: string | null; region?: string | null; languages?: string[]; } export class TeamsLeaderboardPresenter implements ITeamsLeaderboardPresenter { private viewModel: TeamsLeaderboardViewModel | null = null; reset(): void { this.viewModel = null; } present(input: TeamsLeaderboardResultDTO): void { const teams = (input.teams ?? []) as TeamLeaderboardInput[]; const recruitingCount = input.recruitingCount ?? 0; const transformedTeams = teams.map((team) => this.transformTeam(team)); const groupsBySkillLevel = transformedTeams.reduce>( (acc, team) => { if (!acc[team.performanceLevel]) { acc[team.performanceLevel] = []; } acc[team.performanceLevel]!.push(team); return acc; }, { beginner: [], intermediate: [], advanced: [], pro: [], }, ); const topTeams = transformedTeams .filter((t) => t.rating !== null) .slice() .sort((a, b) => (b.rating ?? 0) - (a.rating ?? 0)) .slice(0, 5); this.viewModel = { teams: transformedTeams, recruitingCount, groupsBySkillLevel, topTeams, }; } getViewModel(): TeamsLeaderboardViewModel | null { return this.viewModel; } private transformTeam(team: TeamLeaderboardInput): TeamLeaderboardItemViewModel { let specialization: TeamLeaderboardItemViewModel['specialization']; if ( team.specialization === 'endurance' || team.specialization === 'sprint' || team.specialization === 'mixed' ) { specialization = team.specialization; } else { specialization = undefined; } return { id: team.id, name: team.name, memberCount: team.memberCount, rating: team.rating, totalWins: team.totalWins, totalRaces: team.totalRaces, performanceLevel: team.performanceLevel, isRecruiting: team.isRecruiting, createdAt: team.createdAt, description: team.description ?? '', specialization: specialization ?? 'mixed', region: team.region ?? '', languages: team.languages ?? [], }; } }