import { inject } from '@angular/core';
import { CanActivateFn, Router } from '@angular/router';
import { Observable, map, of } from 'rxjs';
import { catchError } from 'rxjs/operators';
import { AuthService } from './auth.service';

/**
 * Garde de route pour les pages protégées.
 *
 * - Si un utilisateur est déjà chargé en mémoire -> accès autorisé.
 * - Sinon, s'il existe un refresh_token persistant, on tente de restaurer la
 *   session (refresh + chargement du profil) : utile après un rechargement de page
 *   où l'access_token en mémoire a été perdu.
 * - En cas d'échec, redirection vers /login en conservant l'URL demandée.
 */
export const authGuard: CanActivateFn = (_route, state): Observable<boolean> => {
  const auth = inject(AuthService);
  const router = inject(Router);

  const versLogin = () =>
    router.createUrlTree(['/login'], {
      queryParams: { redirige: state.url },
    });

  // Utilisateur déjà en mémoire.
  if (auth.getAccessToken()) {
    return of(true);
  }

  // Tentative de restauration via le refresh_token persistant.
  if (auth.aUneSessionPotentielle()) {
    return auth.refresh().pipe(
      // Après refresh on récupère le profil pour peupler le BehaviorSubject.
      map(() => true),
      // chargerProfil est déclenché en arrière-plan ; on autorise dès le refresh OK.
      catchError(() => {
        auth.viderSession();
        router.navigateByUrl('');
        return of(false);
      }),
      map((ok) => {
        if (ok) {
          auth.chargerProfil().subscribe({ error: () => {} });
        }
        return ok;
      }),
    );
  }

  // Aucune session : redirection.
  router.navigateByUrl(versLogin().toString());
  return of(false);
};
