import { injectable, unmanaged } from 'inversify'; import { DriversApiClient } from '@/lib/api/drivers/DriversApiClient'; import type { CompleteOnboardingInputDTO } from '@/lib/types/generated/CompleteOnboardingInputDTO'; import type { GetDriverOutputDTO } from '@/lib/types/generated/GetDriverOutputDTO'; import type { CompleteOnboardingOutputDTO } from '@/lib/types/generated/CompleteOnboardingOutputDTO'; import type { DriverDTO } from '@/lib/types/generated/DriverDTO'; import type { GetDriverProfileOutputDTO } from '@/lib/types/generated/GetDriverProfileOutputDTO'; import { Result } from '@/lib/contracts/Result'; import { DomainError, Service } from '@/lib/contracts/services/Service'; import { getWebsiteApiBaseUrl } from '@/lib/config/apiBaseUrl'; import { ConsoleLogger } from '@/lib/infrastructure/logging/ConsoleLogger'; import { EnhancedErrorReporter } from '@/lib/infrastructure/EnhancedErrorReporter'; import { DriverLeaderboardViewModel } from '@/lib/view-models/DriverLeaderboardViewModel'; import { DriverViewModel } from '@/lib/view-models/DriverViewModel'; import { CompleteOnboardingViewModel } from '@/lib/view-models/CompleteOnboardingViewModel'; /** * Driver Service - DTO Only * * Returns raw API DTOs. No ViewModels or UX logic. * All client-side presentation logic must be handled by hooks/components. */ @injectable() export class DriverService implements Service { private readonly apiClient: DriversApiClient; constructor(@unmanaged() apiClient?: DriversApiClient) { if (apiClient) { this.apiClient = apiClient; } else { const baseUrl = getWebsiteApiBaseUrl(); const logger = new ConsoleLogger(); const errorReporter = new EnhancedErrorReporter(logger); this.apiClient = new DriversApiClient(baseUrl, errorReporter, logger); } } async getDriver(id: string): Promise { return this.apiClient.getDriver(id); } /** * Get driver leaderboard (returns DTO) */ async getDriverLeaderboard(): Promise { try { const res = await this.apiClient.getLeaderboard(); const data = (res as any).value || res; return new DriverLeaderboardViewModel(data); } catch (error: unknown) { throw error; } } /** * Complete driver onboarding (returns DTO) */ async completeDriverOnboarding(input: CompleteOnboardingInputDTO): Promise { try { const res = await this.apiClient.completeOnboarding(input); const data = (res as any).value || res; return new CompleteOnboardingViewModel(data); } catch (error: unknown) { throw error; } } /** * Get current driver (returns DTO) */ async getCurrentDriver(): Promise { try { const res = await this.apiClient.getCurrent(); if (!res) return null; const data = (res as any).value || res; if (!data) return null; return new DriverViewModel(data); } catch (error: unknown) { throw error; } } /** * Get driver profile (returns DTO) */ async getDriverProfile(driverId: string): Promise> { try { const data = await this.apiClient.getDriverProfile(driverId); return Result.ok(data); } catch (error: unknown) { return Result.err({ type: 'serverError', message: (error as Error).message || 'Failed to get driver profile' }); } } /** * Update current driver profile (returns DTO) */ async updateProfile(updates: { bio?: string; country?: string }): Promise> { try { const data = await this.apiClient.updateProfile(updates); return Result.ok(data); } catch (error: unknown) { return Result.err({ type: 'serverError', message: (error as Error).message || 'Failed to update profile' }); } } /** * Find driver by ID (returns DTO) */ async findById(id: string): Promise> { try { const data = await this.apiClient.getDriver(id); return Result.ok(data); } catch (error: unknown) { return Result.err({ type: 'serverError', message: (error as Error).message || 'Failed to find driver' }); } } /** * Find multiple drivers by IDs (returns DTOs) */ async findByIds(ids: string[]): Promise> { try { const drivers = await Promise.all(ids.map(id => this.apiClient.getDriver(id))); return Result.ok(drivers.filter((d): d is GetDriverOutputDTO => d !== null)); } catch (error: unknown) { return Result.err({ type: 'serverError', message: (error as Error).message || 'Failed to find drivers' }); } } }