import type { Logger } from '@core/shared/application';
import type { IDriverRepository } from '@core/racing/domain/repositories/IDriverRepository';
import type { ILeagueRepository } from '@core/racing/domain/repositories/ILeagueRepository';
import type { IRaceRepository } from '@core/racing/domain/repositories/IRaceRepository';
import type { IResultRepository } from '@core/racing/domain/repositories/IResultRepository';
import type { IStandingRepository } from '@core/racing/domain/repositories/IStandingRepository';
import type { ILeagueMembershipRepository } from '@core/racing/domain/repositories/ILeagueMembershipRepository';
import type { IRaceRegistrationRepository } from '@core/racing/domain/repositories/IRaceRegistrationRepository';
import type { ITeamRepository } from '@core/racing/domain/repositories/ITeamRepository';
import type { ITeamMembershipRepository } from '@core/racing/domain/repositories/ITeamMembershipRepository';
import type { ISponsorRepository } from '@core/racing/domain/repositories/ISponsorRepository';
import type { ISeasonRepository } from '@core/racing/domain/repositories/ISeasonRepository';
import type { ILeagueScoringConfigRepository } from '@core/racing/domain/repositories/ILeagueScoringConfigRepository';
import type { ISeasonSponsorshipRepository } from '@core/racing/domain/repositories/ISeasonSponsorshipRepository';
import type { ISponsorshipRequestRepository } from '@core/racing/domain/repositories/ISponsorshipRequestRepository';
import type { ILeagueWalletRepository } from '@core/racing/domain/repositories/ILeagueWalletRepository';
import type { ITransactionRepository } from '@core/racing/domain/repositories/ITransactionRepository';
import type { Season } from '@core/racing/domain/entities/season/Season';
import { getLeagueScoringPresetById } from './LeagueScoringPresets';
import type { IProtestRepository } from '@core/racing/domain/repositories/IProtestRepository';
import type { IPenaltyRepository } from '@core/racing/domain/repositories/IPenaltyRepository';
import type { IFeedRepository } from '@core/social/domain/repositories/IFeedRepository';
import type { ISocialGraphRepository } from '@core/social/domain/repositories/ISocialGraphRepository';
import type { IDriverStatsRepository } from '@core/racing/domain/repositories/IDriverStatsRepository';
import type { ITeamStatsRepository, TeamStats } from '@core/racing/domain/repositories/ITeamStatsRepository';
import type { IMediaRepository } from '@core/racing/domain/repositories/IMediaRepository';
import { createRacingSeed } from './racing/RacingSeed';
import { seedId } from './racing/SeedIdHelper';
import { Driver } from '@core/racing/domain/entities/Driver';
import { Result } from '@core/racing/domain/entities/result/Result';
import { Standing } from '@core/racing/domain/entities/Standing';
import { Team } from '@core/racing/domain/entities/Team';
import type { DriverStats } from '@core/racing/application/use-cases/IDriverStatsUseCase';

export type RacingSeedDependencies = {
  driverRepository: IDriverRepository;
  leagueRepository: ILeagueRepository;
  seasonRepository: ISeasonRepository;
  leagueScoringConfigRepository: ILeagueScoringConfigRepository;
  seasonSponsorshipRepository: ISeasonSponsorshipRepository;
  sponsorshipRequestRepository: ISponsorshipRequestRepository;
  leagueWalletRepository: ILeagueWalletRepository;
  transactionRepository: ITransactionRepository;
  protestRepository: IProtestRepository;
  penaltyRepository: IPenaltyRepository;
  raceRepository: IRaceRepository;
  resultRepository: IResultRepository;
  standingRepository: IStandingRepository;
  leagueMembershipRepository: ILeagueMembershipRepository;
  raceRegistrationRepository: IRaceRegistrationRepository;
  teamRepository: ITeamRepository;
  teamMembershipRepository: ITeamMembershipRepository;
  sponsorRepository: ISponsorRepository;
  feedRepository: IFeedRepository;
  socialGraphRepository: ISocialGraphRepository;
  driverStatsRepository: IDriverStatsRepository;
  teamStatsRepository: ITeamStatsRepository;
  mediaRepository: IMediaRepository;
};

