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 { WalletsApiClient } from '../api/wallets/WalletsApiClient';
import { AuthApiClient } from '../api/auth/AuthApiClient';
import { AnalyticsApiClient } from '../api/analytics/AnalyticsApiClient';
import { MediaApiClient } from '../api/media/MediaApiClient';
import { DashboardApiClient } from '../api/dashboard/DashboardApiClient';
import { PolicyApiClient } from '../api/policy/PolicyApiClient';
import { ProtestsApiClient } from '../api/protests/ProtestsApiClient';
import { PenaltiesApiClient } from '../api/penalties/PenaltiesApiClient';
import { getWebsiteApiBaseUrl } from '../config/apiBaseUrl';
import { PenaltyService } from './penalties/PenaltyService';
import { ConsoleErrorReporter } from '../infrastructure/logging/ConsoleErrorReporter';
import { ConsoleLogger } from '../infrastructure/logging/ConsoleLogger';
import { LandingService } from './landing/LandingService';

// Services
import { RaceService } from './races/RaceService';
import { RaceResultsService } from './races/RaceResultsService';
import { RaceStewardingService } from './races/RaceStewardingService';
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 { LeagueSettingsService } from './leagues/LeagueSettingsService';
import { LeagueStewardingService } from './leagues/LeagueStewardingService';
import { LeagueWalletService } from './leagues/LeagueWalletService';
import { SponsorService } from './sponsors/SponsorService';
import { SponsorshipService } from './sponsors/SponsorshipService';
import { PaymentService } from './payments/PaymentService';
import { AnalyticsService } from './analytics/AnalyticsService';
import { DashboardService as AnalyticsDashboardService } from './analytics/DashboardService';
import { DashboardService } from './dashboard/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';
import { ProtestService } from './protests/ProtestService';
import { PolicyService } from './policy/PolicyService';
import { OnboardingService } from './onboarding/OnboardingService';

/**
 * ServiceFactory - Composition root for all services
 *
 * Centralizes service creation and dependency injection wiring.
 * Each factory method creates fresh instances with proper dependencies.
 * Services now directly instantiate View Models instead of using Presenters.
 */
export class ServiceFactory {
  private readonly errorReporter = new ConsoleErrorReporter();
  private readonly logger = new ConsoleLogger();

  private readonly apiClients: {
    races: RacesApiClient;
    drivers: DriversApiClient;
    teams: TeamsApiClient;
    leagues: LeaguesApiClient;
    sponsors: SponsorsApiClient;
    payments: PaymentsApiClient;
    wallets: WalletsApiClient;
    auth: AuthApiClient;
    analytics: AnalyticsApiClient;
    media: MediaApiClient;
    dashboard: DashboardApiClient;
    policy: PolicyApiClient;
    protests: ProtestsApiClient;
    penalties: PenaltiesApiClient;
  };

  constructor(baseUrl: string) {
    // Initialize API clients
    this.apiClients = {
      races: new RacesApiClient(baseUrl, this.errorReporter, this.logger),
      drivers: new DriversApiClient(baseUrl, this.errorReporter, this.logger),
      teams: new TeamsApiClient(baseUrl, this.errorReporter, this.logger),
      leagues: new LeaguesApiClient(baseUrl, this.errorReporter, this.logger),
      sponsors: new SponsorsApiClient(baseUrl, this.errorReporter, this.logger),
      payments: new PaymentsApiClient(baseUrl, this.errorReporter, this.logger),
      wallets: new WalletsApiClient(baseUrl, this.errorReporter, this.logger),
      auth: new AuthApiClient(baseUrl, this.errorReporter, this.logger),
      analytics: new AnalyticsApiClient(baseUrl, this.errorReporter, this.logger),
      media: new MediaApiClient(baseUrl, this.errorReporter, this.logger),
      dashboard: new DashboardApiClient(baseUrl, this.errorReporter, this.logger),
      policy: new PolicyApiClient(baseUrl, this.errorReporter, this.logger),
      protests: new ProtestsApiClient(baseUrl, this.errorReporter, this.logger),
      penalties: new PenaltiesApiClient(baseUrl, this.errorReporter, this.logger),
    };
  }

