import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter/foundation.dart' show kIsWeb; import 'package:flutter_web_plugins/url_strategy.dart'; import 'package:geosector_app/core/services/app_info_service.dart'; import 'package:geosector_app/core/services/api_service.dart'; import 'package:geosector_app/core/services/current_user_service.dart'; import 'package:geosector_app/core/services/current_amicale_service.dart'; import 'package:geosector_app/app.dart'; import 'package:hive_flutter/hive_flutter.dart'; import 'package:geosector_app/core/data/models/user_model.dart'; import 'package:geosector_app/core/data/models/amicale_model.dart'; import 'package:geosector_app/core/data/models/client_model.dart'; import 'package:geosector_app/core/data/models/operation_model.dart'; import 'package:geosector_app/core/data/models/sector_model.dart'; import 'package:geosector_app/core/data/models/passage_model.dart'; import 'package:geosector_app/core/data/models/membre_model.dart'; import 'package:geosector_app/core/data/models/user_sector_model.dart'; import 'package:geosector_app/core/data/models/region_model.dart'; import 'package:geosector_app/core/constants/app_keys.dart'; import 'package:geosector_app/core/services/hive_reset_state_service.dart'; import 'package:geosector_app/chat/models/chat_adapters.dart'; void main() async { // IMPORTANT: Configurer l'URL strategy pour éviter les # dans les URLs usePathUrlStrategy(); WidgetsFlutterBinding.ensureInitialized(); // Initialiser les services essentiels await _initializeServices(); // Initialiser Hive avec gestion des erreurs final hiveInitialized = await _initializeHive(); // TEMPORAIREMENT: Ne pas marquer l'erreur pour éviter la redirection // if (!hiveInitialized) { // debugPrint('Incompatibilité détectée dans les données Hive. Marquage pour affichage du dialogue...'); // hiveResetStateService.markAsReset(); // } // Configurer l'orientation de l'application (mobile uniquement) if (!kIsWeb) { await SystemChrome.setPreferredOrientations([ DeviceOrientation.portraitUp, DeviceOrientation.portraitDown, ]); } // Lancer l'application runApp(const GeosectorApp()); } /// Initialise les services essentiels Future _initializeServices() async { try { // Initialiser ApiService en premier await ApiService.initialize(); debugPrint('✅ ApiService singleton initialisé'); // Les services CurrentUserService et CurrentAmicaleService s'initialisent automatiquement // au premier accès via le pattern singleton lazy debugPrint('✅ CurrentUserService prêt'); debugPrint('✅ CurrentAmicaleService prêt'); await AppInfoService.initialize(); debugPrint('✅ Tous les services initialisés avec succès'); } catch (e) { debugPrint('❌ Erreur lors de l\'initialisation des services: $e'); rethrow; // Important pour arrêter l'app si les services critiques échouent } } /// Initialise Hive et les adaptateurs Future _initializeHive() async { try { // Initialiser Hive await Hive.initFlutter(); // Enregistrer les adaptateurs Hive pour les modèles principaux _registerHiveAdapters(); // Ouvrir uniquement les boîtes essentielles au démarrage await _openEssentialHiveBoxes(); // Charger les données depuis Hive au démarrage await CurrentUserService.instance.loadFromHive(); await CurrentAmicaleService.instance.loadFromHive(); debugPrint('✅ Données utilisateur/amicale chargées depuis Hive'); debugPrint('Hive initialisé avec succès'); return true; } catch (e) { debugPrint('Erreur lors de l\'initialisation de Hive: $e'); return false; } } /// Enregistre tous les adaptateurs Hive void _registerHiveAdapters() { // Vérifier si les adaptateurs sont déjà enregistrés pour éviter les doublons if (!Hive.isAdapterRegistered(0)) { Hive.registerAdapter(UserModelAdapter()); } if (!Hive.isAdapterRegistered(1)) { Hive.registerAdapter(AmicaleModelAdapter()); } if (!Hive.isAdapterRegistered(2)) { Hive.registerAdapter(ClientModelAdapter()); } if (!Hive.isAdapterRegistered(3)) { Hive.registerAdapter(OperationModelAdapter()); } if (!Hive.isAdapterRegistered(4)) { Hive.registerAdapter(SectorModelAdapter()); } if (!Hive.isAdapterRegistered(5)) { Hive.registerAdapter(PassageModelAdapter()); } if (!Hive.isAdapterRegistered(6)) { Hive.registerAdapter(MembreModelAdapter()); } if (!Hive.isAdapterRegistered(7)) { Hive.registerAdapter(UserSectorModelAdapter()); } if (!Hive.isAdapterRegistered(8)) { Hive.registerAdapter(RegionModelAdapter()); } // Modèles de chat if (!Hive.isAdapterRegistered(9)) { Hive.registerAdapter(ConversationModelAdapter()); } if (!Hive.isAdapterRegistered(10)) { Hive.registerAdapter(MessageModelAdapter()); } if (!Hive.isAdapterRegistered(11)) { Hive.registerAdapter(ParticipantModelAdapter()); } if (!Hive.isAdapterRegistered(12)) { Hive.registerAdapter(AnonymousUserModelAdapter()); } if (!Hive.isAdapterRegistered(13)) { Hive.registerAdapter(AudienceTargetModelAdapter()); } if (!Hive.isAdapterRegistered(14)) { Hive.registerAdapter(NotificationSettingsAdapter()); } } /// Ouvre les boîtes Hive essentielles avec migration users -> user Future _openEssentialHiveBoxes() async { final boxesToOpen = [ {'name': AppKeys.userBoxName, 'type': 'UserModel'}, {'name': AppKeys.amicaleBoxName, 'type': 'AmicaleModel'}, {'name': AppKeys.clientsBoxName, 'type': 'ClientModel'}, {'name': AppKeys.settingsBoxName, 'type': 'dynamic'}, {'name': AppKeys.chatConversationsBoxName, 'type': 'ConversationModel'}, {'name': AppKeys.chatMessagesBoxName, 'type': 'MessageModel'}, ]; // Logique de migration de l'ancienne box users vers user try { // Vérifier si l'ancienne box users existe if (await _doesBoxExist(AppKeys.usersBoxNameOld)) { debugPrint('🔄 Migration détectée: box users -> user'); // Ouvrir l'ancienne box final oldBox = await Hive.openBox(AppKeys.usersBoxNameOld); // Ouvrir la nouvelle box final newBox = await Hive.openBox(AppKeys.userBoxName); // Migrer les données si la nouvelle box est vide if (oldBox.isNotEmpty && newBox.isEmpty) { debugPrint('📦 Migration des données users -> user...'); // Chercher l'utilisateur actuel dans l'ancienne box final userData = oldBox.get('current_user') ?? oldBox.values.firstOrNull; if (userData != null) { await newBox.put('current_user', userData); debugPrint('✅ Migration de users -> user réussie pour ${userData.email}'); } } // Fermer et supprimer l'ancienne box await oldBox.close(); await Hive.deleteBoxFromDisk(AppKeys.usersBoxNameOld); debugPrint('🗑️ Ancienne box users supprimée'); } else { // Ouvrir normalement la nouvelle box await Hive.openBox(AppKeys.userBoxName); } } catch (e) { debugPrint('⚠️ Erreur migration box users: $e'); // En cas d'erreur, ouvrir quand même la nouvelle box try { await Hive.openBox(AppKeys.userBoxName); } catch (e2) { debugPrint('❌ Impossible d\'ouvrir la box user: $e2'); } } // Ouvrir les autres boîtes for (final box in boxesToOpen) { try { final boxName = box['name'] as String; final boxType = box['type'] as String; // Skip userBoxName car déjà traité dans la migration if (boxName == AppKeys.userBoxName) continue; // Vérifier si la boîte est déjà ouverte if (Hive.isBoxOpen(boxName)) { debugPrint('📦 Boîte $boxName déjà ouverte'); continue; } switch (boxType) { case 'AmicaleModel': await Hive.openBox(boxName); break; case 'ClientModel': await Hive.openBox(boxName); break; case 'ConversationModel': await Hive.openBox(boxName); break; case 'MessageModel': await Hive.openBox(boxName); break; default: await Hive.openBox(boxName); } debugPrint('✅ Boîte $boxName ouverte avec succès'); } catch (e) { debugPrint('❌ Erreur lors de l\'ouverture de la boîte ${box['name']}: $e'); // Ne pas lancer d'erreur, continuer avec les autres boîtes } } } /// Vérifie si une box Hive existe sur le disque Future _doesBoxExist(String boxName) async { try { // Tentative d'ouverture pour vérifier l'existence final box = await Hive.openBox(boxName); final exists = box.isNotEmpty; await box.close(); return exists; } catch (e) { return false; } }