export class SeedRacingData {
  constructor(
    private readonly logger: Logger,
    private readonly seedDeps: RacingSeedDependencies,
  ) {}

  private getApiPersistence(): 'postgres' | 'inmemory' {
    const configured = process.env.GRIDPILOT_API_PERSISTENCE?.toLowerCase();
    if (configured === 'postgres' || configured === 'inmemory') {
      return configured;
    }

    if (process.env.NODE_ENV === 'test') {
      return 'inmemory';
    }

    return process.env.DATABASE_URL ? 'postgres' : 'inmemory';
  }

  async execute(): Promise<void> {
    const existingDrivers = await this.seedDeps.driverRepository.findAll();
    const existingTeams = await this.seedDeps.teamRepository.findAll().catch(() => []);
    const persistence = this.getApiPersistence();
    
    // Check for force reseed via environment variable
    const forceReseedRaw = process.env.GRIDPILOT_API_FORCE_RESEED;
    const forceReseed = forceReseedRaw !== undefined && forceReseedRaw !== '0' && forceReseedRaw.toLowerCase() !== 'false';
    
    this.logger.info(
      `[Bootstrap] Racing seed precheck: forceReseed=${forceReseed}, drivers=${existingDrivers.length}, teams=${existingTeams.length}, persistence=${persistence}`,
    );

    if (existingDrivers.length > 0 && !forceReseed) {
      this.logger.info('[Bootstrap] Racing seed skipped (drivers already exist), ensuring scoring configs');
      await this.ensureScoringConfigsForExistingData();
      return;
    }

    // IMPORTANT:
    // Force reseed must clear even when drivers are already empty.
    // Otherwise stale teams can remain (e.g. with logoRef=system-default/logo),
    // and the seed will "ignore duplicates" on create, leaving stale logoRefs in Postgres.
    if (forceReseed) {
      this.logger.info(
        `[Bootstrap] Force reseed enabled - clearing existing racing data (drivers=${existingDrivers.length}, teams=${existingTeams.length})`,
      );
      await this.clearExistingRacingData();
    }

    const seed = createRacingSeed({
      persistence,
      driverCount: 150 // Expanded from 100 to 150
    });

    // Clear existing stats repositories
    await this.seedDeps.driverStatsRepository.clear();
    await this.seedDeps.teamStatsRepository.clear();

    this.logger.info('[Bootstrap] Cleared existing stats repositories');

    let sponsorshipRequestsSeededViaRepo = false;
    const seedableSponsorshipRequests = this.seedDeps
      .sponsorshipRequestRepository as unknown as { seed?: (input: unknown) => void };

    if (typeof seedableSponsorshipRequests.seed === 'function') {
      seedableSponsorshipRequests.seed(seed.sponsorshipRequests);
      sponsorshipRequestsSeededViaRepo = true;
    }

    for (const driver of seed.drivers) {
      try {
        await this.seedDeps.driverRepository.create(driver);
      } catch {
        // ignore duplicates
      }
    }

    for (const league of seed.leagues) {
      try {
        await this.seedDeps.leagueRepository.create(league);
      } catch {
        // ignore duplicates
      }
    }

    for (const season of seed.seasons) {
      try {
        await this.seedDeps.seasonRepository.create(season);
      } catch {
        // ignore duplicates
      }
    }

    const activeSeasons = seed.seasons.filter((season) => season.status.isActive());
    for (const season of activeSeasons) {
      const presetId = this.selectScoringPresetIdForSeason(season, persistence);
      const preset = getLeagueScoringPresetById(presetId);

      if (!preset) {
        this.logger.warn(
          `[Bootstrap] Scoring preset not found (presetId=${presetId}, seasonId=${season.id}, leagueId=${season.leagueId})`,
        );
        continue;
      }

      const scoringConfig = preset.createConfig({ seasonId: season.id });

      try {
        await this.seedDeps.leagueScoringConfigRepository.save(scoringConfig);
      } catch {
        // ignore duplicates
      }
    }

    for (const sponsorship of seed.seasonSponsorships) {
      try {
        await this.seedDeps.seasonSponsorshipRepository.create(sponsorship);
      } catch {
        // ignore duplicates
      }
    }

    if (!sponsorshipRequestsSeededViaRepo) {
      for (const request of seed.sponsorshipRequests) {
        try {
          await this.seedDeps.sponsorshipRequestRepository.create(request);
        } catch {
          // ignore duplicates
        }
      }
    }

    for (const wallet of seed.leagueWallets) {
      try {
        await this.seedDeps.leagueWalletRepository.create(wallet);
      } catch {
        // ignore duplicates
      }
    }

    for (const tx of seed.leagueWalletTransactions) {
      try {
        await this.seedDeps.transactionRepository.create(tx);
      } catch {
        // ignore duplicates
      }
    }

    for (const protest of seed.protests) {
      try {
        await this.seedDeps.protestRepository.create(protest);
      } catch {
        // ignore duplicates
      }
    }

    for (const penalty of seed.penalties) {
      try {
        await this.seedDeps.penaltyRepository.create(penalty);
      } catch {
        // ignore duplicates
      }
    }

    for (const race of seed.races) {
      try {
        await this.seedDeps.raceRepository.create(race);
      } catch {
        // ignore duplicates
      }
    }

    try {
      await this.seedDeps.resultRepository.createMany(seed.results);
    } catch {
      // ignore duplicates
    }

    for (const membership of seed.leagueMemberships) {
      try {
        await this.seedDeps.leagueMembershipRepository.saveMembership(membership);
      } catch {
        // ignore duplicates
      }
    }

    for (const request of seed.leagueJoinRequests) {
      try {
        await this.seedDeps.leagueMembershipRepository.saveJoinRequest(request);
      } catch {
        // ignore duplicates
      }
    }

    for (const team of seed.teams) {
      try {
        await this.seedDeps.teamRepository.create(team);
      } catch {
        // ignore duplicates
      }
    }

    for (const sponsor of seed.sponsors) {
      try {
        await this.seedDeps.sponsorRepository.create(sponsor);
      } catch {
        // ignore duplicates
      }
    }

    for (const membership of seed.teamMemberships) {
      try {
        await this.seedDeps.teamMembershipRepository.saveMembership(membership);
      } catch {
        // ignore duplicates
      }
    }

    for (const request of seed.teamJoinRequests) {
      try {
        await this.seedDeps.teamMembershipRepository.saveJoinRequest(request);
      } catch {
        // ignore duplicates
      }
    }

    for (const registration of seed.raceRegistrations) {
      try {
        await this.seedDeps.raceRegistrationRepository.register(registration);
      } catch {
        // ignore duplicates
      }
    }

    try {
      await this.seedDeps.standingRepository.saveMany(seed.standings);
    } catch {
      // ignore duplicates
    }

    const seedableFeed = this.seedDeps.feedRepository as unknown as { seed?: (input: unknown) => void };
    if (typeof seedableFeed.seed === 'function') {
      seedableFeed.seed({
        drivers: seed.drivers,
        friendships: seed.friendships,
        feedEvents: seed.feedEvents,
      });
    }

    const seedableSocial = this.seedDeps.socialGraphRepository as unknown as { seed?: (input: unknown) => void };
    if (typeof seedableSocial.seed === 'function') {
      seedableSocial.seed({
        drivers: seed.drivers,
        friendships: seed.friendships,
        feedEvents: seed.feedEvents,
      });
    }

    // Compute and store driver stats from real data
    await this.computeAndStoreDriverStats();
    
    // Compute and store team stats from real data
    await this.computeAndStoreTeamStats();

    this.logger.info(
      `[Bootstrap] Seeded racing data: drivers=${seed.drivers.length}, leagues=${seed.leagues.length}, races=${seed.races.length}`,
    );
  }

