import 'dart:async';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:hive_flutter/hive_flutter.dart';
import 'package:geosector_app/core/constants/app_keys.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/core/services/data_loading_service.dart';
import 'package:geosector_app/core/services/hive_service.dart';
import 'package:geosector_app/core/services/hive_reset_state_service.dart';
import 'package:geosector_app/core/services/chat_manager.dart';
import 'package:geosector_app/chat/services/chat_info_service.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/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/presentation/widgets/loading_spin_overlay.dart';
import 'package:geosector_app/core/models/loading_state.dart';

class UserRepository extends ChangeNotifier {
  bool _isLoading = false;
  Timer? _refreshTimer;

  // Constructeur simplifié - plus d'injection d'ApiService
  UserRepository() {
    // Initialiser la session si un utilisateur est déjà connecté
    final currentUser = getCurrentUser();
    if (currentUser != null && currentUser.sessionId != null) {
      setSessionId(currentUser.sessionId);
    }
  }

  // === DÉLÉGATION AUX SERVICES ===
  UserModel? get currentUser => CurrentUserService.instance.currentUser;
  bool get isLoggedIn => CurrentUserService.instance.isLoggedIn;
  int get userRole => CurrentUserService.instance.userRole;

  // Getters délégués
  bool get isUser => CurrentUserService.instance.isUser;
  bool get isAdminAmicale => CurrentUserService.instance.isAdminAmicale;
  bool get isSuperAdmin => CurrentUserService.instance.isSuperAdmin;
  bool get canAccessAdmin => CurrentUserService.instance.canAccessAdmin;
  int? get userId => CurrentUserService.instance.userId;
  String? get userEmail => CurrentUserService.instance.userEmail;
  String? get userName => CurrentUserService.instance.userName;
  String? get userFirstName => CurrentUserService.instance.userFirstName;

  // Getters
  bool get isLoading => _isLoading;
  LoadingState get loadingState => DataLoadingService.instance.loadingState;

  // === GETTERS POUR LES BOXES DÉLÉGUÉES ===
  Box<UserModel> get _userBox => Hive.box<UserModel>(AppKeys.userBoxName);

  // Getters sécurisés pour les autres données
  List<OperationModel> get operations {
    try {
      if (Hive.isBoxOpen(AppKeys.operationsBoxName)) {
        return Hive.box<OperationModel>(AppKeys.operationsBoxName)
            .values
            .toList();
      }
      return [];
    } catch (e) {
      debugPrint('⚠️ Erreur accès operations: $e');
      return [];
    }
  }

  List<SectorModel> get sectors {
    try {
      if (Hive.isBoxOpen(AppKeys.sectorsBoxName)) {
        return Hive.box<SectorModel>(AppKeys.sectorsBoxName).values.toList();
      }
      return [];
    } catch (e) {
      debugPrint('⚠️ Erreur accès sectors: $e');
      return [];
    }
  }

  List<PassageModel> get passages {
    try {
      if (Hive.isBoxOpen(AppKeys.passagesBoxName)) {
        return Hive.box<PassageModel>(AppKeys.passagesBoxName).values.toList();
      }
      return [];
    } catch (e) {
      debugPrint('⚠️ Erreur accès passages: $e');
      return [];
    }
  }

  List<MembreModel> get membres {
    try {
      if (Hive.isBoxOpen(AppKeys.membresBoxName)) {
        return Hive.box<MembreModel>(AppKeys.membresBoxName).values.toList();
      }
      return [];
    } catch (e) {
      debugPrint('⚠️ Erreur accès membres: $e');
      return [];
    }
  }

  // === MÉTHODES PRINCIPALES ===

  /// Récupérer l'utilisateur actuellement connecté
  UserModel? getCurrentUser() {
    return CurrentUserService.instance.currentUser;
  }

  /// Retourne le rôle de l'utilisateur sous forme d'entier
  int getUserRole() {
    return CurrentUserService.instance.userRole;
  }

  /// Mettre à jour le chemin de la page actuelle pour l'utilisateur connecté
  Future<void> updateLastPath(String path) async {
    await CurrentUserService.instance.updateLastPath(path);
  }

  /// Récupérer le dernier chemin visité par l'utilisateur
  String? getLastPath() {
    return CurrentUserService.instance.getLastPath();
  }

