import 'package:get/get.dart';
import 'package:youmazgestion/Services/stock_managementDatabase.dart';

class PermissionCacheService extends GetxController {
  static final PermissionCacheService instance = PermissionCacheService._init();
  PermissionCacheService._init();

  // Cache en mémoire optimisé
  final Map<String, Map<String, bool>> _permissionCache = {};
  final Map<String, List<Map<String, dynamic>>> _menuCache = {};
  bool _isLoaded = false;
  String _currentUsername = '';

  /// ✅ OPTIMISÉ: Une seule requête complexe pour charger tout
  Future<void> loadUserPermissions(String username) async {
    if (_isLoaded && _currentUsername == username && _permissionCache.containsKey(username)) {
      print("📋 Permissions déjà en cache pour: $username");
      return;
    }

    print("🔄 Chargement OPTIMISÉ des permissions pour: $username");
    final stopwatch = Stopwatch()..start();
    
    try {
      final db = AppDatabase.instance;
      
      // 🚀 UNE SEULE REQUÊTE pour tout récupérer
      final userPermissions = await _getUserPermissionsOptimized(db, username);
      
      // Organiser les données
      Map<String, bool> permissions = {};
      Set<Map<String, dynamic>> accessibleMenus = {};
      
      for (var row in userPermissions) {
        final menuId = row['menu_id'] as int;
        final menuName = row['menu_name'] as String;
        final menuRoute = row['menu_route'] as String;
        final permissionName = row['permission_name'] as String;
        
        // Ajouter la permission
        final key = "${permissionName}_$menuRoute";
        permissions[key] = true;
        
        // Ajouter le menu aux accessibles
        accessibleMenus.add({
          'id': menuId,
          'name': menuName,
          'route': menuRoute,
        });
      }
      
      // Mettre en cache
      _permissionCache[username] = permissions;
      _menuCache[username] = accessibleMenus.toList();
      _currentUsername = username;
      _isLoaded = true;
      
      stopwatch.stop();
      print("✅ Permissions chargées en ${stopwatch.elapsedMilliseconds}ms");
      print("   - ${permissions.length} permissions");
      print("   - ${accessibleMenus.length} menus accessibles");
      
    } catch (e) {
      stopwatch.stop();
      print("❌ Erreur après ${stopwatch.elapsedMilliseconds}ms: $e");
      rethrow;
    }
  }

  /// 🚀 NOUVELLE MÉTHODE: Une seule requête optimisée
  Future<List<Map<String, dynamic>>> _getUserPermissionsOptimized(
    AppDatabase db, String username) async {
    
    final connection = await db.database;
    
    final result = await connection.query('''
      SELECT DISTINCT
        m.id as menu_id,
        m.name as menu_name,
        m.route as menu_route,
        p.name as permission_name
      FROM users u
      INNER JOIN roles r ON u.role_id = r.id
      INNER JOIN role_menu_permissions rmp ON r.id = rmp.role_id
      INNER JOIN menu m ON rmp.menu_id = m.id
      INNER JOIN permissions p ON rmp.permission_id = p.id
      WHERE u.username = ?
      ORDER BY m.name, p.name
    ''', [username]);
    
    return result.map((row) => row.fields).toList();
  }

  /// ✅ Vérification rapide depuis le cache
  bool hasPermission(String username, String permissionName, String menuRoute) {
    final userPermissions = _permissionCache[username];
    if (userPermissions == null) {
      print("⚠️ Cache non initialisé pour: $username");
      return false;
    }
    
    final key = "${permissionName}_$menuRoute";
    return userPermissions[key] ?? false;
  }

  /// ✅ Récupération rapide des menus
  List<Map<String, dynamic>> getUserMenus(String username) {
    return _menuCache[username] ?? [];
  }

  /// ✅ Vérification d'accès menu
  bool hasMenuAccess(String username, String menuRoute) {
    final userMenus = _menuCache[username] ?? [];
    return userMenus.any((menu) => menu['route'] == menuRoute);
  }

  /// ✅ Préchargement asynchrone en arrière-plan
  Future<void> preloadUserDataAsync(String username) async {
    // Lancer en arrière-plan sans bloquer l'UI
    unawaited(_preloadInBackground(username));
  }