  private async computeAndStoreDriverStats(): Promise<void> {
    const drivers = await this.seedDeps.driverRepository.findAll();
    const standings = await this.seedDeps.standingRepository.findAll();
    const results = await this.seedDeps.resultRepository.findAll();

    this.logger.info(`[Bootstrap] Computing stats for ${drivers.length} drivers from ${standings.length} standings and ${results.length} results`);

    for (const driver of drivers) {
      const driverResults = results.filter(r => r.driverId.toString() === driver.id);
      const driverStandings = standings.filter(s => s.driverId.toString() === driver.id);

      if (driverResults.length === 0) continue;

      const stats = this.calculateDriverStats(driver, driverResults, driverStandings);
      await this.seedDeps.driverStatsRepository.saveDriverStats(driver.id, stats);
    }

    this.logger.info(`[Bootstrap] Computed and stored stats for ${drivers.length} drivers`);
  }

  private calculateDriverStats(driver: Driver, results: Result[], standings: Standing[]): DriverStats {
    const wins = results.filter(r => r.position.toNumber() === 1).length;
    const podiums = results.filter(r => r.position.toNumber() <= 3).length;
    const dnfs = results.filter(r => r.position.toNumber() > 20).length;
    const totalRaces = results.length;
    
    const positions = results.map(r => r.position.toNumber());
    const avgFinish = positions.reduce((sum, pos) => sum + pos, 0) / totalRaces;
    const bestFinish = Math.min(...positions);
    const worstFinish = Math.max(...positions);

    // Calculate rating based on performance
    let rating = 1000;
    const driverStanding = standings.find(s => s.driverId.toString() === driver.id);
    if (driverStanding) {
      const pointsBonus = driverStanding.points.toNumber() * 2;
      const positionBonus = Math.max(0, 50 - (driverStanding.position.toNumber() * 2));
      const winBonus = driverStanding.wins * 100;
      rating = Math.round(1000 + pointsBonus + positionBonus + winBonus);
    } else {
      const performanceBonus = ((totalRaces - wins) * 5) + ((totalRaces - podiums) * 2);
      rating = Math.round(1000 + (wins * 100) + (podiums * 50) - performanceBonus);
    }

    // Calculate consistency
    const avgPosition = avgFinish;
    const variance = positions.reduce((sum, pos) => sum + Math.pow(pos - avgPosition, 2), 0) / totalRaces;
    const consistency = Math.round(Math.max(0, 100 - (variance * 2)));

    // Safety rating (based on incidents)
    const totalIncidents = results.reduce((sum, r) => sum + r.incidents.toNumber(), 0);
    const safetyRating = Math.round(Math.max(0, 100 - (totalIncidents / totalRaces)));

    // Sportsmanship rating (placeholder)
    const sportsmanshipRating = 4.5;

    // Experience level
    const experienceLevel = this.determineExperienceLevel(totalRaces);

    // Overall rank
    const overallRank = driverStanding ? driverStanding.position.toNumber() : null;

    return {
      rating,
      safetyRating,
      sportsmanshipRating,
      totalRaces,
      wins,
      podiums,
      dnfs,
      avgFinish: Math.round(avgFinish * 10) / 10,
      bestFinish,
      worstFinish,
      consistency,
      experienceLevel,
      overallRank
    };
  }