  /**
   * Legacy compatibility: older pages/components were written against a static ServiceFactory.
   * Prefer `useServices()` + react-query hooks.
   */
  private static defaultInstance: ServiceFactory | null = null;

  private static getDefaultInstance(): ServiceFactory {
    if (!this.defaultInstance) {
      this.defaultInstance = new ServiceFactory(getWebsiteApiBaseUrl());
    }
    return this.defaultInstance;
  }

  static getSponsorService(): SponsorService {
    return this.getDefaultInstance().createSponsorService();
  }

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

  /**
   * Create RaceResultsService instance
   */
  createRaceResultsService(): RaceResultsService {
    return new RaceResultsService(this.apiClients.races);
  }

  /**
   * Create RaceStewardingService instance
   */
  createRaceStewardingService(): RaceStewardingService {
    return new RaceStewardingService(
      this.apiClients.races,
      this.apiClients.protests,
      this.apiClients.penalties
    );
  }

  /**
   * Create DriverService instance
   */
  createDriverService(): DriverService {
    return new DriverService(this.apiClients.drivers);
  }

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

  /**
   * Create TeamService instance
   */
  createTeamService(): TeamService {
    return new TeamService(this.apiClients.teams);
  }

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

  /**
   * Create LeagueService instance
   */
  createLeagueService(): LeagueService {
    return new LeagueService(this.apiClients.leagues, this.apiClients.drivers, this.apiClients.sponsors, this.apiClients.races);
  }

  /**
    * Create LeagueMembershipService instance
    */
  createLeagueMembershipService(): LeagueMembershipService {
     return new LeagueMembershipService();
   }

   /**
    * Create LeagueSettingsService instance
    */
   createLeagueSettingsService(): LeagueSettingsService {
     return new LeagueSettingsService(this.apiClients.leagues, this.apiClients.drivers);
   }

   /**
    * Create LeagueStewardingService instance
    */
   createLeagueStewardingService(): LeagueStewardingService {
     return new LeagueStewardingService(
       this.createRaceService(),
       this.createProtestService(),
       this.createPenaltyService(),
       this.createDriverService(),
       this.createLeagueMembershipService()
     );
   }

   /**
    * Create LeagueWalletService instance
    */
   createLeagueWalletService(): LeagueWalletService {
     return new LeagueWalletService(this.apiClients.wallets);
   }

  /**
   * Create SponsorService instance
   */
  createSponsorService(): SponsorService {
    return new SponsorService(this.apiClients.sponsors);
  }

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

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

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

  /**
    * Create Analytics DashboardService instance
    */
   createAnalyticsDashboardService(): AnalyticsDashboardService {
     return new AnalyticsDashboardService(this.apiClients.analytics);
   }

   /**
    * Create PolicyService instance
    */
   createPolicyService(): PolicyService {
     return new PolicyService(this.apiClients.policy);
   }

   /**
     * Create DashboardService instance
     */
    createDashboardService(): DashboardService {
      return new DashboardService(this.apiClients.dashboard);
    }

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

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

  /**
   * 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);
  }

  /**
   * Create ProtestService instance
   */
  createProtestService(): ProtestService {
    return new ProtestService(this.apiClients.protests);
  }

  /**
   * Create PenaltyService instance
   */
  createPenaltyService(): PenaltyService {
    return new PenaltyService(this.apiClients.penalties);
  }

  /**
   * Create OnboardingService instance
   */
  createOnboardingService(): OnboardingService {
    return new OnboardingService(this.apiClients.media, this.apiClients.drivers);
  }

  /**
   * Create LandingService instance (used by server components)
   */
  createLandingService(): LandingService {
    return new LandingService(this.apiClients.races, this.apiClients.leagues, this.apiClients.teams, this.apiClients.auth);
  }
}
