import { ContainerModule } from 'inversify';
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 { 
  LOGGER_TOKEN,
  ERROR_REPORTER_TOKEN,
  CONFIG_TOKEN,
  LEAGUE_API_CLIENT_TOKEN,
  DRIVER_API_CLIENT_TOKEN,
  TEAM_API_CLIENT_TOKEN,
  RACE_API_CLIENT_TOKEN,
  SPONSOR_API_CLIENT_TOKEN,
  PAYMENT_API_CLIENT_TOKEN,
  WALLET_API_CLIENT_TOKEN,
  AUTH_API_CLIENT_TOKEN,
  ANALYTICS_API_CLIENT_TOKEN,
  MEDIA_API_CLIENT_TOKEN,
  DASHBOARD_API_CLIENT_TOKEN,
  POLICY_API_CLIENT_TOKEN,
  PROTEST_API_CLIENT_TOKEN,
  PENALTY_API_CLIENT_TOKEN
} from '../tokens';

export const ApiModule = new ContainerModule((options) => {
  const bind = options.bind;

  // Factory for creating API clients with shared dependencies
  const createApiClient = (
    ClientClass: any,
    context: any
  ) => {
    const getConfig = context.get(CONFIG_TOKEN);
    const baseUrl = getConfig(); // Call function to get fresh config
    const errorReporter = context.get(ERROR_REPORTER_TOKEN);
    const logger = context.get(LOGGER_TOKEN);
    
    return new ClientClass(baseUrl, errorReporter, logger);
  };

  // Register all API clients
  bind<LeaguesApiClient>(LEAGUE_API_CLIENT_TOKEN)
    .toDynamicValue(ctx => createApiClient(LeaguesApiClient, ctx))
    .inSingletonScope();

  bind<DriversApiClient>(DRIVER_API_CLIENT_TOKEN)
    .toDynamicValue(ctx => createApiClient(DriversApiClient, ctx))
    .inSingletonScope();

  bind<TeamsApiClient>(TEAM_API_CLIENT_TOKEN)
    .toDynamicValue(ctx => createApiClient(TeamsApiClient, ctx))
    .inSingletonScope();

  bind<RacesApiClient>(RACE_API_CLIENT_TOKEN)
    .toDynamicValue(ctx => createApiClient(RacesApiClient, ctx))
    .inSingletonScope();

  bind<SponsorsApiClient>(SPONSOR_API_CLIENT_TOKEN)
    .toDynamicValue(ctx => createApiClient(SponsorsApiClient, ctx))
    .inSingletonScope();

  bind<PaymentsApiClient>(PAYMENT_API_CLIENT_TOKEN)
    .toDynamicValue(ctx => createApiClient(PaymentsApiClient, ctx))
    .inSingletonScope();

  bind<WalletsApiClient>(WALLET_API_CLIENT_TOKEN)
    .toDynamicValue(ctx => createApiClient(WalletsApiClient, ctx))
    .inSingletonScope();

  bind<AuthApiClient>(AUTH_API_CLIENT_TOKEN)
    .toDynamicValue(ctx => createApiClient(AuthApiClient, ctx))
    .inSingletonScope();

  bind<AnalyticsApiClient>(ANALYTICS_API_CLIENT_TOKEN)
    .toDynamicValue(ctx => createApiClient(AnalyticsApiClient, ctx))
    .inSingletonScope();

  bind<MediaApiClient>(MEDIA_API_CLIENT_TOKEN)
    .toDynamicValue(ctx => createApiClient(MediaApiClient, ctx))
    .inSingletonScope();

  bind<DashboardApiClient>(DASHBOARD_API_CLIENT_TOKEN)
    .toDynamicValue(ctx => createApiClient(DashboardApiClient, ctx))
    .inSingletonScope();

  bind<PolicyApiClient>(POLICY_API_CLIENT_TOKEN)
    .toDynamicValue(ctx => createApiClient(PolicyApiClient, ctx))
    .inSingletonScope();

  bind<ProtestsApiClient>(PROTEST_API_CLIENT_TOKEN)
    .toDynamicValue(ctx => createApiClient(ProtestsApiClient, ctx))
    .inSingletonScope();

  bind<PenaltiesApiClient>(PENALTY_API_CLIENT_TOKEN)
    .toDynamicValue(ctx => createApiClient(PenaltiesApiClient, ctx))
    .inSingletonScope();
});