  /// Configurer la session dans l'API
  void setSessionId(String? sessionId) {
    ApiService.instance.setSessionId(sessionId);
  }

  /// Navigation après connexion réussie
  void navigateAfterLogin(BuildContext context) {
    if (context.mounted) {
      final route = CurrentUserService.instance.getDefaultRoute();
      context.go(route);
    }
  }

  // === AUTHENTIFICATION ===

  /// Login API PHP
  Future<Map<String, dynamic>> loginAPI(String username, String password,
      {required String type}) async {
    try {
      return await ApiService.instance.login(username, password, type: type);
    } catch (e) {
      debugPrint('❌ Erreur login API: $e');
      rethrow;
    }
  }

  /// Register API PHP - Uniquement pour les administrateurs
  Future<Map<String, dynamic>> registerAPI(String email, String name,
      String amicaleName, String postalCode, String cityName) async {
    try {
      final Map<String, dynamic> data = {
        'email': email,
        'name': name,
        'amicale_name': amicaleName,
        'postal_code': postalCode,
        'city_name': cityName
      };

      final response =
          await ApiService.instance.post(AppKeys.registerEndpoint, data: data);
      return response.data;
    } catch (e) {
      debugPrint('❌ Erreur register API: $e');
      rethrow;
    }
  }

  /// Logout API PHP
  Future<void> logoutAPI() async {
    try {
      await ApiService.instance.logout();
    } catch (e) {
      debugPrint('⚠️ Erreur logout API: $e');
      rethrow;
    }
  }

  /// Méthode d'inscription (uniquement pour les administrateurs)
  Future<bool> register(String email, String password, String name,
      String amicaleName, String postalCode, String cityName) async {
    _isLoading = true;
    notifyListeners();

    try {
      debugPrint('📝 Tentative d\'inscription: $email');

      // Enregistrer l'administrateur via l'API
      final apiResult =
          await registerAPI(email, name, amicaleName, postalCode, cityName);

      // Créer l'administrateur local
      final int userId = apiResult['user_id'] is String
          ? int.parse(apiResult['user_id'])
          : apiResult['user_id'];
      final now = DateTime.now();
      final newAdmin = UserModel(
        id: userId,
        email: email,
        name: name,
        role: AppKeys.roleAdmin2,
        createdAt: now,
        lastSyncedAt: now,
        isActive: true,
        isSynced: true,
        sessionId: apiResult['session_id'],
        sessionExpiry: DateTime.parse(apiResult['session_expiry']),
      );

      // Sauvegarder dans le service
      await CurrentUserService.instance.setUser(newAdmin);

      // Configurer la session dans l'API
      setSessionId(newAdmin.sessionId);

      notifyListeners();
      debugPrint('✅ Inscription réussie');
      return true;
    } catch (e) {
      debugPrint('❌ Erreur d\'inscription: $e');
      return false;
    } finally {
      _isLoading = false;
      notifyListeners();
    }
  }

