import 'package:get_it/get_it.dart';

import '../../feature/auth/data/data_source/local/auth_local_data.dart';
import '../../feature/auth/data/data_source/remote/auth_api_provider.dart';
import '../../feature/auth/data/repository/auth_repository_impl.dart';
import '../../feature/auth/domain/repository/auth_repository.dart';
import '../../feature/auth/domain/use_cases/check_otp_usecase.dart';
import '../../feature/auth/domain/use_cases/login_usecase.dart';
import '../../feature/auth/domain/use_cases/logout_usecase.dart';
import '../../feature/auth/domain/use_cases/update_profile_usecase.dart';
import '../../feature/auth/presentation/bloc/auth_bloc.dart';
import '../../feature/game/data/data_source/remote/game_api_provider.dart';
import '../../feature/game/data/data_source/remote/game_ws_provider.dart';
import '../../feature/game/data/repository/game_repository_impl.dart';
import '../../feature/game/domain/repository/game_repository.dart';
import '../../feature/game/domain/use_cases/get_tables_info_usecase.dart';
import '../../feature/game/domain/use_cases/get_tiers_usecase.dart';
import '../../feature/game/presentation/bloc/game_bloc.dart';
import '../../feature/game/presentation/bloc/private_info_bloc.dart';
import '../../feature/game/presentation/bloc/tier_bloc.dart';
import '../../feature/profile/data/data_source/remote/profile_api_provider.dart';
import '../../feature/profile/data/repository/profile_repository_impl.dart';
import '../../feature/profile/domain/repository/profile_repository.dart';
import '../../feature/profile/domain/use_cases/get_profile_usecase.dart';
import '../../feature/profile/domain/use_cases/save_profile_usecase.dart';
import '../../feature/profile/presentation/bloc/profile_bloc.dart';
import '../../feature/ranked/data/data_source/remote/ranked_api_provider.dart';
import '../../feature/chat/data/data_source/remote/chat_api_provider.dart';
import '../../feature/ranked/data/repository/ranked_repository_impl.dart';
import '../../feature/ranked/domain/repository/ranked_repository.dart';
import '../../feature/ranked/domain/use_cases/get_leaderboard_usecase.dart';
import '../../feature/ranked/presentation/bloc/leaderboard_bloc.dart';
import '../../feature/shop/data/data_source/remote/shop_api_provider.dart';
import '../../feature/shop/data/data_source/remote/avatar_api_provider.dart';
import '../../feature/shop/data/data_source/remote/carpet_api_provider.dart';
import '../../feature/shop/data/data_source/remote/frame_api_provider.dart';
import '../../feature/tournament/data/data_source/remote/tournament_api_provider.dart';
import '../../feature/shop/data/repository/shop_repository_impl.dart';
import '../../feature/shop/domain/repository/shop_repository.dart';
import '../../feature/shop/domain/use_cases/ad_reward_usecase.dart';
import '../../feature/shop/domain/use_cases/buy_card_usecase.dart';
import '../../feature/shop/domain/use_cases/get_shop_usecase.dart';
import '../../feature/shop/domain/use_cases/purchase_usecase.dart';
import '../../feature/shop/domain/use_cases/select_card_usecase.dart';
import '../../feature/shop/presentation/bloc/shop_bloc.dart';
import '../../feature/wallet/data/data_source/remote/wallet_api_provider.dart';
import '../../feature/wallet/data/repository/wallet_repository_impl.dart';
import '../../feature/wallet/domain/repository/wallet_repository.dart';
import '../../feature/wallet/domain/use_cases/claim_daily_usecase.dart';
import '../../feature/wallet/domain/use_cases/get_wallet_usecase.dart';
import '../../feature/wallet/presentation/bloc/wallet_bloc.dart';
import '../config.dart';
import '../network/api_provider_imp.dart';
import '../payment/bazaar_payment_gateway.dart';
import '../payment/dev_payment_gateway.dart';
import '../payment/myket_payment_gateway.dart';
import '../payment/payment_gateway.dart';
import '../storage/token_storage.dart';

final GetIt locator = GetIt.instance;