  private async computeAndStoreTeamStats(): Promise<void> {
    const teams = await this.seedDeps.teamRepository.findAll();
    const results = await this.seedDeps.resultRepository.findAll();
    const drivers = await this.seedDeps.driverRepository.findAll();

    this.logger.info(`[Bootstrap] Computing stats for ${teams.length} teams`);

    for (const team of teams) {
      // Get team members using the correct method
      const teamMemberships = await this.seedDeps.teamMembershipRepository.getTeamMembers(team.id);
      const teamMemberIds = teamMemberships.map(m => m.driverId.toString());
      
      // Get results for team members
      const teamResults = results.filter(r => teamMemberIds.includes(r.driverId.toString()));
      
      // Get team drivers for name resolution
      const teamDrivers = drivers.filter(d => teamMemberIds.includes(d.id));

      const stats = this.calculateTeamStats(team, teamResults, teamDrivers);
      await this.seedDeps.teamStatsRepository.saveTeamStats(team.id, stats);
    }

    this.logger.info(`[Bootstrap] Computed and stored stats for ${teams.length} teams`);
  }

  private calculateTeamStats(_team: Team, results: Result[], drivers: Driver[]): TeamStats {
    const wins = results.filter(r => r.position.toNumber() === 1).length;
    const totalRaces = results.length;

    // Calculate rating
    const baseRating = 1000;
    const winBonus = wins * 50;
    const raceBonus = Math.min(totalRaces * 5, 200);
    const rating = Math.round(baseRating + winBonus + raceBonus);

    // Determine performance level
    let performanceLevel: 'beginner' | 'intermediate' | 'advanced' | 'pro';
    if (wins >= 20) performanceLevel = 'pro';
    else if (wins >= 10) performanceLevel = 'advanced';
    else if (wins >= 5) performanceLevel = 'intermediate';
    else performanceLevel = 'beginner';

    // Determine specialization (based on race types - simplified)
    const specialization: 'endurance' | 'sprint' | 'mixed' = 'mixed';

    // Get region from team name or first driver
    const region = drivers.length > 0 && drivers[0] ? drivers[0].country.toString() : 'International';

    // Languages (based on drivers)
    const languages = Array.from(new Set(drivers.map(d => {
      // Simplified language mapping based on country
      const country = d.country.toString().toLowerCase();
      if (country === 'us' || country === 'gb' || country === 'ca') return 'en';
      if (country === 'de') return 'de';
      if (country === 'fr') return 'fr';
      if (country === 'es') return 'es';
      if (country === 'it') return 'it';
      if (country === 'jp') return 'ja';
      return 'en';
    })));

    return {
      performanceLevel,
      specialization,
      region,
      languages,
      totalWins: wins,
      totalRaces,
      rating
    };
  }

