import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode'; import type { GetRaceResultsDetailResult, GetRaceResultsDetailErrorCode, } from '@core/racing/application/use-cases/GetRaceResultsDetailUseCase'; import type { IImageServicePort } from '@core/racing/application/ports/IImageServicePort'; import type { RaceResultsDetailDTO } from '../dtos/RaceResultsDetailDTO'; import type { RaceResultDTO } from '../dtos/RaceResultDTO'; export type GetRaceResultsDetailResponseModel = RaceResultsDetailDTO; export type GetRaceResultsDetailApplicationError = ApplicationErrorCode< GetRaceResultsDetailErrorCode, { message: string } >; export class RaceResultsDetailPresenter { private result: GetRaceResultsDetailResult | null = null; constructor(private readonly imageService: IImageServicePort) {} present(result: GetRaceResultsDetailResult): void { this.result = result; } async getResponseModel(): Promise { if (!this.result) { return null; } const output = this.result; const driverMap = new Map(output.drivers.map(driver => [driver.id, driver])); const results: RaceResultDTO[] = await Promise.all( output.results.map(async singleResult => { const driver = driverMap.get(singleResult.driverId.toString()); if (!driver) { throw new Error(`Driver not found for result: ${singleResult.driverId}`); } const avatarUrl = this.imageService.getDriverAvatar(driver.id); return { driverId: singleResult.driverId.toString(), driverName: driver.name.toString(), avatarUrl, position: singleResult.position.toNumber(), startPosition: singleResult.startPosition.toNumber(), incidents: singleResult.incidents.toNumber(), fastestLap: singleResult.fastestLap.toNumber(), positionChange: singleResult.getPositionChange(), isPodium: singleResult.isPodium(), isClean: singleResult.isClean(), } as RaceResultDTO; }), ); return { raceId: output.race.id, track: output.race.track, results, } as RaceResultsDetailDTO; } get viewModel(): Promise { return this.getResponseModel().then(model => { if (!model) throw new Error('Presenter not presented'); return model; }); } }