/// Mapper de Rôles Keycloak vers UserRole
/// Convertit les rôles Keycloak existants vers notre système de rôles sophistiqué
library keycloak_role_mapper;

import '../models/user_role.dart';
import '../models/permission_matrix.dart';

/// Service de mapping des rôles Keycloak
class KeycloakRoleMapper {
  
  /// Mapping des rôles Keycloak vers UserRole
  static const Map<String, UserRole> _keycloakToUserRole = {
    // Rôles administratifs
    'SUPER_ADMINISTRATEUR': UserRole.superAdmin,
    'ADMIN': UserRole.superAdmin,
    'ADMIN_ORGANISATION': UserRole.orgAdmin, // Rôle Keycloak (backend)
    'ADMINISTRATEUR_ORGANISATION': UserRole.orgAdmin,
    'PRESIDENT': UserRole.orgAdmin,

    // Rôles de gestion
    'RESPONSABLE_TECHNIQUE': UserRole.moderator,
    'RESPONSABLE_MEMBRES': UserRole.moderator,
    'TRESORIER': UserRole.moderator,
    'SECRETAIRE': UserRole.moderator,
    'GESTIONNAIRE_MEMBRE': UserRole.moderator,
    'ORGANISATEUR_EVENEMENT': UserRole.moderator,
    'CONSULTANT': UserRole.consultant,
    'GESTIONNAIRE_RH': UserRole.hrManager,
    'HR_MANAGER': UserRole.hrManager,

    // Rôles membres
    'MEMBRE_ACTIF': UserRole.activeMember,
    'MEMBRE_SIMPLE': UserRole.simpleMember,
    'MEMBRE': UserRole.activeMember,
  };
  