  private determineExperienceLevel(totalRaces: number): string {
    if (totalRaces >= 100) return 'Veteran';
    if (totalRaces >= 50) return 'Experienced';
    if (totalRaces >= 20) return 'Intermediate';
    if (totalRaces >= 10) return 'Rookie';
    return 'Beginner';
  }


  private async clearExistingRacingData(): Promise<void> {
    this.logger.info('[Bootstrap] Starting comprehensive clearing of all racing data');

    // Clear stats repositories first
    try {
      await this.seedDeps.driverStatsRepository.clear();
      await this.seedDeps.teamStatsRepository.clear();
      this.logger.info('[Bootstrap] Cleared stats repositories');
    } catch (error) {
      this.logger.warn('[Bootstrap] Could not clear stats repositories:', error);
    }

    // Clear race registrations - get all races first, then clear their registrations
    try {
      const races = await this.seedDeps.raceRepository.findAll();
      for (const race of races) {
        try {
          await this.seedDeps.raceRegistrationRepository.clearRaceRegistrations(race.id.toString());
        } catch {
          // Ignore
        }
      }
      this.logger.info('[Bootstrap] Cleared race registrations');
    } catch (error) {
      this.logger.warn('[Bootstrap] Could not clear race registrations:', error);
    }

    // Clear team join requests - get all teams first, then clear their join requests
    try {
      const teams = await this.seedDeps.teamRepository.findAll();
      for (const team of teams) {
        const joinRequests = await this.seedDeps.teamMembershipRepository.getJoinRequests(team.id.toString());
        for (const request of joinRequests) {
          try {
            await this.seedDeps.teamMembershipRepository.removeJoinRequest(request.id);
          } catch {
            // Ignore
          }
        }
      }
      this.logger.info('[Bootstrap] Cleared team join requests');
    } catch (error) {
      this.logger.warn('[Bootstrap] Could not clear team join requests:', error);
    }

    // Clear team memberships
    try {
      const teams = await this.seedDeps.teamRepository.findAll();
      for (const team of teams) {
        const memberships = await this.seedDeps.teamMembershipRepository.getTeamMembers(team.id.toString());
        for (const membership of memberships) {
          try {
            await this.seedDeps.teamMembershipRepository.removeMembership(team.id.toString(), membership.driverId.toString());
          } catch {
            // Ignore
          }
        }
      }
      this.logger.info('[Bootstrap] Cleared team memberships');
    } catch (error) {
      this.logger.warn('[Bootstrap] Could not clear team memberships:', error);
    }

    // Clear teams (this is critical - teams have stale logoRef)
    try {
      const teams = await this.seedDeps.teamRepository.findAll();
      for (const team of teams) {
        try {
          await this.seedDeps.teamRepository.delete(team.id.toString());
        } catch {
          // Ignore
        }
      }
      this.logger.info('[Bootstrap] Cleared teams');
    } catch (error) {
      this.logger.warn('[Bootstrap] Could not clear teams:', error);
    }

    // Clear results
    try {
      const results = await this.seedDeps.resultRepository.findAll();
      for (const result of results) {
        try {
          await this.seedDeps.resultRepository.delete(result.id.toString());
        } catch {
          // Ignore
        }
      }
      this.logger.info('[Bootstrap] Cleared results');
    } catch (error) {
      this.logger.warn('[Bootstrap] Could not clear results:', error);
    }

    // Clear standings
    try {
      const standings = await this.seedDeps.standingRepository.findAll();
      for (const standing of standings) {
        try {
          await this.seedDeps.standingRepository.delete(standing.leagueId.toString(), standing.driverId.toString());
        } catch {
          // Ignore
        }
      }
      this.logger.info('[Bootstrap] Cleared standings');
    } catch (error) {
      this.logger.warn('[Bootstrap] Could not clear standings:', error);
    }

    // Clear races
    try {
      const races = await this.seedDeps.raceRepository.findAll();
      for (const race of races) {
        try {
          await this.seedDeps.raceRepository.delete(race.id.toString());
        } catch {
          // Ignore
        }
      }
      this.logger.info('[Bootstrap] Cleared races');
    } catch (error) {
      this.logger.warn('[Bootstrap] Could not clear races:', error);
    }

    // Clear league join requests
    try {
      const leagues = await this.seedDeps.leagueRepository.findAll();
      for (const league of leagues) {
        const joinRequests = await this.seedDeps.leagueMembershipRepository.getJoinRequests(league.id.toString());
        for (const request of joinRequests) {
          try {
            await this.seedDeps.leagueMembershipRepository.removeJoinRequest(request.id);
          } catch {
            // Ignore
          }
        }
      }
      this.logger.info('[Bootstrap] Cleared league join requests');
    } catch (error) {
      this.logger.warn('[Bootstrap] Could not clear league join requests:', error);
    }

    // Clear league memberships
    try {
      const leagues = await this.seedDeps.leagueRepository.findAll();
      for (const league of leagues) {
        const memberships = await this.seedDeps.leagueMembershipRepository.getLeagueMembers(league.id.toString());
        for (const membership of memberships) {
          try {
            await this.seedDeps.leagueMembershipRepository.removeMembership(league.id.toString(), membership.driverId.toString());
          } catch {
            // Ignore
          }
        }
      }
      this.logger.info('[Bootstrap] Cleared league memberships');
    } catch (error) {
      this.logger.warn('[Bootstrap] Could not clear league memberships:', error);
    }

    // Note: Some repositories don't support direct deletion methods
    // The key fix is clearing teams, team memberships, and join requests
    // which resolves the logoRef issue

    // Clear leagues
    try {
      const leagues = await this.seedDeps.leagueRepository.findAll();
      for (const league of leagues) {
        try {
          await this.seedDeps.leagueRepository.delete(league.id.toString());
        } catch {
          // Ignore
        }
      }
      this.logger.info('[Bootstrap] Cleared leagues');
    } catch (error) {
      this.logger.warn('[Bootstrap] Could not clear leagues:', error);
    }

    // Clear drivers (do this last as other data depends on it)
    try {
      const drivers = await this.seedDeps.driverRepository.findAll();
      for (const driver of drivers) {
        try {
          await this.seedDeps.driverRepository.delete(driver.id);
        } catch {
          // Ignore
        }
      }
      this.logger.info('[Bootstrap] Cleared drivers');
    } catch (error) {
      this.logger.warn('[Bootstrap] Could not clear drivers:', error);
    }

    // Clear social data if repositories support it
    try {
      const seedableFeed = this.seedDeps.feedRepository as unknown as { clear?: () => void };
      if (typeof seedableFeed.clear === 'function') {
        seedableFeed.clear();
        this.logger.info('[Bootstrap] Cleared feed repository');
      }
    } catch (error) {
      this.logger.warn('[Bootstrap] Could not clear feed repository:', error);
    }

    try {
      const seedableSocial = this.seedDeps.socialGraphRepository as unknown as { clear?: () => void };
      if (typeof seedableSocial.clear === 'function') {
        seedableSocial.clear();
        this.logger.info('[Bootstrap] Cleared social graph repository');
      }
    } catch (error) {
      this.logger.warn('[Bootstrap] Could not clear social graph repository:', error);
    }

    this.logger.info('[Bootstrap] Completed comprehensive clearing of all racing data');
  }

