import { LeaguesApiClient } from '@/lib/api/leagues/LeaguesApiClient'; import { ConsoleLogger } from '@/lib/infrastructure/logging/ConsoleLogger'; import { ConsoleErrorReporter } from '@/lib/infrastructure/logging/ConsoleErrorReporter'; import { getWebsiteApiBaseUrl } from '@/lib/config/apiBaseUrl'; import { Result } from '@/lib/contracts/Result'; import { Service, type DomainError } from '@/lib/contracts/services/Service'; export interface ProfileLeaguesPageDto { ownedLeagues: Array<{ leagueId: string; name: string; description: string; membershipRole: 'owner' | 'admin' | 'steward' | 'member'; }>; memberLeagues: Array<{ leagueId: string; name: string; description: string; membershipRole: 'owner' | 'admin' | 'steward' | 'member'; }>; } interface MembershipDTO { driverId: string; role: string; status?: 'active' | 'inactive'; } export class ProfileLeaguesService implements Service { async getProfileLeagues(driverId: string): Promise> { try { const baseUrl = getWebsiteApiBaseUrl(); const logger = new ConsoleLogger(); const errorReporter = new ConsoleErrorReporter(); const leaguesApiClient = new LeaguesApiClient(baseUrl, errorReporter, logger); const leaguesDto = await leaguesApiClient.getAllWithCapacity(); if (!leaguesDto?.leagues) { return Result.err({ type: 'notFound', message: 'Leagues not found' }); } // Fetch all memberships in parallel const leagueMemberships = await Promise.all( leaguesDto.leagues.map(async (league) => { try { const membershipsDto = await leaguesApiClient.getMemberships(league.id); let memberships: MembershipDTO[] = []; if (membershipsDto && typeof membershipsDto === 'object') { if ('members' in membershipsDto && Array.isArray((membershipsDto as { members?: unknown }).members)) { memberships = (membershipsDto as { members: MembershipDTO[] }).members; } else if ('memberships' in membershipsDto && Array.isArray((membershipsDto as { memberships?: unknown }).memberships)) { memberships = (membershipsDto as { memberships: MembershipDTO[] }).memberships; } } const currentMembership = memberships.find((m) => m.driverId === driverId); if (currentMembership && currentMembership.status === 'active') { return { leagueId: league.id, name: league.name, description: league.description, membershipRole: currentMembership.role as 'owner' | 'admin' | 'steward' | 'member', }; } return null; } catch { return null; } }) ); // Filter and categorize const validLeagues = leagueMemberships.filter((l): l is NonNullable => l !== null); const ownedLeagues = validLeagues.filter((l) => l.membershipRole === 'owner'); const memberLeagues = validLeagues.filter((l) => l.membershipRole !== 'owner'); return Result.ok({ ownedLeagues, memberLeagues, }); } catch (error: any) { const errorAny = error as { statusCode?: number; message?: string }; if (errorAny.statusCode === 404 || errorAny.message?.toLowerCase().includes('not found')) { return Result.err({ type: 'notFound', message: 'Profile leagues not found' }); } if (errorAny.statusCode === 302 || errorAny.message?.toLowerCase().includes('redirect')) { return Result.err({ type: 'unauthorized', message: 'Unauthorized access' }); } return Result.err({ type: 'unknown', message: error.message || 'Failed to fetch profile leagues' }); } } }