import { getWebsiteApiBaseUrl } from '@/lib/config/apiBaseUrl'; import { Result } from '@/lib/contracts/Result'; import { Service, type DomainError } from '@/lib/contracts/services/Service'; import { LeaguesApiClient } from '@/lib/gateways/api/leagues/LeaguesApiClient'; import { ConsoleErrorReporter } from '@/lib/infrastructure/logging/ConsoleErrorReporter'; import { ConsoleLogger } from '@/lib/infrastructure/logging/ConsoleLogger'; import { AllLeaguesWithCapacityDTO } from '@/lib/types/generated/AllLeaguesWithCapacityDTO'; import { LeagueMembershipsDTO } from '@/lib/types/generated/LeagueMembershipsDTO'; 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'; }>; } 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: AllLeaguesWithCapacityDTO = 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: LeagueMembershipsDTO = await leaguesApiClient.getMemberships(league.id); const memberships = membershipsDto.members || []; const currentMembership = memberships.find((m) => m.driverId === driverId); // Note: LeagueMemberDTO doesn't have status, assuming if they are in the list they are active if (currentMembership) { 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' }); } } }