  private async ensureScoringConfigsForExistingData(): Promise<void> {
    const leagues = await this.seedDeps.leagueRepository.findAll();

    for (const league of leagues) {
      const seasons = await this.seedDeps.seasonRepository.findByLeagueId(league.id.toString());
      const activeSeasons = seasons.filter((season) => season.status.isActive());

      for (const season of activeSeasons) {
        const existing = await this.seedDeps.leagueScoringConfigRepository.findBySeasonId(season.id);
        if (existing) continue;

        const presetId = this.selectScoringPresetIdForSeason(season, 'postgres');
        const preset = getLeagueScoringPresetById(presetId);

        if (!preset) {
          this.logger.warn(
            `[Bootstrap] Scoring preset not found (presetId=${presetId}, seasonId=${season.id}, leagueId=${season.leagueId})`,
          );
          continue;
        }

        const scoringConfig = preset.createConfig({ seasonId: season.id });

        try {
          await this.seedDeps.leagueScoringConfigRepository.save(scoringConfig);
        } catch {
          // ignore duplicates
        }
      }
    }
  }

  private selectScoringPresetIdForSeason(season: Season, persistence: 'postgres' | 'inmemory'): string {
    const expectedLeagueId = seedId('league-5', persistence);
    const expectedSeasonId = seedId('season-1-b', persistence);
    
    if (season.leagueId === expectedLeagueId && season.status.isActive()) {
      return 'sprint-main-driver';
    }

    if (season.leagueId === seedId('league-3', persistence)) {
      return season.id === expectedSeasonId ? 'sprint-main-team' : 'club-default-nations';
    }

    const match = /^league-(\d+)$/.exec(season.leagueId);
    const leagueNumber = match ? Number(match[1]) : undefined;

    if (leagueNumber !== undefined) {
      switch (leagueNumber % 4) {
        case 0:
          return 'sprint-main-team';
        case 1:
          return 'endurance-main-trophy';
        case 2:
          return 'sprint-main-driver';
        case 3:
          return 'club-default-nations';
      }
    }

    return 'club-default';
  }
}
