import { Result } from '@/lib/contracts/Result';
import { Service, type DomainError } from '@/lib/contracts/services/Service';
import { type LeagueStandingsApiDto, type LeagueMembershipsApiDto } from '@/lib/types/tbd/LeagueStandingsApiDto';
import { LeaguesApiClient } from '@/lib/api/leagues/LeaguesApiClient';
import { ConsoleErrorReporter } from '@/lib/infrastructure/logging/ConsoleErrorReporter';
import { ConsoleLogger } from '@/lib/infrastructure/logging/ConsoleLogger';
import { getWebsiteApiBaseUrl } from '@/lib/config/apiBaseUrl';

export class LeagueStandingsService implements Service {
  private apiClient: LeaguesApiClient;

  constructor() {
    const baseUrl = getWebsiteApiBaseUrl();
    this.apiClient = new LeaguesApiClient(
      baseUrl,
      new ConsoleErrorReporter(),
      new ConsoleLogger()
    );
  }

  async getStandingsData(leagueId: string): Promise<Result<{ standings: LeagueStandingsApiDto; memberships: LeagueMembershipsApiDto }, DomainError>> {
    try {
      const [standingsData, membershipsData] = await Promise.all([
        this.apiClient.getStandings(leagueId),
        this.apiClient.getMemberships(leagueId),
      ]);

      // Map LeagueStandingsDTO to LeagueStandingsApiDto
      const standings: LeagueStandingsApiDto = {
        standings: standingsData.standings.map(s => ({
          driverId: s.driverId,
          driver: {
            id: s.driver.id,
            name: s.driver.name,
            iracingId: s.driver.iracingId,
            country: s.driver.country,
            joinedAt: s.driver.joinedAt,
          },
          points: s.points,
          position: s.position,
          wins: s.wins,
          podiums: s.podiums,
          races: s.races,
          positionChange: s.positionChange,
          lastRacePoints: s.lastRacePoints,
          droppedRaceIds: s.droppedRaceIds,
        })),
      };

      // Map LeagueMembershipsDTO to LeagueMembershipsApiDto
      const memberships: LeagueMembershipsApiDto = {
        members: (membershipsData.members || []).map(m => ({
          driverId: m.driverId,
          driver: {
            id: m.driver.id,
            name: m.driver.name,
            iracingId: m.driver.iracingId,
            country: m.driver.country,
            joinedAt: m.driver.joinedAt,
          },
          role: m.role as any,
          joinedAt: m.joinedAt,
        })),
      };

      return Result.ok({ standings, memberships });
    } catch (error: unknown) {
      return Result.err({ type: 'serverError', message: (error as Error).message || 'Failed to fetch standings' });
    }
  }
}