  /// Mapping des rôles Keycloak vers permissions spécifiques
  static const Map<String, List<String>> _keycloakToPermissions = {
    'SUPER_ADMINISTRATEUR': [
      // Permissions Super Admin - Accès total
      PermissionMatrix.SYSTEM_ADMIN,
      PermissionMatrix.SYSTEM_CONFIG,
      PermissionMatrix.SYSTEM_SECURITY,
      PermissionMatrix.ORG_CREATE,
      PermissionMatrix.ORG_DELETE,
      PermissionMatrix.ORG_CONFIG,
      PermissionMatrix.MEMBERS_VIEW_ALL,
      PermissionMatrix.MEMBERS_EDIT_ALL,
      PermissionMatrix.MEMBERS_DELETE_ALL,
      PermissionMatrix.FINANCES_VIEW_ALL,
      PermissionMatrix.FINANCES_EDIT_ALL,
      PermissionMatrix.EVENTS_VIEW_ALL,
      PermissionMatrix.EVENTS_EDIT_ALL,
      PermissionMatrix.SOLIDARITY_VIEW_ALL,
      PermissionMatrix.SOLIDARITY_EDIT_ALL,
      PermissionMatrix.REPORTS_GENERATE,
      PermissionMatrix.DASHBOARD_ANALYTICS,
    ],
    'ADMIN': [
      // Permissions Super Admin - Accès total (compatibilité)
      PermissionMatrix.SYSTEM_ADMIN,
      PermissionMatrix.SYSTEM_CONFIG,
      PermissionMatrix.SYSTEM_SECURITY,
      PermissionMatrix.ORG_CREATE,
      PermissionMatrix.ORG_DELETE,
      PermissionMatrix.ORG_CONFIG,
      PermissionMatrix.MEMBERS_VIEW_ALL,
      PermissionMatrix.MEMBERS_EDIT_ALL,
      PermissionMatrix.MEMBERS_DELETE_ALL,
      PermissionMatrix.FINANCES_VIEW_ALL,
      PermissionMatrix.FINANCES_EDIT_ALL,
      PermissionMatrix.EVENTS_VIEW_ALL,
      PermissionMatrix.EVENTS_EDIT_ALL,
      PermissionMatrix.SOLIDARITY_VIEW_ALL,
      PermissionMatrix.SOLIDARITY_EDIT_ALL,
      PermissionMatrix.REPORTS_GENERATE,
      PermissionMatrix.DASHBOARD_ANALYTICS,
    ],
    'ADMIN_ORGANISATION': [
      // Permissions Admin Organisation (rôle Keycloak backend)
      PermissionMatrix.ORG_CONFIG,
      PermissionMatrix.MEMBERS_VIEW_ALL,
      PermissionMatrix.MEMBERS_EDIT_ALL,
      PermissionMatrix.FINANCES_VIEW_ALL,
      PermissionMatrix.FINANCES_EDIT_ALL,
      PermissionMatrix.EVENTS_VIEW_ALL,
      PermissionMatrix.EVENTS_EDIT_ALL,
      PermissionMatrix.SOLIDARITY_VIEW_ALL,
      PermissionMatrix.SOLIDARITY_EDIT_ALL,
      PermissionMatrix.REPORTS_GENERATE,
      PermissionMatrix.DASHBOARD_ANALYTICS,
    ],

    'ADMINISTRATEUR_ORGANISATION': [
      // Permissions Admin Organisation
      PermissionMatrix.ORG_CONFIG,
      PermissionMatrix.MEMBERS_VIEW_ALL,
      PermissionMatrix.MEMBERS_EDIT_ALL,
      PermissionMatrix.FINANCES_VIEW_ALL,
      PermissionMatrix.FINANCES_EDIT_ALL,
      PermissionMatrix.EVENTS_VIEW_ALL,
      PermissionMatrix.EVENTS_EDIT_ALL,
      PermissionMatrix.SOLIDARITY_VIEW_ALL,
      PermissionMatrix.SOLIDARITY_EDIT_ALL,
      PermissionMatrix.REPORTS_GENERATE,
      PermissionMatrix.DASHBOARD_ANALYTICS,
    ],

    'PRESIDENT': [
      // Permissions Président - Gestion organisation
      PermissionMatrix.ORG_CONFIG,
      PermissionMatrix.MEMBERS_VIEW_ALL,
      PermissionMatrix.MEMBERS_EDIT_ALL,
      PermissionMatrix.FINANCES_VIEW_ALL,
      PermissionMatrix.FINANCES_EDIT_ALL,
      PermissionMatrix.EVENTS_VIEW_ALL,
      PermissionMatrix.EVENTS_EDIT_ALL,
      PermissionMatrix.SOLIDARITY_VIEW_ALL,
      PermissionMatrix.SOLIDARITY_EDIT_ALL,
      PermissionMatrix.REPORTS_GENERATE,
      PermissionMatrix.DASHBOARD_ANALYTICS,
      PermissionMatrix.COMM_SEND_ALL,
    ],

    'RESPONSABLE_TECHNIQUE': [
      // Permissions Responsable Technique
      PermissionMatrix.SYSTEM_MONITORING,
      PermissionMatrix.SYSTEM_MAINTENANCE,
      PermissionMatrix.MEMBERS_VIEW_ALL,
      PermissionMatrix.MEMBERS_EDIT_BASIC,
      PermissionMatrix.EVENTS_VIEW_ALL,
      PermissionMatrix.EVENTS_EDIT_ALL,
      PermissionMatrix.DASHBOARD_VIEW,
      PermissionMatrix.REPORTS_GENERATE,
    ],

    'RESPONSABLE_MEMBRES': [
      // Permissions Responsable Membres
      PermissionMatrix.MEMBERS_VIEW_ALL,
      PermissionMatrix.MEMBERS_EDIT_ALL,
      PermissionMatrix.MEMBERS_DELETE_ALL,
      PermissionMatrix.EVENTS_VIEW_ALL,
      PermissionMatrix.EVENTS_EDIT_ALL,
      PermissionMatrix.SOLIDARITY_VIEW_ALL,
      PermissionMatrix.SOLIDARITY_EDIT_ALL,
      PermissionMatrix.DASHBOARD_VIEW,
      PermissionMatrix.REPORTS_GENERATE,
    ],

    'TRESORIER': [
      // Permissions Trésorier - Focus finances
      PermissionMatrix.FINANCES_VIEW_ALL,
      PermissionMatrix.FINANCES_EDIT_ALL,
      PermissionMatrix.MEMBERS_VIEW_ALL,
      PermissionMatrix.MEMBERS_EDIT_BASIC,
      PermissionMatrix.EVENTS_VIEW_ALL,
      PermissionMatrix.REPORTS_GENERATE,
      PermissionMatrix.DASHBOARD_VIEW,
    ],
    
    'SECRETAIRE': [
      // Permissions Secrétaire - Communication et membres
      PermissionMatrix.MEMBERS_VIEW_ALL,
      PermissionMatrix.MEMBERS_EDIT_BASIC,
      PermissionMatrix.EVENTS_VIEW_ALL,
      PermissionMatrix.EVENTS_EDIT_ALL,
      PermissionMatrix.COMM_SEND_ALL,
      PermissionMatrix.COMM_MODERATE,
      PermissionMatrix.DASHBOARD_VIEW,
    ],
    
    'GESTIONNAIRE_MEMBRE': [
      // Permissions Gestionnaire de Membres
      PermissionMatrix.MEMBERS_VIEW_ALL,
      PermissionMatrix.MEMBERS_EDIT_ALL,
      PermissionMatrix.MEMBERS_CREATE,
      PermissionMatrix.EVENTS_VIEW_ALL,
      PermissionMatrix.SOLIDARITY_VIEW_ALL,
      PermissionMatrix.DASHBOARD_VIEW,
      PermissionMatrix.COMM_SEND_MEMBERS,
    ],
    
    'ORGANISATEUR_EVENEMENT': [
      // Permissions Organisateur d'Événements
      PermissionMatrix.EVENTS_VIEW_ALL,
      PermissionMatrix.EVENTS_EDIT_ALL,
      PermissionMatrix.EVENTS_CREATE,
      PermissionMatrix.MEMBERS_VIEW_ALL,
      PermissionMatrix.SOLIDARITY_VIEW_ALL,
      PermissionMatrix.DASHBOARD_VIEW,
      PermissionMatrix.COMM_SEND_MEMBERS,
    ],

    'CONSULTANT': [
      PermissionMatrix.DASHBOARD_VIEW,
      PermissionMatrix.DASHBOARD_ANALYTICS,
      PermissionMatrix.MEMBERS_VIEW_ALL,
      PermissionMatrix.EVENTS_VIEW_ALL,
      PermissionMatrix.REPORTS_VIEW_ALL,
      PermissionMatrix.REPORTS_GENERATE,
    ],

    'GESTIONNAIRE_RH': [
      PermissionMatrix.DASHBOARD_VIEW,
      PermissionMatrix.MEMBERS_VIEW_ALL,
      PermissionMatrix.MEMBERS_EDIT_BASIC,
      PermissionMatrix.MEMBERS_APPROVE,
      PermissionMatrix.EVENTS_VIEW_ALL,
      PermissionMatrix.MODERATION_USERS,
    ],

    'HR_MANAGER': [
      PermissionMatrix.DASHBOARD_VIEW,
      PermissionMatrix.MEMBERS_VIEW_ALL,
      PermissionMatrix.MEMBERS_EDIT_BASIC,
      PermissionMatrix.MEMBERS_APPROVE,
      PermissionMatrix.EVENTS_VIEW_ALL,
      PermissionMatrix.MODERATION_USERS,
    ],

    'MEMBRE_ACTIF': [
      // Permissions Membre Actif
      PermissionMatrix.MEMBERS_VIEW_OWN,
      PermissionMatrix.MEMBERS_EDIT_OWN,
      PermissionMatrix.EVENTS_VIEW_ALL,
      PermissionMatrix.EVENTS_PARTICIPATE,
      PermissionMatrix.EVENTS_CREATE,
      PermissionMatrix.SOLIDARITY_VIEW_ALL,
      PermissionMatrix.SOLIDARITY_PARTICIPATE,
      PermissionMatrix.SOLIDARITY_CREATE,
      PermissionMatrix.FINANCES_VIEW_OWN,
      PermissionMatrix.DASHBOARD_VIEW,
      PermissionMatrix.COMM_SEND_MEMBERS,
    ],

    'MEMBRE_SIMPLE': [
      // Permissions Membre Simple
      PermissionMatrix.MEMBERS_VIEW_OWN,
      PermissionMatrix.MEMBERS_EDIT_OWN,
      PermissionMatrix.EVENTS_VIEW_PUBLIC,
      PermissionMatrix.EVENTS_PARTICIPATE,
      PermissionMatrix.SOLIDARITY_VIEW_PUBLIC,
      PermissionMatrix.SOLIDARITY_PARTICIPATE,
      PermissionMatrix.FINANCES_VIEW_OWN,
      PermissionMatrix.DASHBOARD_VIEW,
    ],

    'MEMBRE': [
      // Permissions Membre Standard (compatibilité)
      PermissionMatrix.MEMBERS_VIEW_OWN,
      PermissionMatrix.MEMBERS_EDIT_OWN,
      PermissionMatrix.EVENTS_VIEW_PUBLIC,
      PermissionMatrix.EVENTS_PARTICIPATE,
      PermissionMatrix.SOLIDARITY_VIEW_PUBLIC,
      PermissionMatrix.SOLIDARITY_PARTICIPATE,
      PermissionMatrix.FINANCES_VIEW_OWN,
      PermissionMatrix.DASHBOARD_VIEW,
    ],
  };
  
