import 'package:flutter/material.dart'; import 'package:flutter/scheduler.dart'; import 'package:hive_flutter/hive_flutter.dart'; import 'package:geosector_app/core/constants/app_keys.dart'; /// Service pour gérer les préférences de thème de l'application /// Supporte la détection automatique du mode sombre/clair du système /// Utilise Hive pour la persistance au lieu de SharedPreferences class ThemeService extends ChangeNotifier { static ThemeService? _instance; static ThemeService get instance => _instance ??= ThemeService._(); ThemeService._() { _init(); } // Mode de thème actuel ThemeMode _themeMode = ThemeMode.system; // Clé pour stocker les préférences dans Hive static const String _themeModeKey = 'theme_mode'; /// Mode de thème actuel ThemeMode get themeMode => _themeMode; /// Détecte si le système est en mode sombre bool get isSystemDark { final brightness = SchedulerBinding.instance.platformDispatcher.platformBrightness; return brightness == Brightness.dark; } /// Détermine si l'app doit utiliser le mode sombre bool get isDarkMode { switch (_themeMode) { case ThemeMode.light: return false; case ThemeMode.dark: return true; case ThemeMode.system: return isSystemDark; } } /// Initialise le service Future _init() async { try { await _loadThemeMode(); // Observer les changements du système SchedulerBinding.instance.platformDispatcher.onPlatformBrightnessChanged = () { _onSystemBrightnessChanged(); }; debugPrint('🎨 ThemeService initialisé - Mode: $_themeMode, Système sombre: $isSystemDark'); } catch (e) { debugPrint('❌ Erreur initialisation ThemeService: $e'); } } /// Charge le mode de thème depuis Hive Future _loadThemeMode() async { try { // Vérifier si la box settings est ouverte if (!Hive.isBoxOpen(AppKeys.settingsBoxName)) { debugPrint('⚠️ Box settings pas encore ouverte, utilisation du mode système par défaut'); _themeMode = ThemeMode.system; return; } final settingsBox = Hive.box(AppKeys.settingsBoxName); final savedMode = settingsBox.get(_themeModeKey) as String?; if (savedMode != null) { _themeMode = ThemeMode.values.firstWhere( (mode) => mode.name == savedMode, orElse: () => ThemeMode.system, ); debugPrint('🎨 Mode de thème chargé depuis Hive: $_themeMode'); } else { debugPrint('🎨 Aucun mode de thème sauvegardé, utilisation du mode système'); } } catch (e) { debugPrint('❌ Erreur chargement thème: $e'); _themeMode = ThemeMode.system; } } /// Sauvegarde le mode de thème dans Hive Future _saveThemeMode() async { try { // Vérifier si la box settings est ouverte if (!Hive.isBoxOpen(AppKeys.settingsBoxName)) { debugPrint('⚠️ Box settings pas ouverte, impossible de sauvegarder le thème'); return; } final settingsBox = Hive.box(AppKeys.settingsBoxName); await settingsBox.put(_themeModeKey, _themeMode.name); debugPrint('💾 Mode de thème sauvegardé dans Hive: $_themeMode'); } catch (e) { debugPrint('❌ Erreur sauvegarde thème: $e'); } } /// Appelée quand la luminosité du système change void _onSystemBrightnessChanged() { if (_themeMode == ThemeMode.system) { debugPrint('🌗 Changement luminosité système détecté - Sombre: $isSystemDark'); notifyListeners(); } } /// Change le mode de thème Future setThemeMode(ThemeMode mode) async { if (_themeMode != mode) { _themeMode = mode; await _saveThemeMode(); notifyListeners(); debugPrint('🎨 Mode de thème changé: $mode'); } } /// Basculer entre clair et sombre Future toggleTheme() async { switch (_themeMode) { case ThemeMode.light: await setThemeMode(ThemeMode.dark); break; case ThemeMode.dark: await setThemeMode(ThemeMode.light); break; case ThemeMode.system: // Si système, basculer vers l'opposé du mode actuel du système await setThemeMode(isSystemDark ? ThemeMode.light : ThemeMode.dark); break; } } /// Retourner au mode système Future useSystemTheme() async { await setThemeMode(ThemeMode.system); } /// Forcer le mode clair Future useLightTheme() async { await setThemeMode(ThemeMode.light); } /// Forcer le mode sombre Future useDarkTheme() async { await setThemeMode(ThemeMode.dark); } /// Obtenir une description textuelle du mode actuel String get themeModeDescription { switch (_themeMode) { case ThemeMode.light: return 'Clair'; case ThemeMode.dark: return 'Sombre'; case ThemeMode.system: return 'Automatique (${isSystemDark ? 'sombre' : 'clair'})'; } } /// Obtenir l'icône appropriée pour le mode actuel IconData get themeModeIcon { switch (_themeMode) { case ThemeMode.light: return Icons.light_mode; case ThemeMode.dark: return Icons.dark_mode; case ThemeMode.system: return Icons.brightness_auto; } } /// Recharge le thème depuis Hive (utile après l'ouverture des boxes) Future reloadFromHive() async { await _loadThemeMode(); notifyListeners(); debugPrint('🔄 ThemeService rechargé depuis Hive'); } /// Réinitialise le service au mode système void reset() { _themeMode = ThemeMode.system; notifyListeners(); debugPrint('🔄 ThemeService réinitialisé'); } }