/**
 * Configuration Keycloak pour BTP Xpress
 * Intégration complète avec security.lions.dev
 */

import Keycloak from 'keycloak-js';
import { KEYCLOAK_CONFIG, KEYCLOAK_ROLES, KEYCLOAK_SCOPES } from './api';

// Configuration de l'instance Keycloak
export const keycloakConfig = {
  url: KEYCLOAK_CONFIG.url,
  realm: KEYCLOAK_CONFIG.realm,
  clientId: KEYCLOAK_CONFIG.clientId,
};

// Instance Keycloak globale avec gestion SSR et développement
let keycloak: any = null;

// Fonction pour initialiser Keycloak côté client uniquement
export const initKeycloak = () => {
  if (typeof window === 'undefined') {
    // Côté serveur - retourner un mock
    return {
      init: () => Promise.resolve(false),
      login: () => console.log('Mock Keycloak login'),
      logout: () => console.log('Mock Keycloak logout'),
      updateToken: () => Promise.resolve(false),
      authenticated: false,
      token: null,
      refreshToken: null,
      tokenParsed: null,
      onTokenExpired: null,
      onAuthRefreshSuccess: null,
      onAuthRefreshError: null,
      onAuthLogout: null,
    };
  }

  // Côté client - initialiser Keycloak réel
  if (!keycloak) {
    try {
      keycloak = new Keycloak(keycloakConfig);
    } catch (error) {
      console.warn('Keycloak non disponible en mode développement:', error);
      // Mock Keycloak pour le développement local
      keycloak = {
        init: () => Promise.resolve(false),
        login: () => console.log('Mock Keycloak login'),
        logout: () => console.log('Mock Keycloak logout'),
        updateToken: () => Promise.resolve(false),
        authenticated: false,
        token: null,
        refreshToken: null,
        tokenParsed: null,
        onTokenExpired: null,
        onAuthRefreshSuccess: null,
        onAuthRefreshError: null,
        onAuthLogout: null,
      };
    }
  }

  return keycloak;
};

// Export pour compatibilité
export { keycloak };

// Options d'initialisation Keycloak
export const keycloakInitOptions = {
  onLoad: 'login-required' as const,
  checkLoginIframe: false,
  pkceMethod: 'S256' as const,
  scope: KEYCLOAK_SCOPES.join(' '),
  responseMode: 'fragment' as const,
  flow: 'standard' as const,
  enableLogging: process.env.NODE_ENV === 'development',
};

// Configuration des rôles BTP Xpress
export const BTP_ROLES = {
  // Rôles administratifs
  SUPER_ADMIN: 'super_admin',
  ADMIN: 'admin',
  
  // Rôles de gestion
  DIRECTEUR: 'directeur',
  MANAGER: 'manager',
  CHEF_CHANTIER: 'chef_chantier',
  
  // Rôles opérationnels
  CONDUCTEUR_TRAVAUX: 'conducteur_travaux',
  CHEF_EQUIPE: 'chef_equipe',
  EMPLOYE: 'employe',
  OUVRIER: 'ouvrier',
  
  // Rôles clients
  CLIENT_ENTREPRISE: 'client_entreprise',
  CLIENT_PARTICULIER: 'client_particulier',
  
  // Rôles techniques
  COMPTABLE: 'comptable',
  COMMERCIAL: 'commercial',
  LOGISTICIEN: 'logisticien',
  
  // Rôles de consultation
  VIEWER: 'viewer',
  GUEST: 'guest',
} as const;

// Hiérarchie des rôles (du plus élevé au plus bas)
export const ROLE_HIERARCHY = [
  BTP_ROLES.SUPER_ADMIN,
  BTP_ROLES.ADMIN,
  BTP_ROLES.DIRECTEUR,
  BTP_ROLES.MANAGER,
  BTP_ROLES.CHEF_CHANTIER,
  BTP_ROLES.CONDUCTEUR_TRAVAUX,
  BTP_ROLES.CHEF_EQUIPE,
  BTP_ROLES.COMMERCIAL,
  BTP_ROLES.COMPTABLE,
  BTP_ROLES.LOGISTICIEN,
  BTP_ROLES.EMPLOYE,
  BTP_ROLES.OUVRIER,
  BTP_ROLES.CLIENT_ENTREPRISE,
  BTP_ROLES.CLIENT_PARTICULIER,
  BTP_ROLES.VIEWER,
  BTP_ROLES.GUEST,
] as const;

