import { HttpInterceptorFn, HttpRequest, HttpHandlerFn, HttpErrorResponse } from '@angular/common/http';
import { inject } from '@angular/core';
import { AuthService } from '../services/auth.service';
import { Router } from '@angular/router';
import { catchError, switchMap, throwError } from 'rxjs';

export const authInterceptor: HttpInterceptorFn = (req, next) => {
  const authService = inject(AuthService);
  const router = inject(Router);

  // On ignore les requêtes d'authentification
  if (isAuthRequest(req)) {
    return next(req);
  }

  const token = authService.getToken();

  // On ajoute le token uniquement si c'est une requête API et que le token existe
  if (token && isApiRequest(req)) {
    const cloned = addToken(req, token);
    
    return next(cloned).pipe(
      catchError((error: HttpErrorResponse) => {
        if (error.status === 401) {
          // Token expiré, on tente de le rafraîchir
          return handle401Error(authService, router, req, next);
        }
        return throwError(() => error);
      })
    );
  }

  return next(req);
};

// Ajoute le token à la requête
function addToken(req: HttpRequest<any>, token: string): HttpRequest<any> {
  return req.clone({
    setHeaders: {
      Authorization: `Bearer ${token}`
    }
  });
}

// Gère les erreurs 401 (token expiré)
function handle401Error(
  authService: AuthService,
  router: Router,
  req: HttpRequest<any>,
  next: HttpHandlerFn
) {
  return authService.refreshToken().pipe(
    switchMap((response: any) => {
      // Nouveau token obtenu, on relance la requête originale
      const newToken = response.access_token;
      const newRequest = addToken(req, newToken);
      return next(newRequest);
    }),
    catchError((refreshError) => {
      // Échec du rafraîchissement, on déconnecte
      authService.logout();
      router.navigate(['/auth/sign-in']);
      return throwError(() => refreshError);
    })
  );
}

// Détermine si c'est une requête vers le backend API
function isApiRequest(req: HttpRequest<any>): boolean {
  return req.url.includes('/api/') || req.url.includes('/auth/');
}

// Liste des endpoints où le token ne doit pas être ajouté
function isAuthRequest(req: HttpRequest<any>): boolean {
  const url = req.url;
  return (
    url.includes('/auth/login') ||
    url.endsWith('/auth/refresh') ||
    url.endsWith('/auth/logout')
  );
}
