// src/app/core/interceptors/auth.interceptor.ts
import { HttpInterceptorFn, HttpRequest, HttpHandlerFn, HttpErrorResponse } from '@angular/common/http';
import { inject } from '@angular/core';
import { AuthService, LoginResponseDto } 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);

  // Exclure les requêtes d’authentification (login, refresh, logout)
  if (isAuthRequest(req)) {
    return next(req);
  }

  const token = authService.getAccessToken();

  // Si un token existe, l’ajouter aux requêtes API
  if (token && isApiRequest(req)) {
    const cloned = addToken(req, token);

    return next(cloned).pipe(
      catchError((error: HttpErrorResponse) => {
        // Si le token est expiré → tentative de refresh
        if (error.status === 401 && !req.url.includes('/auth/refresh')) {
          return handle401Error(authService, router, req, next);
        }

        // Autres erreurs → propager
        return throwError(() => error);
      })
    );
  }

  // Si pas de token → requête normale
  return next(req);
};

// === FONCTIONS UTILITAIRES ===

function addToken(req: HttpRequest<any>, token: string): HttpRequest<any> {
  return req.clone({
    setHeaders: {
      Authorization: `Bearer ${token}`
    }
  });
}

/**
 * Gestion du renouvellement de token en cas d’erreur 401
 */
function handle401Error(
  authService: AuthService,
  router: Router,
  req: HttpRequest<any>,
  next: HttpHandlerFn
) {
  return authService.refreshAccessToken().pipe(
    switchMap((response: LoginResponseDto) => {
      const newRequest = addToken(req, response.access_token);
      return next(newRequest);
    }),
    catchError((refreshError) => {
      authService.logout().subscribe(() => {
        router.navigate(['/auth/login'], { replaceUrl: true });
      });
      return throwError(() => refreshError);
    })
  );
}

/**
 * Détecte si la requête cible une API de ton backend
 */
function isApiRequest(req: HttpRequest<any>): boolean {
  // Ajuste ici selon ton backend (ex : '/api/', '/v1/', etc.)
  return req.url.includes('/api/v1/') || req.url.includes('/auth/');
}

/**
 * Exclut les endpoints liés à l’authentification
 */
function isAuthRequest(req: HttpRequest<any>): boolean {
  const authEndpoints = ['/auth/login', '/auth/refresh', '/auth/logout'];
  return authEndpoints.some(endpoint => req.url.includes(endpoint));
}