// Permissions par rôle
export const ROLE_PERMISSIONS = {
  [BTP_ROLES.SUPER_ADMIN]: ['*'], // Toutes les permissions
  [BTP_ROLES.ADMIN]: [
    'users.manage',
    'chantiers.manage',
    'materiels.manage',
    'employes.manage',
    'clients.manage',
    'devis.manage',
    'factures.manage',
    'reports.view',
    'dashboard.admin',
  ],
  [BTP_ROLES.DIRECTEUR]: [
    'chantiers.manage',
    'employes.manage',
    'clients.manage',
    'devis.manage',
    'factures.manage',
    'reports.view',
    'dashboard.management',
  ],
  [BTP_ROLES.MANAGER]: [
    'chantiers.view',
    'chantiers.edit',
    'employes.view',
    'employes.edit',
    'materiels.view',
    'materiels.edit',
    'devis.view',
    'devis.edit',
    'factures.view',
    'reports.view',
    'dashboard.management',
  ],
  [BTP_ROLES.CHEF_CHANTIER]: [
    'chantiers.view',
    'chantiers.edit',
    'employes.view',
    'materiels.view',
    'materiels.reserve',
    'planning.view',
    'planning.edit',
    'dashboard.chantier',
  ],
  [BTP_ROLES.CONDUCTEUR_TRAVAUX]: [
    'chantiers.view',
    'employes.view',
    'materiels.view',
    'planning.view',
    'dashboard.chantier',
  ],
  [BTP_ROLES.CHEF_EQUIPE]: [
    'chantiers.view',
    'employes.view',
    'materiels.view',
    'planning.view',
    'dashboard.equipe',
  ],
  [BTP_ROLES.COMMERCIAL]: [
    'clients.manage',
    'devis.manage',
    'factures.view',
    'chantiers.view',
    'dashboard.commercial',
  ],
  [BTP_ROLES.COMPTABLE]: [
    'factures.manage',
    'devis.view',
    'clients.view',
    'reports.financial',
    'dashboard.financial',
  ],
  [BTP_ROLES.LOGISTICIEN]: [
    'materiels.manage',
    'chantiers.view',
    'planning.view',
    'dashboard.logistique',
  ],
  [BTP_ROLES.EMPLOYE]: [
    'chantiers.view',
    'planning.view',
    'profile.edit',
    'dashboard.employe',
  ],
  [BTP_ROLES.OUVRIER]: [
    'chantiers.view',
    'planning.view',
    'profile.edit',
    'dashboard.employe',
  ],
  [BTP_ROLES.CLIENT_ENTREPRISE]: [
    'chantiers.view.own',
    'devis.view.own',
    'factures.view.own',
    'profile.edit',
    'dashboard.client',
  ],
  [BTP_ROLES.CLIENT_PARTICULIER]: [
    'chantiers.view.own',
    'devis.view.own',
    'factures.view.own',
    'profile.edit',
    'dashboard.client',
  ],
  [BTP_ROLES.VIEWER]: [
    'chantiers.view',
    'dashboard.readonly',
  ],
  [BTP_ROLES.GUEST]: [
    'dashboard.public',
  ],
} as const;

// Utilitaires pour la gestion des rôles
export const RoleUtils = {
  /**
   * Vérifie si l'utilisateur a un rôle spécifique
   */
  hasRole: (userRoles: string[], requiredRole: string): boolean => {
    return userRoles.includes(requiredRole);
  },

  /**
   * Vérifie si l'utilisateur a au moins un des rôles requis
   */
  hasAnyRole: (userRoles: string[], requiredRoles: string[]): boolean => {
    return requiredRoles.some(role => userRoles.includes(role));
  },

  /**
   * Vérifie si l'utilisateur a tous les rôles requis
   */
  hasAllRoles: (userRoles: string[], requiredRoles: string[]): boolean => {
    return requiredRoles.every(role => userRoles.includes(role));
  },

  /**
   * Obtient le rôle le plus élevé de l'utilisateur
   */
  getHighestRole: (userRoles: string[]): string | null => {
    for (const role of ROLE_HIERARCHY) {
      if (userRoles.includes(role)) {
        return role;
      }
    }
    return null;
  },

  /**
   * Vérifie si l'utilisateur a une permission spécifique
   */
  hasPermission: (userRoles: string[], permission: string): boolean => {
    for (const role of userRoles) {
      const rolePermissions = (ROLE_PERMISSIONS as any)[role];
      if (rolePermissions?.includes('*') || rolePermissions?.includes(permission)) {
        return true;
      }
    }
    return false;
  },

  /**
   * Obtient toutes les permissions de l'utilisateur
   */
  getUserPermissions: (userRoles: string[]): string[] => {
    const permissions = new Set<string>();
    for (const role of userRoles) {
      const rolePermissions = (ROLE_PERMISSIONS as any)[role];
      if (rolePermissions) {
        rolePermissions.forEach((permission: string) => permissions.add(permission));
      }
    }
    return Array.from(permissions);
  },

  /**
   * Vérifie si un rôle est supérieur à un autre
   */
  isRoleHigher: (role1: string, role2: string): boolean => {
    const index1 = ROLE_HIERARCHY.indexOf(role1 as any);
    const index2 = ROLE_HIERARCHY.indexOf(role2 as any);
    return index1 !== -1 && index2 !== -1 && index1 < index2;
  },
};

// Configuration des redirections après authentification
export const KEYCLOAK_REDIRECTS = {
  LOGIN_SUCCESS: '/dashboard',
  LOGIN_ERROR: '/auth/error',
  LOGOUT_SUCCESS: '/auth/logout',
  UNAUTHORIZED: '/auth/unauthorized',
  FORBIDDEN: '/auth/forbidden',
} as const;

// Configuration des timeouts
export const KEYCLOAK_TIMEOUTS = {
  TOKEN_REFRESH_BEFORE_EXPIRY: 30, // secondes
  SESSION_CHECK_INTERVAL: 60, // secondes
  SILENT_CHECK_SSO_TIMEOUT: 5000, // millisecondes
} as const;

export default keycloak;