  /// Connexion simplifiée avec DataLoadingService
  Future<bool> login(String username, String password,
      {required String type}) async {
    _isLoading = true;
    notifyListeners();

    try {
      debugPrint('🔐 Tentative de connexion: $username');

      // Étape 2: Connexion à l'API (25%)
      final apiResult = await loginAPI(username, password, type: type);

      // Vérifier le statut de la réponse
      final status = apiResult['status'] as String?;
      final message = apiResult['message'] as String?;

      if (status != 'success') {
        debugPrint('❌ Connexion échouée: $message');
        return false;
      }

      // Étape 3: Traitement des données utilisateur (35%)
      debugPrint('👤 Traitement des données utilisateur...');

      if (apiResult['user'] != null &&
          apiResult['user'] is Map<String, dynamic>) {
        final user = _processUserData(apiResult['user'] as Map<String, dynamic>,
            apiResult['session_id'], apiResult['session_expiry']);

        // Sauvegarder via le service
        await CurrentUserService.instance.setUser(user);
        setSessionId(user.sessionId);

        debugPrint('✅ Utilisateur connecté: ${user.email}');
      }

      // Étape 4: Traitement de l'amicale
      if (apiResult['amicale'] != null) {
        if (apiResult['amicale'] is Map<String, dynamic>) {
          final amicale = AmicaleModel.fromJson(apiResult['amicale']);
          await CurrentAmicaleService.instance.setAmicale(amicale);
          debugPrint('✅ Amicale définie: ${amicale.name}');
        }
      }

      // Étape 5: Traitement des infos chat
      if (apiResult['chat'] != null) {
        try {
          ChatInfoService.instance.updateFromLogin(apiResult);
          debugPrint('💬 Infos chat mises à jour');
        } catch (chatError) {
          debugPrint('⚠️ Erreur traitement infos chat: $chatError');
        }
      }

      // Étape 6: Traitement de toutes les autres données via DataLoadingService
      try {
        await DataLoadingService.instance.processLoginData(apiResult);
      } catch (processingError) {
        debugPrint('❌ Erreur lors du traitement des données: $processingError');
        // On continue quand même car l'utilisateur est connecté
        debugPrint('⚠️ Connexion réussie mais avec des données partielles');
      }

      // Initialiser le chat en arrière-plan après connexion réussie
      try {
        await ChatManager.instance.initializeChat();
        debugPrint('✅ Module chat initialisé en arrière-plan');
      } catch (chatError) {
        // Ne pas bloquer la connexion si le chat échoue
        debugPrint('⚠️ Erreur initialisation chat (non bloquant): $chatError');
      }

      // Sauvegarder le timestamp de dernière sync après un login réussi
      await _saveLastSyncTimestamp(DateTime.now());

      // Démarrer le timer de refresh automatique
      _startAutoRefreshTimer();

      debugPrint('✅ Connexion réussie');
      return true;
    } catch (e) {
      debugPrint('❌ Erreur de connexion: $e');
      return false;
    } finally {
      _isLoading = false;
      notifyListeners();
    }
  }

