import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';

// IMPORTANT: SeedRacingData imports createRacingSeed from ./racing/RacingSeed
// We mock it to avoid heavy seed generation and to keep the test focused on
// force-reseed decision logic.
vi.mock('./racing/RacingSeed', () => {
  return {
    createRacingSeed: vi.fn(() => ({
      drivers: [],
      driverStats: new Map(),
      leagues: [],
      seasons: [],
      seasonSponsorships: [],
      sponsorshipRequests: [],
      leagueWallets: [],
      leagueWalletTransactions: [],
      protests: [],
      penalties: [],
      races: [],
      results: [],
      standings: [],
      leagueMemberships: [],
      leagueJoinRequests: [],
      raceRegistrations: [],
      teams: [],
      teamStats: new Map(),
      teamMemberships: [],
      teamJoinRequests: [],
      sponsors: [],
      tracks: [],
      friendships: [],
      feedEvents: [],
    })),
  };
});

import type { Logger } from '@core/shared/application';
import { SeedRacingData, type RacingSeedDependencies } from './SeedRacingData';

describe('SeedRacingData force reseed behavior', () => {
  const originalEnv = { ...process.env };

  beforeEach(() => {
    vi.clearAllMocks();
    process.env = { ...originalEnv };
  });

  afterEach(() => {
    process.env = originalEnv;
  });

  it('clears existing racing data when force reseed is enabled even if drivers are empty (stale teams scenario)', async () => {
    process.env.GRIDPILOT_API_FORCE_RESEED = '1';
    process.env.GRIDPILOT_API_PERSISTENCE = 'inmemory';
    delete process.env.DATABASE_URL;

    const logger: Logger = {
      debug: vi.fn(),
      info: vi.fn(),
      warn: vi.fn(),
      error: vi.fn(),
    };

    const seedDeps = {
      driverRepository: {
        findAll: vi.fn().mockResolvedValue([]),
        create: vi.fn(),
        delete: vi.fn(),
      },
      leagueRepository: { findAll: vi.fn().mockResolvedValue([]), create: vi.fn(), delete: vi.fn() },
      seasonRepository: { findByLeagueId: vi.fn().mockResolvedValue([]), create: vi.fn() },
      leagueScoringConfigRepository: { findBySeasonId: vi.fn().mockResolvedValue(null), save: vi.fn() },
      seasonSponsorshipRepository: { create: vi.fn() },
      sponsorshipRequestRepository: { create: vi.fn() },
      leagueWalletRepository: { create: vi.fn() },
      transactionRepository: { create: vi.fn() },
      protestRepository: { create: vi.fn() },
      penaltyRepository: { create: vi.fn() },
      raceRepository: { findAll: vi.fn().mockResolvedValue([]), create: vi.fn(), delete: vi.fn() },
      resultRepository: { findAll: vi.fn().mockResolvedValue([]), createMany: vi.fn() },
      standingRepository: { findAll: vi.fn().mockResolvedValue([]), saveMany: vi.fn() },
      leagueMembershipRepository: {
        saveMembership: vi.fn(),
        saveJoinRequest: vi.fn(),
        getJoinRequests: vi.fn().mockResolvedValue([]),
        getLeagueMembers: vi.fn().mockResolvedValue([]),
        removeJoinRequest: vi.fn(),
        removeMembership: vi.fn(),
      },
      raceRegistrationRepository: { register: vi.fn(), clearRaceRegistrations: vi.fn() },
      // STALE TEAMS PRESENT
      teamRepository: {
        findAll: vi.fn().mockResolvedValue([{ id: 't1' }]),
        create: vi.fn(),
        delete: vi.fn(),
      },
      teamMembershipRepository: {
        saveMembership: vi.fn(),
        saveJoinRequest: vi.fn(),
        getJoinRequests: vi.fn().mockResolvedValue([]),
        getTeamMembers: vi.fn().mockResolvedValue([]),
        removeJoinRequest: vi.fn(),
        removeMembership: vi.fn(),
      },
      sponsorRepository: { create: vi.fn() },
      feedRepository: {},
      socialGraphRepository: {},
      driverStatsRepository: { clear: vi.fn(), saveDriverStats: vi.fn() },
      teamStatsRepository: { clear: vi.fn(), saveTeamStats: vi.fn(), getTeamStats: vi.fn().mockResolvedValue(null) },
      mediaRepository: { clear: vi.fn() },
    } as unknown as RacingSeedDependencies;

    const s = new SeedRacingData(logger, seedDeps);

    // Spy on the private method by monkey-patching (this is the behavior under test)
    const clearSpy = vi.fn().mockResolvedValue(undefined);
    (s as unknown as { clearExistingRacingData: () => Promise<void> }).clearExistingRacingData = clearSpy;

    await s.execute();

    expect(clearSpy).toHaveBeenCalledTimes(1);
  });
});