  Future<void> _preloadInBackground(String username) async {
    try {
      print("🔄 Préchargement en arrière-plan pour: $username");
      await loadUserPermissions(username);
      print("✅ Préchargement terminé");
    } catch (e) {
      print("⚠️ Erreur préchargement: $e");
    }
  }

  /// ✅ Préchargement synchrone (pour la connexion)
  Future<void> preloadUserData(String username) async {
    try {
      print("🔄 Préchargement synchrone pour: $username");
      await loadUserPermissions(username);
      print("✅ Données préchargées avec succès");
    } catch (e) {
      print("❌ Erreur lors du préchargement: $e");
      // Ne pas bloquer la connexion
    }
  }

  /// ✅ Vider le cache
  void clearAllCache() {
    _permissionCache.clear();
    _menuCache.clear();
    _isLoaded = false;
    _currentUsername = '';
    print("🗑️ Cache vidé complètement");
  }

  /// ✅ Rechargement forcé
  Future<void> refreshUserPermissions(String username) async {
    _permissionCache.remove(username);
    _menuCache.remove(username);
    _isLoaded = false;
    
    await loadUserPermissions(username);
    print("🔄 Permissions rechargées pour: $username");
  }

  /// ✅ Status du cache
  bool get isLoaded => _isLoaded && _currentUsername.isNotEmpty;
  String get currentCachedUser => _currentUsername;

  /// ✅ Statistiques
  Map<String, dynamic> getCacheStats() {
    return {
      'is_loaded': _isLoaded,
      'current_user': _currentUsername,
      'users_cached': _permissionCache.length,
      'total_permissions': _permissionCache.values
          .map((perms) => perms.length)
          .fold(0, (a, b) => a + b),
      'total_menus': _menuCache.values
          .map((menus) => menus.length)
          .fold(0, (a, b) => a + b),
    };
  }

  /// ✅ Debug amélioré
  void debugPrintCache() {
    print("=== DEBUG CACHE OPTIMISÉ ===");
    print("Chargé: $_isLoaded");
    print("Utilisateur actuel: $_currentUsername");
    print("Utilisateurs en cache: ${_permissionCache.keys.toList()}");
    
    for (var username in _permissionCache.keys) {
      final permissions = _permissionCache[username]!;
      final menus = _menuCache[username] ?? [];
      print("$username: ${permissions.length} permissions, ${menus.length} menus");
      
      // Détail des menus pour debug
      for (var menu in menus.take(3)) {
        print("  → ${menu['name']} (${menu['route']})");
      }
    }
    print("============================");
  }

  /// ✅ NOUVEAU: Validation de l'intégrité du cache
  Future<bool> validateCacheIntegrity(String username) async {
    if (!_permissionCache.containsKey(username)) {
      return false;
    }

    try {
      final db = AppDatabase.instance;
      final connection = await db.database;
      
      // Vérification rapide: compter les permissions de l'utilisateur
      final result = await connection.query('''
        SELECT COUNT(DISTINCT CONCAT(p.name, '_', m.route)) as permission_count
        FROM users u
        INNER JOIN roles r ON u.role_id = r.id
        INNER JOIN role_menu_permissions rmp ON r.id = rmp.role_id
        INNER JOIN menu m ON rmp.menu_id = m.id
        INNER JOIN permissions p ON rmp.permission_id = p.id
        WHERE u.username = ?
      ''', [username]);
      
      final dbCount = result.first['permission_count'] as int;
      final cacheCount = _permissionCache[username]!.length;
      
      final isValid = dbCount == cacheCount;
      if (!isValid) {
        print("⚠️ Cache invalide: DB=$dbCount, Cache=$cacheCount");
      }
      
      return isValid;
    } catch (e) {
      print("❌ Erreur validation cache: $e");
      return false;
    }
  }

  /// ✅ NOUVEAU: Rechargement intelligent
  Future<void> smartRefresh(String username) async {
    final isValid = await validateCacheIntegrity(username);
    
    if (!isValid) {
      print("🔄 Cache invalide, rechargement nécessaire");
      await refreshUserPermissions(username);
    } else {
      print("✅ Cache valide, pas de rechargement nécessaire");
    }
  }
}

/// ✅ Extension pour éviter l'import de dart:async
void unawaited(Future future) {
  // Ignorer le warning sur le Future non attendu
  future.catchError((error) {
    print("Erreur tâche en arrière-plan: $error");
  });
}