import { RacesApiClient } from '../api/races/RacesApiClient';
import { DriversApiClient } from '../api/drivers/DriversApiClient';
import { TeamsApiClient } from '../api/teams/TeamsApiClient';
import { LeaguesApiClient } from '../api/leagues/LeaguesApiClient';
import { SponsorsApiClient } from '../api/sponsors/SponsorsApiClient';
import { PaymentsApiClient } from '../api/payments/PaymentsApiClient';
import { AuthApiClient } from '../api/auth/AuthApiClient';
import { AnalyticsApiClient } from '../api/analytics/AnalyticsApiClient';
import { MediaApiClient } from '../api/media/MediaApiClient';

// Services
import { RaceService } from './races/RaceService';
import { RaceResultsService } from './races/RaceResultsService';
import { DriverService } from './drivers/DriverService';
import { DriverRegistrationService } from './drivers/DriverRegistrationService';
import { TeamService } from './teams/TeamService';
import { TeamJoinService } from './teams/TeamJoinService';
import { LeagueService } from './leagues/LeagueService';
import { LeagueMembershipService } from './leagues/LeagueMembershipService';
import { SponsorService } from './sponsors/SponsorService';
import { SponsorshipService } from './sponsors/SponsorshipService';
import { PaymentService } from './payments/PaymentService';
import { AnalyticsService } from './analytics/AnalyticsService';
import { DashboardService } from './analytics/DashboardService';
import { MediaService } from './media/MediaService';
import { AvatarService } from './media/AvatarService';
import { WalletService } from './payments/WalletService';
import { MembershipFeeService } from './payments/MembershipFeeService';
import { AuthService } from './auth/AuthService';
import { SessionService } from './auth/SessionService';

// Presenters
import { RaceDetailPresenter } from '../presenters/RaceDetailPresenter';
import { RaceResultsDetailPresenter } from '../presenters/RaceResultsDetailPresenter';
import { RaceWithSOFPresenter } from '../presenters/RaceWithSOFPresenter';
import { ImportRaceResultsPresenter } from '../presenters/ImportRaceResultsPresenter';
import { DriversLeaderboardPresenter } from '../presenters/DriversLeaderboardPresenter';
import { DriverPresenter } from '../presenters/DriverPresenter';
import { CompleteOnboardingPresenter } from '../presenters/CompleteOnboardingPresenter';
import { DriverRegistrationStatusPresenter } from '../presenters/DriverRegistrationStatusPresenter';
import { TeamDetailsPresenter } from '../presenters/TeamDetailsPresenter';
import { TeamListPresenter } from '../presenters/TeamListPresenter';
import { TeamMembersPresenter } from '../presenters/TeamMembersPresenter';
import { TeamJoinRequestPresenter } from '../presenters/TeamJoinRequestPresenter';
import { LeagueSummaryPresenter } from '../presenters/LeagueSummaryPresenter';
import { LeagueStandingsPresenter } from '../presenters/LeagueStandingsPresenter';
import { LeagueMembersPresenter } from '../presenters/LeagueMembersPresenter';
import { SponsorListPresenter } from '../presenters/SponsorListPresenter';
import { SponsorDashboardPresenter } from '../presenters/SponsorDashboardPresenter';
import { SponsorSponsorshipsPresenter } from '../presenters/SponsorSponsorshipsPresenter';
import { SponsorshipPricingPresenter } from '../presenters/SponsorshipPricingPresenter';
import { PaymentListPresenter } from '../presenters/PaymentListPresenter';
import { presentPayment } from '../presenters/PaymentPresenter';
import { presentMembershipFee } from '../presenters/MembershipFeePresenter';
import { presentPrize } from '../presenters/PrizePresenter';
import { presentWallet } from '../presenters/WalletPresenter';
import { AnalyticsDashboardPresenter } from '../presenters/AnalyticsDashboardPresenter';
import { AnalyticsMetricsPresenter } from '../presenters/AnalyticsMetricsPresenter';
import { MediaPresenter } from '../presenters/MediaPresenter';
import { AvatarPresenter } from '../presenters/AvatarPresenter';
import { SessionPresenter } from '../presenters/SessionPresenter';

