import 'dart:async';
import 'dart:io';

import 'package:connectivity_plus/connectivity_plus.dart';

class CheckInternet {
  CheckInternet._();

  static final _instance = CheckInternet._();

  static CheckInternet get instance => _instance;

  final _connectivity = Connectivity();

  final StreamController<bool> _controller = StreamController.broadcast();

  Stream<bool> get myStream => _controller.stream;

  void initialise() async {
    ConnectivityResult result = await _connectivity.checkConnectivity();

    _checkStatus(result);

    _connectivity.onConnectivityChanged.listen((result) {
      _checkStatus(result);
    });
  }

  void _checkStatus(ConnectivityResult result) async {
    bool isOnline = false;

    try {
      isOnline = await isInternet();
    } on SocketException catch (_) {
      isOnline = false;
    }

    _controller.sink.add(isOnline);
  }

  void disposeStream() => _controller.close();

  static Future<bool> isInternet() async {
    var connectivityResult = await (Connectivity().checkConnectivity());

    try {
      final result = await InternetAddress.lookup('google.com');

      if (connectivityResult == ConnectivityResult.mobile) {
        // I am connected to a mobile network, make sure there is actually a net connection.
        if (result.isNotEmpty && result[0].rawAddress.isNotEmpty) {
          return true;
        } else {
          // Mobile data detected but no internet connection found.
          return false;
        }
      } else if (connectivityResult == ConnectivityResult.wifi) {
        // I am connected to a WIFI network, make sure there is actually a net connection.
        if (result.isNotEmpty && result[0].rawAddress.isNotEmpty) {
          return true;
        } else {
          // Wifi detected but no internet connection found.
          return false;
        }
      } else {
        // Neither mobile data or WIFI detected, not internet connection found.
        return false;
      }
    } on SocketException catch (_) {
      return false;
    }
  }
}