  /// Mappe une liste de rôles Keycloak vers le UserRole principal
  static UserRole mapToUserRole(List<String> keycloakRoles) {
    // Normaliser en majuscules pour éviter les écarts de casse (ex. admin_organisation)
    final normalized = keycloakRoles.map((r) => r.toUpperCase()).toList();

    // Priorité des rôles (du plus élevé au plus bas)
    const List<String> rolePriority = [
      'SUPER_ADMINISTRATEUR',
      'ADMIN',
      'ADMIN_ORGANISATION',
      'ADMINISTRATEUR_ORGANISATION',
      'PRESIDENT',
      'RESPONSABLE_TECHNIQUE',
      'RESPONSABLE_MEMBRES',
      'TRESORIER',
      'SECRETAIRE',
      'GESTIONNAIRE_MEMBRE',
      'ORGANISATEUR_EVENEMENT',
      'CONSULTANT',
      'GESTIONNAIRE_RH',
      'HR_MANAGER',
      'MEMBRE_ACTIF',
      'MEMBRE_SIMPLE',
      'MEMBRE',
    ];

    // Trouver le rôle avec la priorité la plus élevée
    for (final String priorityRole in rolePriority) {
      if (normalized.contains(priorityRole)) {
        return _keycloakToUserRole[priorityRole] ?? UserRole.simpleMember;
      }
    }

    // Par défaut, visiteur si aucun rôle reconnu
    return UserRole.visitor;
  }
  
