import { getWebsiteApiBaseUrl } from '@/lib/config/apiBaseUrl'; import { isProductionEnvironment } from '@/lib/config/env'; import { Result } from '@/lib/contracts/Result'; import { Service, type DomainError } from '@/lib/contracts/services/Service'; import { LeaguesApiClient } from '@/lib/gateways/api/leagues/LeaguesApiClient'; import { EnhancedErrorReporter } from '@/lib/infrastructure/EnhancedErrorReporter'; import { ConsoleLogger } from '@/lib/infrastructure/logging/ConsoleLogger'; import type { LeagueRosterJoinRequestDTO } from '@/lib/types/generated/LeagueRosterJoinRequestDTO'; import type { LeagueRosterMemberDTO } from '@/lib/types/generated/LeagueRosterMemberDTO'; import { LeagueMemberViewModel } from '@/lib/view-models/LeagueMemberViewModel'; import { injectable, unmanaged } from 'inversify'; export interface LeagueRosterAdminData { leagueId: string; members: LeagueRosterMemberDTO[]; joinRequests: LeagueRosterJoinRequestDTO[]; } @injectable() export class LeagueMembershipService implements Service { private apiClient: LeaguesApiClient; // eslint-disable-next-line @typescript-eslint/no-explicit-any private static cachedMemberships = new Map(); constructor(@unmanaged() apiClient?: LeaguesApiClient) { if (apiClient) { this.apiClient = apiClient; } else { const baseUrl = getWebsiteApiBaseUrl(); const logger = new ConsoleLogger(); const errorReporter = new EnhancedErrorReporter(logger, { showUserNotifications: false, logToConsole: true, reportToExternal: isProductionEnvironment(), }); this.apiClient = new LeaguesApiClient(baseUrl, errorReporter, logger); } } async getLeagueMemberships(leagueId: string, currentUserId: string): Promise { const res = await this.apiClient.getMemberships(leagueId); const members = (res as any).members || res; return members.map((m: any) => new LeagueMemberViewModel({ ...m, currentUserId })); } async removeMember(leagueId: string, performerDriverId: string, targetDriverId: string): Promise { const res = await this.apiClient.removeMember(leagueId, performerDriverId, targetDriverId); return (res as any).value || res; } async removeRosterMember(leagueId: string, targetDriverId: string): Promise> { try { const res = await this.apiClient.removeRosterMember(leagueId, targetDriverId); const dto = (res as any).value || res; return Result.ok({ success: dto.success }); } catch (error: unknown) { return Result.err({ type: 'serverError', message: (error as Error).message || 'Failed to remove member' }); } } // eslint-disable-next-line @typescript-eslint/no-explicit-any static getMembership(leagueId: string, driverId: string): any | null { const members = this.cachedMemberships.get(leagueId); if (!members) return null; return members.find(m => m.driverId === driverId) || null; } // eslint-disable-next-line @typescript-eslint/no-explicit-any static getLeagueMembers(leagueId: string): any[] { return this.cachedMemberships.get(leagueId) || []; } // eslint-disable-next-line @typescript-eslint/no-explicit-any static getAllMembershipsForDriver(driverId: string): any[] { const allMemberships: any[] = []; for (const [leagueId, members] of this.cachedMemberships.entries()) { const membership = members.find(m => m.driverId === driverId); if (membership) { allMemberships.push({ ...membership, leagueId }); } } return allMemberships; } async fetchLeagueMemberships(leagueId: string): Promise { try { const members = await this.apiClient.getMemberships(leagueId); // eslint-disable-next-line @typescript-eslint/no-explicit-any LeagueMembershipService.cachedMemberships.set(leagueId, (members as any).members || []); } catch (error) { console.error('Failed to fetch memberships', error); } } // eslint-disable-next-line @typescript-eslint/no-explicit-any getMembership(leagueId: string, driverId: string): any | null { return LeagueMembershipService.getMembership(leagueId, driverId); } // eslint-disable-next-line @typescript-eslint/no-explicit-any getLeagueMembers(leagueId: string): any[] { return LeagueMembershipService.getLeagueMembers(leagueId); } async joinLeague(_: string, __: string): Promise> { return Result.err({ type: 'notImplemented', message: 'joinLeague' }); } async leaveLeague(_: string, __: string): Promise> { return Result.err({ type: 'notImplemented', message: 'leaveLeague' }); } async getRosterAdminData(leagueId: string): Promise> { try { const [members, joinRequests] = await Promise.all([ this.apiClient.getAdminRosterMembers(leagueId), this.apiClient.getAdminRosterJoinRequests(leagueId), ]); return Result.ok({ leagueId, members, joinRequests, }); } catch (error: unknown) { console.error('LeagueMembershipService.getRosterAdminData failed:', error); return Result.err({ type: 'serverError', message: (error as Error).message || 'Failed to fetch roster data' }); } } async approveJoinRequest(leagueId: string, joinRequestId: string): Promise> { try { const res = await this.apiClient.approveRosterJoinRequest(leagueId, joinRequestId); const dto = (res as any).value || res; return Result.ok({ success: dto.success }); } catch (error: unknown) { return Result.err({ type: 'serverError', message: (error as Error).message || 'Failed to approve join request' }); } } async rejectJoinRequest(leagueId: string, joinRequestId: string): Promise> { try { const res = await this.apiClient.rejectRosterJoinRequest(leagueId, joinRequestId); const dto = (res as any).value || res; return Result.ok({ success: dto.success }); } catch (error: unknown) { return Result.err({ type: 'serverError', message: (error as Error).message || 'Failed to reject join request' }); } } }