  /// Déconnexion simplifiée avec HiveService
  Future<bool> logout(BuildContext context) async {
    _isLoading = true;
    notifyListeners();

    try {
      debugPrint('🚪 Déconnexion en cours...');
      
      // Vérifier les requêtes en attente AVANT de déconnecter
      int pendingCount = 0;
      try {
        if (Hive.isBoxOpen(AppKeys.pendingRequestsBoxName)) {
          final pendingBox = Hive.box(AppKeys.pendingRequestsBoxName);
          pendingCount = pendingBox.length;
          if (pendingCount > 0) {
            debugPrint('⏳ $pendingCount requêtes en attente trouvées');
            
            // Afficher un avertissement non bloquant
            if (context.mounted) {
              showDialog(
                context: context,
                barrierDismissible: true,
                builder: (BuildContext dialogContext) => AlertDialog(
                  title: const Row(
                    children: [
                      Icon(Icons.warning_amber, color: Colors.orange, size: 28),
                      SizedBox(width: 12),
                      Text('Données en attente'),
                    ],
                  ),
                  content: Column(
                    mainAxisSize: MainAxisSize.min,
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      Text(
                        pendingCount == 1 
                          ? '1 requête sera synchronisée lors de votre prochaine connexion.'
                          : '$pendingCount requêtes seront synchronisées lors de votre prochaine connexion.',
                        style: const TextStyle(fontSize: 16),
                      ),
                      const SizedBox(height: 12),
                      const Text(
                        'Vos données sont conservées et seront envoyées automatiquement.',
                        style: TextStyle(fontSize: 14, color: Colors.grey),
                      ),
                    ],
                  ),
                  actions: [
                    TextButton(
                      onPressed: () => Navigator.of(dialogContext).pop(),
                      child: const Text('Compris'),
                    ),
                  ],
                ),
              );
            }
          }
        }
      } catch (e) {
        debugPrint('⚠️ Impossible de vérifier les requêtes en attente: $e');
      }

      try {
        await logoutAPI();
      } catch (e) {
        debugPrint('⚠️ Erreur API logout, mais on continue: $e');
      }

      // Supprimer la session API
      setSessionId(null);

      // Arrêter le timer de refresh automatique
      _stopAutoRefreshTimer();

      // Effacer les données via les services singleton
      await CurrentUserService.instance.clearUser();
      await CurrentAmicaleService.instance.clearAmicale();

      // Arrêter le chat (stoppe les syncs)
      ChatManager.instance.dispose();

      // Réinitialiser les infos chat
      ChatInfoService.instance.reset();

      // Nettoyage des données via HiveService (préserve les utilisateurs)
      await HiveService.instance.cleanDataOnLogout();

      // Réinitialiser l'état de HiveResetStateService
      hiveResetStateService.reset();

      debugPrint('✅ Déconnexion réussie');
      return true;
    } catch (e) {
      debugPrint('❌ Erreur déconnexion: $e');
      return false;
    } finally {
      _isLoading = false;
      notifyListeners();
    }
  }


  /// Connexion avec spinner moderne (pour remplacer la barre de progression)
  Future<bool> loginWithSpinner(
      BuildContext context, String username, String password,
      {required String type}) async {
    OverlayEntry? spinOverlay;
    try {
      // Déterminer le message selon le type de connexion
      final message = type == 'admin' 
        ? 'Connexion administrateur...' 
        : 'Connexion utilisateur...';
      
      // Afficher le spinner moderne
      spinOverlay = LoadingSpinOverlayUtils.show(
        context: context,
        message: message,
        blurAmount: 10.0,
        showCard: true,
      );

      // Exécuter la connexion
      final result = await login(username, password, type: type);

      // Petit délai pour une meilleure UX
      await Future.delayed(const Duration(milliseconds: 300));

      // Fermer le spinner
      LoadingSpinOverlayUtils.hideSpecific(spinOverlay);

      return result;
    } catch (e) {
      // En cas d'erreur, supprimer l'overlay
      LoadingSpinOverlayUtils.hideSpecific(spinOverlay);
      return false;
    }
  }

  // === ACCESSEURS DÉLÉGUÉS AUX SERVICES ===

  /// Simplifier les getters d'amicale
  AmicaleModel? getCurrentUserAmicale() =>
      CurrentAmicaleService.instance.currentAmicale;

  /// Obtenir tous les utilisateurs locaux
  List<UserModel> getAllUsers() {
    return _userBox.values.toList();
  }

  /// Obtenir un utilisateur par son ID
  UserModel? getUserById(int id) {
    return _userBox.get(id);
  }

  /// Obtenir un utilisateur par son email
  UserModel? getUserByEmail(String email) {
    try {
      return _userBox.values.firstWhere(
        (user) => user.email == email,
      );
    } catch (e) {
      return null;
    }
  }

  /// Créer ou mettre à jour un utilisateur localement
  Future<UserModel> saveUser(UserModel user) async {
    await _userBox.put(user.id, user);
    notifyListeners();
    return user;
  }

  /// Supprimer un utilisateur localement
  Future<void> deleteUser(String id) async {
    await _userBox.delete(id);
  }

  /// Mettre à jour un utilisateur (pour le profil personnel et la gestion des membres)
  Future<UserModel> updateUser(UserModel updatedUser) async {
    try {
      debugPrint('🔄 Mise à jour utilisateur: ${updatedUser.email}');

      // D'ABORD essayer de synchroniser avec l'API
      try {
        // Tentative de mise à jour sur l'API (gère automatiquement le mode offline)
        final response = await ApiService.instance.put('/users/${updatedUser.id}', data: updatedUser.toJson());
        
        // Vérifier si la requête a été mise en queue (mode offline)
        if (response.data != null && response.data['queued'] == true) {
          // Mode offline : Sauvegarder localement avec isSynced = false
          final unsyncedUser = updatedUser.copyWith(
            isSynced: false,
            lastSyncedAt: null,
          );
          
          await _userBox.put(unsyncedUser.id, unsyncedUser);
          
          // Si c'est l'utilisateur connecté, mettre à jour le service
          if (currentUser?.id == unsyncedUser.id) {
            await CurrentUserService.instance.setUser(unsyncedUser);
          }
          
          debugPrint('⏳ Modification utilisateur ${updatedUser.id} mise en attente (mode hors ligne)');
          notifyListeners();
          return unsyncedUser;
        }
        
        // Mode online : succès de la mise à jour
        debugPrint('✅ Utilisateur mis à jour sur l\'API');

        // Si succès API, sauvegarder localement avec sync = true
        final syncedUser = updatedUser.copyWith(
          isSynced: true,
          lastSyncedAt: DateTime.now(),
        );

        await _userBox.put(syncedUser.id, syncedUser);

        // Si c'est l'utilisateur connecté, mettre à jour le service
        if (currentUser?.id == syncedUser.id) {
          await CurrentUserService.instance.setUser(syncedUser);
        }

        notifyListeners();
        return syncedUser;
      } catch (apiError) {
        debugPrint('❌ Erreur API lors de la mise à jour: $apiError');
        // Relancer l'erreur pour qu'elle soit gérée par l'appelant
        rethrow;
      }
    } catch (e) {
      debugPrint('❌ Erreur mise à jour utilisateur: $e');
      rethrow;
    }
  }

  // === MÉTHODES UTILITAIRES POUR LES DONNÉES ===

  /// Récupérer la dernière opération active
  OperationModel? getCurrentOperation() {
    try {
      final ops = operations;
      final activeOps = ops.where((op) => op.isActive).toList();

      if (activeOps.isEmpty) {
        return ops.isNotEmpty ? ops.last : null;
      }

      return activeOps.last;
    } catch (e) {
      debugPrint('⚠️ Erreur récupération opération courante: $e');
      return null;
    }
  }

  /// Récupérer tous les secteurs de l'utilisateur
  List<SectorModel> getUserSectors() {
    return sectors;
  }

  /// Récupérer un secteur par son ID
  SectorModel? getSectorById(int id) {
    try {
      if (Hive.isBoxOpen(AppKeys.sectorsBoxName)) {
        return Hive.box<SectorModel>(AppKeys.sectorsBoxName).get(id);
      }
      return null;
    } catch (e) {
      debugPrint('⚠️ Erreur récupération secteur: $e');
      return null;
    }
  }

  /// Récupérer toutes les amicales
  List<AmicaleModel> getAllAmicales() {
    try {
      if (Hive.isBoxOpen(AppKeys.amicaleBoxName)) {
        return Hive.box<AmicaleModel>(AppKeys.amicaleBoxName).values.toList();
      }
      return [];
    } catch (e) {
      debugPrint('⚠️ Erreur récupération amicales: $e');
      return [];
    }
  }

  /// Récupérer tous les clients (entités de type 1)
  List<AmicaleModel> getAllClients() {
    try {
      return getAllAmicales().where((amicale) => amicale.fkType == 1).toList();
    } catch (e) {
      debugPrint('⚠️ Erreur récupération clients: $e');
      return [];
    }
  }

  /// Récupérer une amicale par son ID
  AmicaleModel? getAmicaleById(int id) {
    try {
      if (Hive.isBoxOpen(AppKeys.amicaleBoxName)) {
        return Hive.box<AmicaleModel>(AppKeys.amicaleBoxName).get(id);
      }
      return null;
    } catch (e) {
      debugPrint('⚠️ Erreur récupération amicale: $e');
      return null;
    }
  }

  /// Créer ou mettre à jour une amicale localement
  Future<AmicaleModel> saveAmicale(AmicaleModel amicale) async {
    if (Hive.isBoxOpen(AppKeys.amicaleBoxName)) {
      await Hive.box<AmicaleModel>(AppKeys.amicaleBoxName)
          .put(amicale.id, amicale);
      notifyListeners();
    }
    return amicale;
  }

  // === SYNCHRONISATION ET REFRESH ===

  /// Rafraîchir la session (soft login)
  /// NOTE: Les endpoints /session/refresh/all et /session/refresh/partial ont été retirés
  /// Cette méthode maintient la session locale sans faire d'appel API
  Future<bool> refreshSession() async {
    try {
      debugPrint('🔄 Début du refresh de session...');

      // Vérifier qu'on a bien une session valide
      if (!isLoggedIn || currentUser?.sessionId == null) {
        debugPrint('⚠️ Pas de session valide pour le refresh');
        return false;
      }

      // Vérifier la connexion internet avant de faire des appels API
      final hasConnection = await ApiService.instance.hasInternetConnection();
      if (!hasConnection) {
        debugPrint('📵 Pas de connexion internet - refresh annulé');
        // On maintient la session locale mais on ne fait pas d'appel API
        return true; // Retourner true car ce n'est pas une erreur
      }

      // S'assurer que le timer de refresh automatique est démarré
      if (_refreshTimer == null || !_refreshTimer!.isActive) {
        _startAutoRefreshTimer();
      }

      // NOTE: Les endpoints de refresh ont été retirés
      // La session locale est maintenue mais aucune synchronisation avec le serveur n'est effectuée
      debugPrint('ℹ️ Refresh de session désactivé (endpoints retirés)');

      return true;
    } catch (e) {
      debugPrint('❌ Erreur générale refresh session: $e');
      return false;
    }
  }

  /// Sauvegarder le timestamp de la dernière sync
  Future<void> _saveLastSyncTimestamp(DateTime timestamp) async {
    try {
      if (Hive.isBoxOpen(AppKeys.settingsBoxName)) {
        final settingsBox = Hive.box(AppKeys.settingsBoxName);
        await settingsBox.put('last_sync', timestamp.toIso8601String());
        debugPrint('💾 Timestamp last_sync sauvegardé: ${timestamp.toIso8601String()}');
      }
    } catch (e) {
      debugPrint('❌ Erreur sauvegarde last_sync: $e');
    }
  }


  // === TIMER DE REFRESH AUTOMATIQUE ===

  /// Démarre le timer de refresh automatique (toutes les 30 minutes)
  void _startAutoRefreshTimer() {
    // Arrêter le timer existant s'il y en a un
    _stopAutoRefreshTimer();

    // Démarrer un nouveau timer qui se déclenche toutes les 30 minutes
    _refreshTimer = Timer.periodic(const Duration(minutes: 30), (timer) async {
      if (isLoggedIn) {
        debugPrint('⏰ Refresh automatique déclenché (30 minutes)');

        // Vérifier la connexion avant de tenter le refresh
        final hasConnection = await ApiService.instance.hasInternetConnection();
        if (!hasConnection) {
          debugPrint('📵 Refresh automatique annulé - pas de connexion');
          return;
        }

        // Appel silencieux du refresh - on ne veut pas spammer les logs
        try {
          await refreshSession();
        } catch (e) {
          // Si c'est une erreur 404, on ignore silencieusement
          if (e.toString().toLowerCase().contains('404')) {
            debugPrint('ℹ️ Refresh automatique ignoré (routes non disponibles)');
          } else {
            debugPrint('⚠️ Erreur refresh automatique: $e');
          }
        }
      } else {
        // Si l'utilisateur n'est plus connecté, arrêter le timer
        _stopAutoRefreshTimer();
      }
    });

    debugPrint('⏰ Timer de refresh automatique démarré (interval: 30 minutes)');
  }

  /// Arrête le timer de refresh automatique
  void _stopAutoRefreshTimer() {
    if (_refreshTimer != null && _refreshTimer!.isActive) {
      _refreshTimer!.cancel();
      _refreshTimer = null;
      debugPrint('⏰ Timer de refresh automatique arrêté');
    }
  }

  /// Déclenche manuellement un refresh (peut être appelé depuis l'UI)
  Future<void> triggerManualRefresh() async {
    debugPrint('🔄 Refresh manuel déclenché par l\'utilisateur');
    await refreshSession();
  }

  @override
  void dispose() {
    _stopAutoRefreshTimer();
    super.dispose();
  }

  // === SYNCHRONISATION ===

  /// Synchroniser un utilisateur spécifique avec le serveur
  Future<UserModel> syncUser(UserModel user) async {
    try {
      final hasConnection = await ApiService.instance.hasInternetConnection();

      if (!hasConnection) {
        return user;
      }

      UserModel syncedUser;

      if (!user.isSynced) {
        syncedUser = await ApiService.instance.createUser(user);
      } else {
        syncedUser = await ApiService.instance.updateUser(user);
      }

      final updatedUser = syncedUser.copyWith(
        isSynced: true,
        lastSyncedAt: DateTime.now(),
      );

      await _userBox.put(updatedUser.id, updatedUser);
      return updatedUser;
    } catch (e) {
      return user;
    }
  }

  /// Synchroniser tous les utilisateurs non synchronisés
  Future<void> syncAllUsers() async {
    try {
      final hasConnection = await ApiService.instance.hasInternetConnection();

      if (!hasConnection) {
        return;
      }

      final unsyncedUsers =
          _userBox.values.where((user) => !user.isSynced).toList();

      if (unsyncedUsers.isEmpty) {
        return;
      }

      final result = await ApiService.instance.syncData(users: unsyncedUsers);

      if (result['users'] != null) {
        for (final userData in result['users']) {
          final syncedUser = UserModel.fromJson(userData);
          await _userBox.put(
            syncedUser.id,
            syncedUser.copyWith(
              isSynced: true,
              lastSyncedAt: DateTime.now(),
            ),
          );
        }
      }
    } catch (e) {
      debugPrint('❌ Erreur de synchronisation des utilisateurs: $e');
    }
  }

  /// Rafraîchir les données depuis le serveur
  Future<void> refreshFromServer() async {
    try {
      final hasConnection = await ApiService.instance.hasInternetConnection();

      if (!hasConnection) {
        return;
      }

      final serverUsers = await ApiService.instance.getUsers();

      for (final serverUser in serverUsers) {
        final updatedUser = serverUser.copyWith(
          isSynced: true,
          lastSyncedAt: DateTime.now(),
        );
        await _userBox.put(updatedUser.id, updatedUser);
      }
    } catch (e) {
      debugPrint('❌ Erreur lors du rafraîchissement: $e');
    }
  }

  // === TRAITEMENT DES DONNÉES UTILISATEUR ===

  /// Méthode pour traiter les données utilisateur reçues de l'API
  UserModel _processUserData(
      Map<String, dynamic> userData, String? sessionId, String? sessionExpiry) {
    debugPrint('👤 Traitement des données utilisateur: ${userData.toString()}');

    // Convertir l'ID en int
    final dynamic rawId = userData['id'];
    final int id = rawId is String ? int.parse(rawId) : rawId as int;

    // Convertir le rôle en int
    final dynamic rawRole = userData['fk_role'];
    int role;
    if (rawRole is String) {
      role = int.tryParse(rawRole) ?? 1;
    } else if (rawRole is int) {
      role = rawRole;
    } else {
      role = 1;
    }

    // Convertir fk_entite en int si présent
    final dynamic rawFkEntite = userData['fk_entite'];
    final int? fkEntite = rawFkEntite != null
        ? (rawFkEntite is String ? int.parse(rawFkEntite) : rawFkEntite as int)
        : null;

    // Convertir fk_titre en int si présent
    final dynamic rawFkTitre = userData['fk_titre'];
    final int? fkTitre = rawFkTitre != null
        ? (rawFkTitre is String ? int.parse(rawFkTitre) : rawFkTitre as int)
        : null;

    // Traiter les dates si présentes
    DateTime? dateNaissance;
    if (userData['date_naissance'] != null &&
        userData['date_naissance'] != '') {
      try {
        dateNaissance = DateTime.parse(userData['date_naissance']);
      } catch (e) {
        dateNaissance = null;
      }
    }

    DateTime? dateEmbauche;
    if (userData['date_embauche'] != null && userData['date_embauche'] != '') {
      try {
        dateEmbauche = DateTime.parse(userData['date_embauche']);
      } catch (e) {
        dateEmbauche = null;
      }
    }

    // Convertir ope_user_id en int si présent
    final dynamic rawOpeUserId = userData['ope_user_id'];
    final int? opeUserId = rawOpeUserId != null
        ? (rawOpeUserId is String ? int.parse(rawOpeUserId) : rawOpeUserId as int)
        : null;

    debugPrint(
        '✅ Données traitées - id: $id, role: $role, fkEntite: $fkEntite, opeUserId: $opeUserId');

    // Créer un utilisateur avec toutes les données disponibles
    return UserModel(
      id: id,
      email: userData['email'] ?? '',
      name: userData['name'],
      username: userData['username'],
      firstName: userData['first_name'],
      role: role,
      createdAt: DateTime.now(),
      lastSyncedAt: DateTime.now(),
      isActive: true,
      isSynced: true,
      sessionId: sessionId,
      sessionExpiry:
          sessionExpiry != null ? DateTime.parse(sessionExpiry) : null,
      sectName: userData['sect_name'],
      fkEntite: fkEntite,
      fkTitre: fkTitre,
      phone: userData['phone'],
      mobile: userData['mobile'],
      dateNaissance: dateNaissance,
      dateEmbauche: dateEmbauche,
      opeUserId: opeUserId,
    );
  }
}