/**
 * ServiceFactory - Composition root for all services
 *
 * Centralizes service creation and dependency injection wiring.
 * Each factory method creates fresh instances with proper dependencies.
 */
export class ServiceFactory {
  private readonly apiClients: {
    races: RacesApiClient;
    drivers: DriversApiClient;
    teams: TeamsApiClient;
    leagues: LeaguesApiClient;
    sponsors: SponsorsApiClient;
    payments: PaymentsApiClient;
    auth: AuthApiClient;
    analytics: AnalyticsApiClient;
    media: MediaApiClient;
  };

  private readonly presenters: {
    raceDetail: RaceDetailPresenter;
    raceResultsDetail: RaceResultsDetailPresenter;
    raceWithSOF: RaceWithSOFPresenter;
    importRaceResults: ImportRaceResultsPresenter;
    driversLeaderboard: DriversLeaderboardPresenter;
    driver: DriverPresenter;
    completeOnboarding: CompleteOnboardingPresenter;
    driverRegistrationStatus: DriverRegistrationStatusPresenter;
    teamDetails: TeamDetailsPresenter;
    teamList: TeamListPresenter;
    teamMembers: TeamMembersPresenter;
    teamJoinRequest: TeamJoinRequestPresenter;
    leagueSummary: LeagueSummaryPresenter;
    leagueStandings: LeagueStandingsPresenter;
    leagueMembers: LeagueMembersPresenter;
    sponsorList: SponsorListPresenter;
    sponsorDashboard: SponsorDashboardPresenter;
    sponsorSponsorships: SponsorSponsorshipsPresenter;
    sponsorshipPricing: SponsorshipPricingPresenter;
    paymentList: PaymentListPresenter;
    analyticsDashboard: AnalyticsDashboardPresenter;
    analyticsMetrics: AnalyticsMetricsPresenter;
    media: MediaPresenter;
    avatar: AvatarPresenter;
    session: SessionPresenter;
  };

  constructor(baseUrl: string) {
    // Initialize API clients
    this.apiClients = {
      races: new RacesApiClient(baseUrl),
      drivers: new DriversApiClient(baseUrl),
      teams: new TeamsApiClient(baseUrl),
      leagues: new LeaguesApiClient(baseUrl),
      sponsors: new SponsorsApiClient(baseUrl),
      payments: new PaymentsApiClient(baseUrl),
      auth: new AuthApiClient(baseUrl),
      analytics: new AnalyticsApiClient(baseUrl),
      media: new MediaApiClient(baseUrl),
    };

    // Initialize presenters
    this.presenters = {
      raceDetail: new RaceDetailPresenter(),
      raceResultsDetail: new RaceResultsDetailPresenter(),
      raceWithSOF: new RaceWithSOFPresenter(),
      importRaceResults: new ImportRaceResultsPresenter(),
      driversLeaderboard: new DriversLeaderboardPresenter(),
      driver: new DriverPresenter(),
      completeOnboarding: new CompleteOnboardingPresenter(),
      driverRegistrationStatus: new DriverRegistrationStatusPresenter(),
      teamDetails: new TeamDetailsPresenter(),
      teamList: new TeamListPresenter(),
      teamMembers: new TeamMembersPresenter(),
      teamJoinRequest: new TeamJoinRequestPresenter(),
      leagueSummary: new LeagueSummaryPresenter(),
      leagueStandings: new LeagueStandingsPresenter(),
      leagueMembers: new LeagueMembersPresenter(),
      sponsorList: new SponsorListPresenter(),
      sponsorDashboard: new SponsorDashboardPresenter(),
      sponsorSponsorships: new SponsorSponsorshipsPresenter(),
      sponsorshipPricing: new SponsorshipPricingPresenter(),
      paymentList: new PaymentListPresenter(),
      analyticsDashboard: new AnalyticsDashboardPresenter(),
      analyticsMetrics: new AnalyticsMetricsPresenter(),
      media: new MediaPresenter(),
      avatar: new AvatarPresenter(),
      session: new SessionPresenter(),
    };
  }

