// src/app/core/guards/auth.guard.ts
import { inject } from '@angular/core';
import { CanActivateFn, Router, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import { AuthService } from '../services/auth.service';
import { RoleService } from '../services/role.service';
import { map, catchError, of, tap, switchMap } from 'rxjs';

export const authGuard: CanActivateFn = (route: ActivatedRouteSnapshot, state: RouterStateSnapshot) => {
  const authService = inject(AuthService);
  const roleService = inject(RoleService);
  const router = inject(Router);

  console.log('🔐 AuthGuard check for:', state.url);

  // Attendre que l'initialisation soit terminée
  return authService.getInitializedState().pipe(
    switchMap(initialized => {
      if (!initialized) {
        console.log('⏳ AuthService pas encore initialisé, attente...');
        return of(false); // Bloquer en attendant l'initialisation
      }

      // Vérifier l'authentification
      if (authService.isAuthenticated()) {
        return of(checkRoleAccess(route, roleService, router, state.url));
      }

      // Tentative de rafraîchissement du token
      const refreshToken = authService.getRefreshToken();
      if (refreshToken) {
        console.log('🔄 Token expiré, tentative de rafraîchissement...');
        
        return authService.refreshToken().pipe(
          tap(() => {
            console.log('✅ Token rafraîchi avec succès');
            roleService.refreshRoles();
          }),
          map(() => checkRoleAccess(route, roleService, router, state.url)),
          catchError((error) => {
            console.error('❌ Échec du rafraîchissement du token:', error);
            authService.logout().subscribe();
            return of(redirectToLogin(router, state.url, 'session_expired'));
          })
        );
      }

      // Redirection vers login
      console.log('🔒 Redirection vers login depuis:', state.url);
      return of(redirectToLogin(router, state.url, 'not_authenticated'));
    }),
    catchError(error => {
      console.error('❌ Erreur dans le guard d\'auth:', error);
      return of(redirectToLogin(router, state.url, 'not_authenticated'));
    })
  );
}

/**
 * Vérifie l'accès basé sur les rôles requis
 */
function checkRoleAccess(
  route: ActivatedRouteSnapshot, 
  roleService: RoleService, 
  router: Router, 
  currentUrl: string
): boolean {
  const requiredRoles = route.data?.['roles'] as string[];
  
  if (!requiredRoles || requiredRoles.length === 0) {
    console.log('✅ Accès autorisé (aucun rôle requis):', currentUrl);
    return true;
  }

  const hasRequiredRole = roleService.hasAnyRole(requiredRoles);
  const currentUserRoles = roleService.getCurrentUserRoles();

  if (hasRequiredRole) {
    console.log('✅ Accès autorisé avec rôles:', currentUrl);
    console.log('   Rôles requis:', requiredRoles);
    console.log('   Rôles actuels:', currentUserRoles);
    return true;
  }

  console.warn('❌ Accès refusé: rôles insuffisants');
  console.warn('   URL demandée:', currentUrl);
  console.warn('   Rôles requis:', requiredRoles);
  console.warn('   Rôles actuels:', currentUserRoles);

  // Rediriger vers la page non autorisée
  router.navigate(['/unauthorized'], {
    queryParams: {
      requiredRoles: requiredRoles.join(','),
      currentRoles: currentUserRoles.join(','),
      attemptedUrl: currentUrl
    },
    replaceUrl: true
  });
  
  return false;
}

/**
 * Redirige vers la page de login avec les paramètres appropriés
 */
function redirectToLogin(
  router: Router, 
  returnUrl: string, 
  reason: 'not_authenticated' | 'session_expired'
): boolean {
  const queryParams: any = { 
    returnUrl: returnUrl,
    reason: reason
  };

  // Message spécifique selon la raison
  if (reason === 'session_expired') {
    queryParams.message = 'Votre session a expiré. Veuillez vous reconnecter.';
  }

  router.navigate(['/auth/sign-in'], { 
    queryParams,
    replaceUrl: true
  });
  
  return false;
}