import 'package:geolocator/geolocator.dart'; import '../../../models/home_config.dart'; import '../geofence_logic.dart'; import 'geofence_runtime_state.dart'; enum GeofenceStatusKind { noActiveHome, disabled, missingCoordinates, locationServicesDisabled, locationPermissionDenied, backgroundPermissionDenied, notificationsPermissionDenied, cooldown, triggered, ready, } class GeofenceDiagnostics { final HomeConfig? activeHome; final GeofenceStatusKind status; final GeofenceRuntimeState runtime; final bool locationServicesEnabled; final LocationPermission locationPermission; final bool notificationsEnabled; final Duration? retryRemaining; final String? detail; const GeofenceDiagnostics({ required this.activeHome, required this.status, required this.runtime, required this.locationServicesEnabled, required this.locationPermission, required this.notificationsEnabled, this.retryRemaining, this.detail, }); const GeofenceDiagnostics.initial() : activeHome = null, status = GeofenceStatusKind.noActiveHome, runtime = const GeofenceRuntimeState(), locationServicesEnabled = true, locationPermission = LocationPermission.denied, notificationsEnabled = true, retryRemaining = null, detail = null; String get title { return switch (status) { GeofenceStatusKind.noActiveHome => 'Геофенс не активен', GeofenceStatusKind.disabled => 'Автовыключение выключено', GeofenceStatusKind.missingCoordinates => 'Нет координат дома', GeofenceStatusKind.locationServicesDisabled => 'Геолокация выключена', GeofenceStatusKind.locationPermissionDenied => 'Нет доступа к геолокации', GeofenceStatusKind.backgroundPermissionDenied => 'Нет фонового доступа к геолокации', GeofenceStatusKind.notificationsPermissionDenied => 'Нет доступа к уведомлениям', GeofenceStatusKind.cooldown => 'Повтор отложен', GeofenceStatusKind.triggered => 'Геофенс уже сработал', GeofenceStatusKind.ready => 'Геофенс активен', }; } String get message { final homeName = activeHome?.name ?? 'активного дома'; return switch (status) { GeofenceStatusKind.noActiveHome => 'Сначала выберите активный дом. Без этого фоновой автоматике нечего отслеживать.', GeofenceStatusKind.disabled => 'Для дома "$homeName" автовыключение пока отключено.', GeofenceStatusKind.missingCoordinates => 'У дома "$homeName" не заданы координаты. Без них расстояние считать не из чего.', GeofenceStatusKind.locationServicesDisabled => 'На устройстве выключена геолокация. И карта расстояний, и фоновый geofence сейчас слепые как кроты.', GeofenceStatusKind.locationPermissionDenied => 'Приложению не дали доступ к геолокации. Разрешите доступ хотя бы во время использования.', GeofenceStatusKind.backgroundPermissionDenied => 'Для фонового geofence нужен доступ к локации "Всегда". Иначе в фоне Android эту магию задушит.', GeofenceStatusKind.notificationsPermissionDenied => 'Свет выключить мы ещё попробуем, но честно отчитаться пользователю не сможем, пока уведомления запрещены.', GeofenceStatusKind.cooldown => 'Последняя попытка выключить свет сорвалась. Повторим позже, чтобы не долбить backend без остановки.', GeofenceStatusKind.triggered => 'Свет уже был автоматически выключен. Повторно бахать не будем, пока вы не вернётесь в домашний радиус.', GeofenceStatusKind.ready => 'Фоновая автоматика готова следить за домом "$homeName" и выключить свет после ухода.', }; } String? get secondaryMessage { if (status == GeofenceStatusKind.cooldown && retryRemaining != null) { return 'Повтор через ${formatGeofenceRetry(retryRemaining!)}.'; } if (status == GeofenceStatusKind.triggered && runtime.lastSuccessAt != null && runtime.lastSuccessHomeId == activeHome?.id) { return 'Последнее успешное срабатывание уже зафиксировано.'; } if (detail != null && detail!.trim().isNotEmpty) { return detail; } return null; } bool get canRequestLocation => status == GeofenceStatusKind.locationPermissionDenied; bool get canRequestBackgroundLocation => status == GeofenceStatusKind.backgroundPermissionDenied; bool get canOpenLocationSettings => status == GeofenceStatusKind.locationServicesDisabled; bool get canRequestNotifications => status == GeofenceStatusKind.notificationsPermissionDenied; }