  /**
   * Create RaceService instance
   */
  createRaceService(): RaceService {
    return new RaceService(
      this.apiClients.races,
      this.presenters.raceDetail
    );
  }

  /**
   * Create RaceResultsService instance
   */
  createRaceResultsService(): RaceResultsService {
    return new RaceResultsService(
      this.apiClients.races,
      this.presenters.raceResultsDetail,
      this.presenters.raceWithSOF,
      this.presenters.importRaceResults
    );
  }

  /**
   * Create DriverService instance
   */
  createDriverService(): DriverService {
    return new DriverService(
      this.apiClients.drivers,
      this.presenters.driversLeaderboard,
      this.presenters.driver,
      this.presenters.completeOnboarding
    );
  }

  /**
   * Create DriverRegistrationService instance
   */
  createDriverRegistrationService(): DriverRegistrationService {
    return new DriverRegistrationService(
      this.apiClients.drivers,
      this.presenters.driverRegistrationStatus
    );
  }

  /**
   * Create TeamService instance
   */
  createTeamService(): TeamService {
    return new TeamService(
      this.apiClients.teams,
      this.presenters.teamList,
      this.presenters.teamDetails,
      this.presenters.teamMembers
    );
  }

  /**
   * Create TeamJoinService instance
   */
  createTeamJoinService(): TeamJoinService {
    return new TeamJoinService(
      this.apiClients.teams,
      this.presenters.teamJoinRequest
    );
  }

  /**
   * Create LeagueService instance
   */
  createLeagueService(): LeagueService {
    return new LeagueService(
      this.apiClients.leagues,
      this.presenters.leagueSummary,
      this.presenters.leagueStandings
    );
  }

  /**
   * Create LeagueMembershipService instance
   */
  createLeagueMembershipService(): LeagueMembershipService {
    return new LeagueMembershipService(
      this.apiClients.leagues,
      this.presenters.leagueMembers
    );
  }

  /**
   * Create SponsorService instance
   */
  createSponsorService(): SponsorService {
    return new SponsorService(
      this.apiClients.sponsors,
      this.presenters.sponsorList,
      this.presenters.sponsorDashboard,
      this.presenters.sponsorSponsorships
    );
  }

  /**
   * Create SponsorshipService instance
   */
  createSponsorshipService(): SponsorshipService {
    return new SponsorshipService(
      this.apiClients.sponsors,
      this.presenters.sponsorshipPricing,
      this.presenters.sponsorSponsorships
    );
  }

  /**
   * Create PaymentService instance
   */
  createPaymentService(): PaymentService {
    return new PaymentService(
      this.apiClients.payments,
      this.presenters.paymentList,
      presentPayment,
      presentMembershipFee,
      presentPrize,
      presentWallet
    );
  }

  /**
   * Create AnalyticsService instance
   */
  createAnalyticsService(): AnalyticsService {
    return new AnalyticsService(this.apiClients.analytics);
  }

  /**
   * Create DashboardService instance
   */
  createDashboardService(): DashboardService {
    return new DashboardService(
      this.apiClients.analytics,
      this.presenters.analyticsDashboard,
      this.presenters.analyticsMetrics
    );
  }

  /**
   * Create MediaService instance
   */
  createMediaService(): MediaService {
    return new MediaService(
      this.apiClients.media,
      this.presenters.media
    );
  }

  /**
   * Create AvatarService instance
   */
  createAvatarService(): AvatarService {
    return new AvatarService(
      this.apiClients.media,
      this.presenters.avatar
    );
  }

  /**
   * Create WalletService instance
   */
  createWalletService(): WalletService {
    return new WalletService(this.apiClients.payments);
  }

  /**
   * Create MembershipFeeService instance
   */
  createMembershipFeeService(): MembershipFeeService {
    return new MembershipFeeService(this.apiClients.payments);
  }

  /**
   * Create AuthService instance
   */
  createAuthService(): AuthService {
    return new AuthService(this.apiClients.auth);
  }

  /**
   * Create SessionService instance
   */
  createSessionService(): SessionService {
    return new SessionService(
      this.apiClients.auth,
      this.presenters.session
    );
  }
}