import type { GetDriverProfileOutputDTO } from '@/lib/types/generated/GetDriverProfileOutputDTO'; import type { DriverProfileDriverSummaryDTO } from '@/lib/types/generated/DriverProfileDriverSummaryDTO'; import type { DriverProfileStatsDTO } from '@/lib/types/generated/DriverProfileStatsDTO'; import type { DriverProfileFinishDistributionDTO } from '@/lib/types/generated/DriverProfileFinishDistributionDTO'; import type { DriverProfileTeamMembershipDTO } from '@/lib/types/generated/DriverProfileTeamMembershipDTO'; import type { DriverProfileSocialSummaryDTO } from '@/lib/types/generated/DriverProfileSocialSummaryDTO'; import type { DriverProfileExtendedProfileDTO } from '@/lib/types/generated/DriverProfileExtendedProfileDTO'; import { DriverProfileViewModel } from '@/lib/view-models/DriverProfileViewModel'; import type { DriverProfileDriverSummaryViewModel, DriverProfileStatsViewModel, DriverProfileFinishDistributionViewModel, DriverProfileTeamMembershipViewModel, DriverProfileSocialSummaryViewModel, DriverProfileExtendedProfileViewModel, } from '@/lib/view-models/DriverProfileViewModel'; /** * DriverProfileViewModelBuilder * * Transforms GetDriverProfileOutputDTO into DriverProfileViewModel. * Deterministic, side-effect free, no HTTP calls. */ export class DriverProfileViewModelBuilder { /** * Build ViewModel from API DTO * * @param apiDto - The API transport DTO * @returns ViewModel ready for template */ static build(apiDto: GetDriverProfileOutputDTO): DriverProfileViewModel { return new DriverProfileViewModel({ currentDriver: apiDto.currentDriver ? this.transformCurrentDriver(apiDto.currentDriver) : null, stats: apiDto.stats ? this.transformStats(apiDto.stats) : null, finishDistribution: apiDto.finishDistribution ? this.transformFinishDistribution(apiDto.finishDistribution) : null, teamMemberships: apiDto.teamMemberships.map(m => this.transformTeamMembership(m)), socialSummary: this.transformSocialSummary(apiDto.socialSummary), extendedProfile: apiDto.extendedProfile ? this.transformExtendedProfile(apiDto.extendedProfile) : null, }); } private static transformCurrentDriver(dto: DriverProfileDriverSummaryDTO): DriverProfileDriverSummaryViewModel { return { id: dto.id, name: dto.name, country: dto.country, avatarUrl: dto.avatarUrl || '', // Handle undefined iracingId: dto.iracingId || null, joinedAt: dto.joinedAt, rating: dto.rating ?? null, globalRank: dto.globalRank ?? null, consistency: dto.consistency ?? null, bio: dto.bio || null, totalDrivers: dto.totalDrivers ?? null, }; } private static transformStats(dto: DriverProfileStatsDTO): DriverProfileStatsViewModel { return { totalRaces: dto.totalRaces, wins: dto.wins, podiums: dto.podiums, dnfs: dto.dnfs, avgFinish: dto.avgFinish ?? null, bestFinish: dto.bestFinish ?? null, worstFinish: dto.worstFinish ?? null, finishRate: dto.finishRate ?? null, winRate: dto.winRate ?? null, podiumRate: dto.podiumRate ?? null, percentile: dto.percentile ?? null, rating: dto.rating ?? null, consistency: dto.consistency ?? null, overallRank: dto.overallRank ?? null, }; } private static transformFinishDistribution(dto: DriverProfileFinishDistributionDTO): DriverProfileFinishDistributionViewModel { return { totalRaces: dto.totalRaces, wins: dto.wins, podiums: dto.podiums, topTen: dto.topTen, dnfs: dto.dnfs, other: dto.other, }; } private static transformTeamMembership(dto: DriverProfileTeamMembershipDTO): DriverProfileTeamMembershipViewModel { return { teamId: dto.teamId, teamName: dto.teamName, teamTag: dto.teamTag || null, role: dto.role, joinedAt: dto.joinedAt, isCurrent: dto.isCurrent, }; } private static transformSocialSummary(dto: DriverProfileSocialSummaryDTO): DriverProfileSocialSummaryViewModel { return { friendsCount: dto.friendsCount, friends: dto.friends.map(f => ({ id: f.id, name: f.name, country: f.country, avatarUrl: f.avatarUrl || '', // Handle undefined })), }; } private static transformExtendedProfile(dto: DriverProfileExtendedProfileDTO): DriverProfileExtendedProfileViewModel { return { socialHandles: dto.socialHandles.map(h => ({ platform: h.platform as any, // Type assertion - assuming valid platform handle: h.handle, url: h.url, })), achievements: dto.achievements.map(a => ({ id: a.id, title: a.title, description: a.description, icon: a.icon as any, // Type assertion - assuming valid icon rarity: a.rarity as any, // Type assertion - assuming valid rarity earnedAt: a.earnedAt, })), racingStyle: dto.racingStyle, favoriteTrack: dto.favoriteTrack, favoriteCar: dto.favoriteCar, timezone: dto.timezone, availableHours: dto.availableHours, lookingForTeam: dto.lookingForTeam, openToRequests: dto.openToRequests, }; } }