/// ثبتِ همه‌ی وابستگی‌ها (تک‌خط در main فراخوانی می‌شود).
Future<void> setupLocator() async {
  // --- core ---
  locator.registerSingleton<TokenStorage>(TokenStorage());
  locator.registerSingleton<ApiProviderImp>(ApiProviderImp(locator()));

  // --- data sources ---
  locator.registerSingleton<AuthLocalData>(AuthLocalData(locator()));
  locator.registerSingleton<AuthApiProvider>(AuthApiProvider());
  locator.registerSingleton<WalletApiProvider>(WalletApiProvider());
  locator.registerSingleton<ShopApiProvider>(ShopApiProvider());
  locator.registerSingleton<CarpetApiProvider>(CarpetApiProvider());
  locator.registerSingleton<FrameApiProvider>(FrameApiProvider());
  locator.registerSingleton<AvatarApiProvider>(AvatarApiProvider());
  locator.registerSingleton<ProfileApiProvider>(ProfileApiProvider());
  locator.registerSingleton<RankedApiProvider>(RankedApiProvider());
  locator.registerSingleton<ChatApiProvider>(ChatApiProvider());
  locator.registerSingleton<TournamentApiProvider>(TournamentApiProvider());
  locator.registerSingleton<GameApiProvider>(GameApiProvider());
  locator.registerSingleton<GameWsProvider>(GameWsProvider(locator()));

  // --- repositories ---
  locator.registerSingleton<AuthRepository>(
      AuthRepositoryImpl(locator(), locator()));
  locator.registerSingleton<WalletRepository>(
      WalletRepositoryImpl(locator()));
  locator.registerSingleton<ShopRepository>(ShopRepositoryImpl(locator()));
  locator.registerSingleton<ProfileRepository>(
      ProfileRepositoryImpl(locator()));
  locator.registerSingleton<RankedRepository>(RankedRepositoryImpl(locator()));
  locator.registerSingleton<GameRepository>(
      GameRepositoryImpl(locator(), locator()));

  // --- use cases ---
  locator.registerSingleton<LoginUseCase>(LoginUseCase(locator()));
  locator.registerSingleton<CheckOtpUseCase>(CheckOtpUseCase(locator()));
  locator.registerSingleton<UpdateProfileUseCase>(
      UpdateProfileUseCase(locator()));
  locator.registerSingleton<LogoutUseCase>(LogoutUseCase(locator()));
  locator.registerSingleton<GetWalletUseCase>(GetWalletUseCase(locator()));
  locator.registerSingleton<ClaimDailyUseCase>(ClaimDailyUseCase(locator()));
  locator.registerSingleton<GetShopUseCase>(GetShopUseCase(locator()));
  locator.registerSingleton<BuyCardUseCase>(BuyCardUseCase(locator()));
  locator.registerSingleton<SelectCardUseCase>(SelectCardUseCase(locator()));
  locator.registerSingleton<PurchaseUseCase>(PurchaseUseCase(locator()));
  locator.registerSingleton<AdRewardUseCase>(AdRewardUseCase(locator()));

  // درگاهِ پرداخت بر اساسِ flavorِ فعال (مایکت/کافه‌بازار/توسعه).
  locator.registerSingleton<PaymentGateway>(_gatewayForStore(AppConfig.store));
  locator.registerSingleton<GetProfileUseCase>(GetProfileUseCase(locator()));
  locator.registerSingleton<SaveProfileUseCase>(SaveProfileUseCase(locator()));
  locator.registerSingleton<GetLeaderboardUseCase>(
      GetLeaderboardUseCase(locator()));
  locator.registerSingleton<GetTiersUseCase>(GetTiersUseCase(locator()));
  locator.registerSingleton<GetTablesInfoUseCase>(
      GetTablesInfoUseCase(locator()));

  // --- blocs (factory) ---
  locator.registerFactory<AuthBloc>(
      () => AuthBloc(locator(), locator(), locator(), locator()));
  locator.registerFactory<WalletBloc>(() => WalletBloc(locator(), locator()));
  locator.registerFactory<ShopBloc>(() => ShopBloc(locator(), locator(),
      locator(), locator(), locator(), locator(), locator()));
  locator.registerFactory<ProfileBloc>(
      () => ProfileBloc(locator(), locator()));
  locator.registerFactory<LeaderboardBloc>(() => LeaderboardBloc(locator()));
  locator.registerFactory<GameBloc>(() => GameBloc(locator()));
  locator.registerFactory<TierBloc>(() => TierBloc(locator()));
  locator.registerFactory<PrivateInfoBloc>(() => PrivateInfoBloc(locator()));
}

/// درگاهِ پرداختِ متناظر با flavor. buildهای بدونِ flavor از درگاهِ توسعه
/// استفاده می‌کنند (بک‌اند در DevFallback می‌پذیرد).
PaymentGateway _gatewayForStore(String store) {
  switch (store) {
    case 'myket':
      return MyketPaymentGateway();
    case 'bazaar':
      return BazaarPaymentGateway();
    default:
      return DevPaymentGateway();
  }
}
