content: import 'dart:io';
  
  import 'package:bb_mobile/core/exchange/domain/repositories/exchange_rate_repository.dart';
  import 'package:bb_mobile/core/fees/data/fees_repository.dart';
  import 'package:bb_mobile/core/payjoin/domain/repositories/payjoin_repository.dart';
  import 'package:bb_mobile/core/status/domain/entity/service_status.dart';
  import 'package:bb_mobile/core/status/domain/ports/electrum_connectivity_port.dart';
  import 'package:bb_mobile/core/swaps/data/repository/boltz_swap_repository.dart';
  import 'package:bb_mobile/core/swaps/domain/entity/swap.dart';
  import 'package:bb_mobile/core/utils/logger.dart';
  import 'package:bb_mobile/core/wallet/domain/entities/wallet.dart';
  
  class CheckAllServiceStatusUsecase {
    final ElectrumConnectivityPort _electrumConnectivityPort;
    final BoltzSwapRepository _mainnetBoltzSwapRepository;
    final BoltzSwapRepository _testnetBoltzSwapRepository;
    final ExchangeRateRepository _exchangeRateRepository;
    final PayjoinRepository _payjoinRepository;
    final FeesRepository _feesRepository;
  
    CheckAllServiceStatusUsecase({
      required ElectrumConnectivityPort electrumConnectivityPort,
      required BoltzSwapRepository mainnetBoltzSwapRepository,
      required BoltzSwapRepository testnetBoltzSwapRepository,
      required ExchangeRateRepository exchangeRateRepository,
      required PayjoinRepository payjoinRepository,
      required FeesRepository feesRepository,
    }) : _electrumConnectivityPort = electrumConnectivityPort,
         _mainnetBoltzSwapRepository = mainnetBoltzSwapRepository,
         _testnetBoltzSwapRepository = testnetBoltzSwapRepository,
         _exchangeRateRepository = exchangeRateRepository,
         _payjoinRepository = payjoinRepository,
         _feesRepository = feesRepository;
  
    Future<AllServicesStatus> execute({required Network network}) async {
      final now = DateTime.now();
  
      try {
        final results = await Future.wait([
          _checkInternetConnection(),
          _checkBitcoinElectrumServer(network),
          _checkLiquidElectrumServer(network),
          _checkBoltzService(network),
          _checkPayjoinService(),
          _checkPricerService(network),
          _checkMempoolService(network),
        ]);
  
        return AllServicesStatus(
          internetConnection: results[0],
          bitcoinElectrum: results[1],
          liquidElectrum: results[2],
          boltz: results[3],
          payjoin: results[4],
          pricer: results[5],
          mempool: results[6],
          lastChecked: now,
        );
      } catch (e) {
        log.severe('Error checking service status: $e');
        return _createUnknownStatus(now);
      }
    }
  
    Future<ServiceStatusInfo> _checkBitcoinElectrumServer(Network network) async {
      try {
        // Check Bitcoin Electrum servers
        final hasOnlineServers = await _electrumConnectivityPort
            .checkServersInUseAreOnlineForNetwork(
              network.isTestnet ? Network.bitcoinTestnet : Network.bitcoinMainnet,
            );
  
        return ServiceStatusInfo(
          status: hasOnlineServers ? ServiceStatus.online : ServiceStatus.offline,
          name: 'Bitcoin Electrum',
          lastChecked: DateTime.now(),
        );
      } catch (e) {
        return ServiceStatusInfo(
          status: ServiceStatus.offline,
          name: 'Bitcoin Electrum',
          lastChecked: DateTime.now(),
        );
      }
    }
  
    Future<ServiceStatusInfo> _checkLiquidElectrumServer(Network network) async {
      try {
        // Check Liquid Electrum servers
        final hasOnlineServers = await _electrumConnectivityPort
            .checkServersInUseAreOnlineForNetwork(
              network.isTestnet ? Network.liquidTestnet : Network.liquidMainnet,
            );
  
        return ServiceStatusInfo(
          status: hasOnlineServers ? ServiceStatus.online : ServiceStatus.offline,
  
          name: 'Liquid Electrum',
          lastChecked: DateTime.now(),
        );
      } catch (e) {
        return ServiceStatusInfo(
          status: ServiceStatus.offline,
          name: 'Liquid Electrum',
          lastChecked: DateTime.now(),
        );
      }
    }
  
    Future<ServiceStatusInfo> _checkBoltzService(Network network) async {
      try {
        // Choose the appropriate repository based on network
        final boltzRepository =
            network == Network.bitcoinMainnet
                ? _mainnetBoltzSwapRepository
                : _testnetBoltzSwapRepository;
  
        // Try to get swap limits as a way to test Boltz connectivity
        await boltzRepository.getSwapLimitsAndFees(SwapType.bitcoinToLightning);
  
        return ServiceStatusInfo(
          status: ServiceStatus.online,
          name: 'Boltz',
          lastChecked: DateTime.now(),
        );
      } catch (e) {
        return ServiceStatusInfo(
          status: ServiceStatus.offline,
          name: 'Boltz',
          lastChecked: DateTime.now(),
        );
      }
    }
  
    Future<ServiceStatusInfo> _checkPayjoinService() async {
      try {
        final isHealthy = await _payjoinRepository.checkOhttpRelayHealth();
  
        return ServiceStatusInfo(
          status: isHealthy ? ServiceStatus.online : ServiceStatus.offline,
          name: 'Payjoin',
          lastChecked: DateTime.now(),
        );
      } catch (e) {
        return ServiceStatusInfo(
          status: ServiceStatus.offline,
          name: 'Payjoin',
          lastChecked: DateTime.now(),
        );
      }
    }
  
    Future<ServiceStatusInfo> _checkPricerService(Network network) async {
      try {
        // Test with a small amount to check if the pricer is working
        final price = await _exchangeRateRepository.getCurrencyValue(
          amountSat: BigInt.from(100000000), // 1 BTC in sats
          currency: 'USD',
        );
  
        return ServiceStatusInfo(
          status: price > 0 ? ServiceStatus.online : ServiceStatus.offline,
          name: 'Pricer',
          lastChecked: DateTime.now(),
        );
      } catch (e) {
        return ServiceStatusInfo(
          status: ServiceStatus.offline,
          name: 'Pricer',
          lastChecked: DateTime.now(),
        );
      }
    }
  
    Future<ServiceStatusInfo> _checkMempoolService(Network network) async {
      try {
        // Test mempool connectivity by getting fees
        await _feesRepository.getNetworkFees(network: network);
  
        return ServiceStatusInfo(
          status: ServiceStatus.online,
          name: 'Mempool',
          lastChecked: DateTime.now(),
        );
      } catch (e) {
        return ServiceStatusInfo(
          status: ServiceStatus.offline,
          name: 'Mempool',
          lastChecked: DateTime.now(),
        );
      }
    }
  
    Future<ServiceStatusInfo> _checkInternetConnection() async {
      try {
        final result = await InternetAddress.lookup('bullbitcoin.com');
        final isConnected = result.isNotEmpty && result[0].rawAddress.isNotEmpty;
  
        return ServiceStatusInfo(
          status: isConnected ? ServiceStatus.online : ServiceStatus.offline,
          name: 'Internet Connection',
          lastChecked: DateTime.now(),
        );
      } catch (e) {
        return ServiceStatusInfo(
          status: ServiceStatus.offline,
          name: 'Internet Connection',
          lastChecked: DateTime.now(),
        );
      }
    }
  
    AllServicesStatus _createUnknownStatus(DateTime now) {
      return AllServicesStatus(
        internetConnection: ServiceStatusInfo(
          status: ServiceStatus.unknown,
          name: 'Internet Connection',
          lastChecked: now,
        ),
        bitcoinElectrum: ServiceStatusInfo(
          status: ServiceStatus.unknown,
          name: 'Bitcoin Electrum',
          lastChecked: now,
        ),
        liquidElectrum: ServiceStatusInfo(
          status: ServiceStatus.unknown,
          name: 'Liquid Electrum',
          lastChecked: now,
        ),
        boltz: ServiceStatusInfo(
          status: ServiceStatus.unknown,
          name: 'Boltz',
          lastChecked: now,
        ),
        payjoin: ServiceStatusInfo(
          status: ServiceStatus.unknown,
          name: 'Payjoin',
          lastChecked: now,
        ),
        pricer: ServiceStatusInfo(
          status: ServiceStatus.unknown,
          name: 'Pricer',
          lastChecked: now,
        ),
        mempool: ServiceStatusInfo(
          status: ServiceStatus.unknown,
          name: 'Mempool',
          lastChecked: now,
        ),
        lastChecked: now,
      );
    }
  }
  