import type { IdentitySessionPort } from '@core/identity/application/ports/IdentitySessionPort';
import { SignupWithEmailUseCase } from '@core/identity/application/use-cases/SignupWithEmailUseCase';
import {
    CreateAchievementUseCase,
    type AchievementRepository,
} from '@core/identity/application/use-cases/achievement/CreateAchievementUseCase';
import type { UserRepository } from '@core/identity/domain/repositories/UserRepository';
import type { Logger } from '@core/shared/domain/Logger';
import { Provider } from '@nestjs/common';
import { EnsureInitialData } from '../../../../../adapters/bootstrap/EnsureInitialData';
import { SeedDemoUsers } from '../../../../../adapters/bootstrap/SeedDemoUsers';
import type { RacingSeedDependencies } from '../../../../../adapters/bootstrap/SeedRacingData';
import { CookieIdentitySessionAdapter } from '../../../../../adapters/identity/session/CookieIdentitySessionAdapter';
import { ACHIEVEMENT_REPOSITORY_TOKEN } from '../../persistence/achievement/AchievementPersistenceTokens';
import { ADMIN_USER_REPOSITORY_TOKEN } from '../../persistence/admin/AdminPersistenceTokens';
import { AUTH_REPOSITORY_TOKEN, USER_REPOSITORY_TOKEN as IDENTITY_USER_REPOSITORY_TOKEN, PASSWORD_HASHING_SERVICE_TOKEN } from '../../persistence/identity/IdentityPersistenceTokens';
import { SOCIAL_FEED_REPOSITORY_TOKEN, SOCIAL_GRAPH_REPOSITORY_TOKEN } from '../../persistence/social/SocialPersistenceTokens';

// Define tokens
export const USER_REPOSITORY_TOKEN = 'IUserRepository_Bootstrap';
// ACHIEVEMENT_REPOSITORY_TOKEN is now imported from AchievementPersistenceTokens
export const IDENTITY_SESSION_PORT_TOKEN = 'IdentitySessionPort_Bootstrap';
export const SIGNUP_USE_CASE_TOKEN = 'SignupWithEmailUseCase_Bootstrap';
export const CREATE_ACHIEVEMENT_USE_CASE_TOKEN = 'CreateAchievementUseCase_Bootstrap';

export const RACING_SEED_DEPENDENCIES_TOKEN = 'RacingSeedDependencies';
export const ENSURE_INITIAL_DATA_TOKEN = 'EnsureInitialData_Bootstrap';
export const SEED_DEMO_USERS_TOKEN = 'SeedDemoUsers';

