import 'package:flutter/foundation.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'road_alert_models.dart'; import 'road_alert_provider_interface.dart'; import 'tomtom_road_alert_provider.dart'; import 'community_traffic_provider.dart'; import 'mock_road_alert_provider.dart'; final tomtomProviderInstance = Provider((ref) { return TomTomRoadAlertProvider(); }); final communityProviderInstance = Provider((ref) { final endpoint = ref.watch(communityEndpointUrlProvider); return CommunityTrafficRoadAlertProvider(endpointUrl: endpoint); }); final mockProviderInstance = Provider((ref) { return MockRoadAlertProvider(); }); // Master Enable class RoadAlertsEnabledNotifier extends StateNotifier { static const _key = 'road_alerts_enabled'; RoadAlertsEnabledNotifier() : super(true) { _load(); } Future _load() async { final prefs = await SharedPreferences.getInstance(); if (!mounted) return; state = prefs.getBool(_key) ?? true; } Future setEnabled(bool enabled) async { state = enabled; final prefs = await SharedPreferences.getInstance(); await prefs.setBool(_key, enabled); } } final roadAlertsEnabledProvider = StateNotifierProvider((ref) { return RoadAlertsEnabledNotifier(); }); // Audio Alerts Toggle class AudioAlertsEnabledNotifier extends StateNotifier { static const _key = 'audio_alerts_enabled'; AudioAlertsEnabledNotifier() : super(true) { _load(); } Future _load() async { final prefs = await SharedPreferences.getInstance(); if (!mounted) return; state = prefs.getBool(_key) ?? true; } Future setEnabled(bool enabled) async { state = enabled; final prefs = await SharedPreferences.getInstance(); await prefs.setBool(_key, enabled); } } final audioAlertsEnabledProvider = StateNotifierProvider((ref) { return AudioAlertsEnabledNotifier(); }); // Alert Radius in Meters class AlertRadiusMetersNotifier extends StateNotifier { static const _key = 'alert_radius_meters'; AlertRadiusMetersNotifier() : super(804.7) { _load(); } Future _load() async { final prefs = await SharedPreferences.getInstance(); if (!mounted) return; state = prefs.getDouble(_key) ?? 804.7; } Future setRadius(double radiusMeters) async { state = radiusMeters; final prefs = await SharedPreferences.getInstance(); await prefs.setDouble(_key, radiusMeters); } } final alertRadiusMetersProvider = StateNotifierProvider((ref) { return AlertRadiusMetersNotifier(); }); // Category Filtering Notifier class EnabledCategoriesNotifier extends StateNotifier> { EnabledCategoriesNotifier() : super({ RoadAlertCategory.police, RoadAlertCategory.speedCamera, RoadAlertCategory.accident, RoadAlertCategory.hazard, RoadAlertCategory.roadClosure, RoadAlertCategory.construction, RoadAlertCategory.traffic, RoadAlertCategory.other, }); void toggleCategory(RoadAlertCategory category, bool enabled) { final current = Set.from(state); if (enabled) { current.add(category); } else { current.remove(category); } state = current; } } final enabledCategoriesProvider = StateNotifierProvider>((ref) { return EnabledCategoriesNotifier(); }); // TomTom API Key class TomTomApiKeyNotifier extends StateNotifier { static const _key = 'tomtom_api_key'; TomTomApiKeyNotifier() : super('') { _load(); } Future _load() async { final prefs = await SharedPreferences.getInstance(); if (!mounted) return; state = prefs.getString(_key) ?? ''; } Future setApiKey(String apiKey) async { state = apiKey.trim(); final prefs = await SharedPreferences.getInstance(); await prefs.setString(_key, state); } } final tomtomApiKeyProvider = StateNotifierProvider((ref) { return TomTomApiKeyNotifier(); }); // Community Traffic API Key class CommunityApiKeyNotifier extends StateNotifier { static const _key = 'community_api_key'; static const String defaultKey = 'wz_live_RqKTtZ10oK3db9hH-ypQhD0tOTLn199q'; CommunityApiKeyNotifier() : super(defaultKey) { _load(); } Future _load() async { final prefs = await SharedPreferences.getInstance(); if (!mounted) return; state = prefs.getString(_key) ?? defaultKey; } Future setApiKey(String apiKey) async { state = apiKey.trim().isEmpty ? defaultKey : apiKey.trim(); final prefs = await SharedPreferences.getInstance(); await prefs.setString(_key, state); } } final communityApiKeyProvider = StateNotifierProvider((ref) { return CommunityApiKeyNotifier(); }); // Custom Community Endpoint URL class CommunityEndpointUrlNotifier extends StateNotifier { static const _key = 'community_endpoint_url'; CommunityEndpointUrlNotifier() : super('') { _load(); } Future _load() async { final prefs = await SharedPreferences.getInstance(); if (!mounted) return; state = prefs.getString(_key) ?? ''; } Future setEndpoint(String url) async { state = url.trim(); final prefs = await SharedPreferences.getInstance(); await prefs.setString(_key, state); } } final communityEndpointUrlProvider = StateNotifierProvider((ref) { return CommunityEndpointUrlNotifier(); }); final tomtomStatusProvider = StateProvider((ref) { final key = ref.watch(tomtomApiKeyProvider); return key.isEmpty ? RoadAlertProviderStatus.notConfigured : RoadAlertProviderStatus.configured; }); final communityStatusProvider = StateProvider((ref) { final key = ref.watch(communityApiKeyProvider); return key.isEmpty ? RoadAlertProviderStatus.notConfigured : RoadAlertProviderStatus.configured; }); // Active Providers List final activeRoadAlertProviders = Provider>((ref) { final tomtomKey = ref.watch(tomtomApiKeyProvider); final communityKey = ref.watch(communityApiKeyProvider); final list = []; if (tomtomKey.isNotEmpty) { list.add(ref.watch(tomtomProviderInstance)); } if (communityKey.isNotEmpty) { list.add(ref.watch(communityProviderInstance)); } // Include Debug Mock Provider only in debug mode if (kDebugMode) { list.add(ref.watch(mockProviderInstance)); } return list; });