import { ViewModel } from "../contracts/view-models/ViewModel"; import type { RaceResultsDetailViewData } from "../view-data/RaceResultsDetailViewData"; import { RaceResultViewModel } from './RaceResultViewModel'; export class RaceResultsDetailViewModel extends ViewModel { private readonly data: RaceResultsDetailViewData; readonly results: RaceResultViewModel[]; constructor(data: RaceResultsDetailViewData) { super(); this.data = data; this.results = data.results.map(r => new RaceResultViewModel(r)); } get raceId(): string { return this.data.raceId; } get track(): string { return this.data.track; } get currentUserId(): string { return this.data.currentUserId; } get league() { return this.data.league; } get race() { return this.data.race; } get drivers() { return this.data.drivers; } get pointsSystem() { return this.data.pointsSystem; } get fastestLapTime(): number { return this.data.fastestLapTime; } get penalties() { return this.data.penalties; } get currentDriverId(): string { return this.data.currentDriverId; } /** UI-specific: Results sorted by position */ get resultsByPosition(): RaceResultViewModel[] { return [...this.results].sort((a, b) => a.position - b.position); } /** UI-specific: Results sorted by fastest lap */ get resultsByFastestLap(): RaceResultViewModel[] { return [...this.results].sort((a, b) => a.fastestLap - b.fastestLap); } /** UI-specific: Clean drivers only */ get cleanDrivers(): RaceResultViewModel[] { return this.results.filter(r => r.isClean); } /** UI-specific: Current user's result */ get currentUserResult(): RaceResultViewModel | undefined { return this.results.find(r => r.driverId === this.currentUserId); } /** UI-specific: Race stats */ get stats(): { totalDrivers: number; cleanRate: number; averageIncidents: number } { const total = this.results.length; const clean = this.cleanDrivers.length; const totalIncidents = this.results.reduce((sum, r) => sum + r.incidents, 0); return { totalDrivers: total, cleanRate: total > 0 ? (clean / total) * 100 : 0, averageIncidents: total > 0 ? totalIncidents / total : 0 }; } }