import 'dart:developer';

import 'package:geolocator/geolocator.dart';

class GeofencingService {
  Future<GeolocationStatus> requestGeolocationPermission() async {
    LocationPermission permission;

    permission = await Geolocator.checkPermission();
    if (permission == LocationPermission.denied) {
      permission = await Geolocator.requestPermission();
      if (permission == LocationPermission.denied) {
        return GeolocationStatus.denied;
      }
    }


    if (permission == LocationPermission.deniedForever){
      return GeolocationStatus.prohibited;
    }
    if (!(await Geolocator.isLocationServiceEnabled())) {
      // Location services are not enabled
      return GeolocationStatus.disabled;
    }
    return GeolocationStatus.enabled;
  }

  bool _isInRange(
      Position currentPosition,
      double pointLat,
      double pointLon,
      int range,
      ) {
    double distance = Geolocator.distanceBetween(
      currentPosition.latitude,
      currentPosition.longitude,
      pointLat,
      pointLon,
    );

    return distance <= range;
  }

  /// Checks if the user's current location is within [range] meters
  /// of the given [pointLatitude] and [pointLongitude].
  Future<bool> isInRangeCheck({
    required double pointLatitude,
    required double pointLongitude,
    int range = 500,
  }) async {
    try {
      Position position = await Geolocator.getCurrentPosition();

      return _isInRange(position, pointLatitude, pointLongitude, range);
    } catch (except) {
      log('Error getting location: $except');
      return false;
    }
  }

  /// Constantly checks if the user's current location is within [range] meters
  /// of the given [pointLatitude] and [pointLongitude].
  Stream<bool> isInRangeStream({
    required double pointLatitude,
    required double pointLongitude,
    int range = 500,
  }) async* {
    await for (final position in Geolocator.getPositionStream()) {
      try {
        yield _isInRange(position, pointLatitude, pointLongitude, range);
      } catch (except) {
        log('Error getting location: $except');
        yield false;
      }
    }
  }
}

/// [disabled] indicates that the user should enable geolocation on the device.
/// [denied] indicates that permission should be requested or re-requested.
/// [prohibited] indicates that permission is denied and can only be changed
/// via the Settings.
/// [enabled] - geolocation service is allowed and available for usage.
enum GeolocationStatus {
  disabled,
  denied,
  prohibited,
  enabled,
}