import { ViewModel } from "../contracts/view-models/ViewModel"; import { DurationFormatter } from '../formatters/DurationFormatter'; import { FinishFormatter } from '../formatters/FinishFormatter'; import type { RaceResultViewData } from "../view-data/RaceResultViewData"; export class RaceResultViewModel extends ViewModel { private readonly data: RaceResultViewData; constructor(data: RaceResultViewData) { super(); this.data = data; } get driverId(): string { return this.data.driverId; } get driverName(): string { return this.data.driverName; } get avatarUrl(): string { return this.data.avatarUrl; } get position(): number { return this.data.position; } get startPosition(): number { return this.data.startPosition; } get incidents(): number { return this.data.incidents; } get fastestLap(): number { return this.data.fastestLap; } get positionChange(): number { return this.data.positionChange; } get isPodium(): boolean { return this.data.isPodium; } get isClean(): boolean { return this.data.isClean; } get id(): string { return this.data.id; } get raceId(): string { return this.data.raceId; } /** UI-specific: Display for position change */ get positionChangeDisplay(): string { if (this.positionChange > 0) return `+${this.positionChange}`; if (this.positionChange < 0) return `${this.positionChange}`; return '0'; } /** UI-specific: Color for position change */ get positionChangeColor(): string { if (this.positionChange > 0) return 'green'; if (this.positionChange < 0) return 'red'; return 'gray'; } /** UI-specific: Whether this is the winner */ get isWinner(): boolean { return this.position === 1; } /** UI-specific: Whether has fastest lap */ get hasFastestLap(): boolean { return this.fastestLap > 0; } /** UI-specific: Badge for position */ get positionBadge(): string { return FinishFormatter.format(this.position); } /** UI-specific: Color for incidents badge */ get incidentsBadgeColor(): string { if (this.incidents === 0) return 'green'; if (this.incidents <= 2) return 'yellow'; return 'red'; } /** UI-specific: Formatted lap time */ get lapTimeFormatted(): string { if (this.fastestLap <= 0) return '--:--.---'; return DurationFormatter.formatSeconds(this.fastestLap); } /** Required by ResultsTable */ getPositionChange(): number { return this.positionChange; } get formattedPosition(): string { return FinishFormatter.format(this.position); } get formattedStartPosition(): string { return FinishFormatter.format(this.startPosition); } get formattedIncidents(): string { return `${this.incidents}x incidents`; } get formattedPositionsGained(): string | undefined { if (this.position < this.startPosition) { return `+${this.startPosition - this.position} positions`; } return undefined; } }