import 'package:flutter/foundation.dart';
import 'package:latlong2/latlong.dart';
import '../services/location_service.dart';
enum AppLocationStatus {
idle,
loading,
ready,
unavailable,
}
class LocationStore extends ChangeNotifier {
LocationStore({LocationService service = const LocationService()})
: _service = service;
final LocationService _service;
LatLng? _position;
AppLocationStatus _status = AppLocationStatus.idle;
DateTime? _updatedAt;
Future<void>? _refreshFuture;
LatLng? get position => _position;
AppLocationStatus get status => _status;
DateTime? get updatedAt => _updatedAt;
bool get hasLocation => _position != null;
bool get isLoading => _status == AppLocationStatus.loading;
Future<void> initialize() => refresh();
Future<void> refresh() {
if (_refreshFuture != null) return _refreshFuture!;
_refreshFuture = _performRefresh();
return _refreshFuture!;
}
Future<void> _performRefresh() async {
_status = AppLocationStatus.loading;
notifyListeners();
try {
final position = await _service.currentPosition();
if (position == null) {
_status = AppLocationStatus.unavailable;
} else {
_position = position;
_updatedAt = DateTime.now();
_status = AppLocationStatus.ready;
}
} catch (_) {
_status = AppLocationStatus.unavailable;
} finally {
_refreshFuture = null;
notifyListeners();
}
}
static bool isUsableTarget(double latitude, double longitude) {
if (!latitude.isFinite || !longitude.isFinite) return false;
if (latitude == 0 && longitude == 0) return false;
// MeinWeimar launch content: Weimar, Ettersberg and close surroundings.
return latitude >= 50.88 &&
latitude <= 51.10 &&
longitude >= 11.10 &&
longitude <= 11.55;
}
int? distanceMetersTo(double latitude, double longitude) {
final from = _position;
if (from == null || !isUsableTarget(latitude, longitude)) return null;
const distance = Distance();
return distance
.as(
LengthUnit.Meter,
from,
LatLng(latitude, longitude),
)
.round();
}
int? walkingMinutesTo(double latitude, double longitude) {
final meters = distanceMetersTo(latitude, longitude);
if (meters == null) return null;
// Overview estimate only. Real navigation uses pedestrian routing.
return (meters / 75).ceil().clamp(1, 999);
}
}