  /// Mappe une liste de rôles Keycloak vers les permissions
  static List<String> mapToPermissions(List<String> keycloakRoles) {
    final Set<String> permissions = <String>{};

    // Normaliser en majuscules pour cohérence avec le mapping
    final normalized = keycloakRoles.map((r) => r.toUpperCase()).toList();

    // Ajouter les permissions pour chaque rôle
    for (final String role in normalized) {
      final List<String>? rolePermissions = _keycloakToPermissions[role];
      if (rolePermissions != null) {
        permissions.addAll(rolePermissions);
      }
    }
    
    // Ajouter les permissions de base pour tous les utilisateurs authentifiés
    permissions.add(PermissionMatrix.DASHBOARD_VIEW);
    permissions.add(PermissionMatrix.MEMBERS_VIEW_OWN);
    
    return permissions.toList();
  }
  
  /// Vérifie si un rôle Keycloak est reconnu
  static bool isValidKeycloakRole(String role) {
    return _keycloakToUserRole.containsKey(role);
  }
  
  /// Récupère tous les rôles Keycloak supportés
  static List<String> getSupportedKeycloakRoles() {
    return _keycloakToUserRole.keys.toList();
  }
  
  /// Récupère le UserRole correspondant à un rôle Keycloak spécifique
  static UserRole? getUserRoleForKeycloakRole(String keycloakRole) {
    return _keycloakToUserRole[keycloakRole];
  }
  
  /// Récupère les permissions pour un rôle Keycloak spécifique
  static List<String> getPermissionsForKeycloakRole(String keycloakRole) {
    return _keycloakToPermissions[keycloakRole] ?? [];
  }
  
  /// Analyse détaillée du mapping des rôles
  static Map<String, dynamic> analyzeRoleMapping(List<String> keycloakRoles) {
    final UserRole primaryRole = mapToUserRole(keycloakRoles);
    final List<String> permissions = mapToPermissions(keycloakRoles);
    
    final Map<String, List<String>> roleBreakdown = {};
    for (final String role in keycloakRoles) {
      if (isValidKeycloakRole(role)) {
        roleBreakdown[role] = getPermissionsForKeycloakRole(role);
      }
    }
    
    return {
      'keycloakRoles': keycloakRoles,
      'primaryRole': primaryRole.name,
      'primaryRoleDisplayName': primaryRole.displayName,
      'totalPermissions': permissions.length,
      'permissions': permissions,
      'roleBreakdown': roleBreakdown,
      'unrecognizedRoles': keycloakRoles
          .where((role) => !isValidKeycloakRole(role))
          .toList(),
    };
  }
  
  /// Suggestions d'amélioration du mapping
  static Map<String, dynamic> getMappingSuggestions(List<String> keycloakRoles) {
    final List<String> unrecognized = keycloakRoles
        .where((role) => !isValidKeycloakRole(role))
        .toList();
    
    final List<String> suggestions = [];
    
    if (unrecognized.isNotEmpty) {
      suggestions.add(
        'Rôles non reconnus détectés: ${unrecognized.join(", ")}. '
        'Considérez ajouter ces rôles au mapping ou les ignorer.',
      );
    }
    
    if (keycloakRoles.isEmpty) {
      suggestions.add(
        'Aucun rôle Keycloak détecté. L\'utilisateur sera traité comme visiteur.',
      );
    }
    
    final UserRole primaryRole = mapToUserRole(keycloakRoles);
    if (primaryRole == UserRole.visitor && keycloakRoles.isNotEmpty) {
      suggestions.add(
        'L\'utilisateur a des rôles Keycloak mais est mappé comme visiteur. '
        'Vérifiez la configuration du mapping.',
      );
    }
    
    return {
      'unrecognizedRoles': unrecognized,
      'suggestions': suggestions,
      'mappingHealth': suggestions.isEmpty ? 'excellent' : 'needs_attention',
    };
  }
}