export const BootstrapProviders: Provider[] = [
  {
    provide: RACING_SEED_DEPENDENCIES_TOKEN,
    useFactory: (
      driverRepository: RacingSeedDependencies['driverRepository'],
      leagueRepository: RacingSeedDependencies['leagueRepository'],
      seasonRepository: RacingSeedDependencies['seasonRepository'],
      leagueScoringConfigRepository: RacingSeedDependencies['leagueScoringConfigRepository'],
      seasonSponsorshipRepository: RacingSeedDependencies['seasonSponsorshipRepository'],
      sponsorshipRequestRepository: RacingSeedDependencies['sponsorshipRequestRepository'],
      leagueWalletRepository: RacingSeedDependencies['leagueWalletRepository'],
      transactionRepository: RacingSeedDependencies['transactionRepository'],
      protestRepository: RacingSeedDependencies['protestRepository'],
      penaltyRepository: RacingSeedDependencies['penaltyRepository'],
      raceRepository: RacingSeedDependencies['raceRepository'],
      resultRepository: RacingSeedDependencies['resultRepository'],
      standingRepository: RacingSeedDependencies['standingRepository'],
      leagueMembershipRepository: RacingSeedDependencies['leagueMembershipRepository'],
      raceRegistrationRepository: RacingSeedDependencies['raceRegistrationRepository'],
      teamRepository: RacingSeedDependencies['teamRepository'],
      teamMembershipRepository: RacingSeedDependencies['teamMembershipRepository'],
      sponsorRepository: RacingSeedDependencies['sponsorRepository'],
      feedRepository: RacingSeedDependencies['feedRepository'],
      socialGraphRepository: RacingSeedDependencies['socialGraphRepository'],
      driverStatsRepository: RacingSeedDependencies['driverStatsRepository'],
      teamStatsRepository: RacingSeedDependencies['teamStatsRepository'],
      mediaRepository: RacingSeedDependencies['mediaRepository'],
      authRepository: RacingSeedDependencies['authRepository'],
      passwordHashingService: RacingSeedDependencies['passwordHashingService'],
      adminUserRepository: RacingSeedDependencies['adminUserRepository'],
    ): RacingSeedDependencies => ({
      driverRepository,
      leagueRepository,
      seasonRepository,
      leagueScoringConfigRepository,
      seasonSponsorshipRepository,
      sponsorshipRequestRepository,
      leagueWalletRepository,
      transactionRepository,
      protestRepository,
      penaltyRepository,
      raceRepository,
      resultRepository,
      standingRepository,
      leagueMembershipRepository,
      raceRegistrationRepository,
      teamRepository,
      teamMembershipRepository,
      sponsorRepository,
      feedRepository,
      socialGraphRepository,
      driverStatsRepository,
      teamStatsRepository,
      mediaRepository,
      authRepository,
      passwordHashingService,
      adminUserRepository,
    }),
    inject: [
      'IDriverRepository',
      'ILeagueRepository',
      'ISeasonRepository',
      'ILeagueScoringConfigRepository',
      'ISeasonSponsorshipRepository',
      'ISponsorshipRequestRepository',
      'ILeagueWalletRepository',
      'ITransactionRepository',
      'IProtestRepository',
      'IPenaltyRepository',
      'IRaceRepository',
      'IResultRepository',
      'IStandingRepository',
      'ILeagueMembershipRepository',
      'IRaceRegistrationRepository',
      'ITeamRepository',
      'ITeamMembershipRepository',
      'ISponsorRepository',
      SOCIAL_FEED_REPOSITORY_TOKEN,
      SOCIAL_GRAPH_REPOSITORY_TOKEN,
      'IDriverStatsRepository',
      'ITeamStatsRepository',
      'IMediaRepository',
      AUTH_REPOSITORY_TOKEN,
      PASSWORD_HASHING_SERVICE_TOKEN,
      ADMIN_USER_REPOSITORY_TOKEN,
    ],
  },
  {
    provide: USER_REPOSITORY_TOKEN,
    useFactory: (userRepository: UserRepository) => userRepository,
    inject: [IDENTITY_USER_REPOSITORY_TOKEN],
  },
  // Achievement repository is now provided by AchievementPersistenceModule
  {
    provide: IDENTITY_SESSION_PORT_TOKEN,
    useFactory: (logger: Logger) => new CookieIdentitySessionAdapter(logger),
    inject: ['Logger'],
  },
  {
    provide: SIGNUP_USE_CASE_TOKEN,
    useFactory: (
      userRepository: UserRepository, 
      sessionPort: IdentitySessionPort,
      logger: Logger
    ) => {
      return new SignupWithEmailUseCase(
        userRepository, 
        sessionPort, 
        logger
      );
    },
    inject: [USER_REPOSITORY_TOKEN, IDENTITY_SESSION_PORT_TOKEN, 'Logger'],
  },
  {
    provide: CREATE_ACHIEVEMENT_USE_CASE_TOKEN,
    useFactory: (
      achievementRepository: AchievementRepository,
      logger: Logger
    ) => {
      return new CreateAchievementUseCase(
        achievementRepository,
        logger
      );
    },
    inject: [ACHIEVEMENT_REPOSITORY_TOKEN, 'Logger'],
  },
  {
    provide: ENSURE_INITIAL_DATA_TOKEN,
    useFactory: (
      signupUseCase: SignupWithEmailUseCase,
      createAchievementUseCase: CreateAchievementUseCase,
      logger: Logger,
    ) => {
      return new EnsureInitialData(signupUseCase, createAchievementUseCase, logger);
    },
    inject: [SIGNUP_USE_CASE_TOKEN, CREATE_ACHIEVEMENT_USE_CASE_TOKEN, 'Logger'],
  },
  {
    provide: SEED_DEMO_USERS_TOKEN,
    useFactory: (
      logger: Logger,
      seedDeps: RacingSeedDependencies,
    ) => {
      return new SeedDemoUsers(logger, seedDeps.authRepository, seedDeps.passwordHashingService, seedDeps.adminUserRepository);
    },
    inject: ['Logger', RACING_SEED_DEPENDENCIES_TOKEN],
  },
];