import 'package:get_it/get_it.dart';
import 'package:dio/dio.dart';
import '../network/api_client.dart';
import '../network/interceptors.dart';
import '../../data/datasources/local/cache_manager.dart';
import '../../data/datasources/remote/auth_remote_datasource.dart';
import '../../data/datasources/remote/mining_remote_datasource.dart';
import '../../data/datasources/remote/trading_remote_datasource.dart';
import '../../data/datasources/remote/contribution_remote_datasource.dart';
import '../../data/datasources/remote/referral_remote_datasource.dart';
import '../../data/repositories/mining_repository_impl.dart';
import '../../data/repositories/trading_repository_impl.dart';
import '../../data/repositories/contribution_repository_impl.dart';
import '../../domain/repositories/mining_repository.dart';
import '../../domain/repositories/trading_repository.dart';
import '../../domain/repositories/contribution_repository.dart';
import '../../domain/usecases/mining/get_share_account.dart';
import '../../domain/usecases/mining/get_global_state.dart';
import '../../domain/usecases/contribution/get_user_contribution.dart';

final getIt = GetIt.instance;

Future<void> configureDependencies() async {
  // Dio
  final dio = Dio();
  dio.interceptors.add(LoggingInterceptor());
  getIt.registerSingleton<Dio>(dio);

  // API Client
  getIt.registerSingleton<ApiClient>(ApiClient(dio: getIt<Dio>()));

  // Cache Manager
  getIt.registerSingleton<CacheManager>(CacheManager());

  // Data Sources
  getIt.registerLazySingleton<MiningRemoteDataSource>(
    () => MiningRemoteDataSourceImpl(client: getIt<ApiClient>()),
  );
  getIt.registerLazySingleton<TradingRemoteDataSource>(
    () => TradingRemoteDataSourceImpl(client: getIt<ApiClient>()),
  );
  getIt.registerLazySingleton<ContributionRemoteDataSource>(
    () => ContributionRemoteDataSourceImpl(client: getIt<ApiClient>()),
  );

  // Auth Data Source
  getIt.registerLazySingleton<AuthRemoteDataSource>(
    () => AuthRemoteDataSourceImpl(client: getIt<ApiClient>()),
  );

  // Referral Data Source
  getIt.registerLazySingleton<ReferralRemoteDataSource>(
    () => ReferralRemoteDataSourceImpl(client: getIt<ApiClient>()),
  );

  // Repositories
  getIt.registerLazySingleton<MiningRepository>(
    () => MiningRepositoryImpl(
      remoteDataSource: getIt<MiningRemoteDataSource>(),
      cacheManager: getIt<CacheManager>(),
    ),
  );
  getIt.registerLazySingleton<TradingRepository>(
    () => TradingRepositoryImpl(
      remoteDataSource: getIt<TradingRemoteDataSource>(),
    ),
  );
  getIt.registerLazySingleton<ContributionRepository>(
    () => ContributionRepositoryImpl(
      remoteDataSource: getIt<ContributionRemoteDataSource>(),
    ),
  );

  // Use Cases - Mining
  getIt.registerLazySingleton(() => GetShareAccount(getIt<MiningRepository>()));
  getIt.registerLazySingleton(() => GetGlobalState(getIt<MiningRepository>()));

  // Use Cases - Contribution
  getIt.registerLazySingleton(() => GetUserContribution(getIt<ContributionRepository>()));
}
