// 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);

  // Exclusion des endpoints d'authentification
  if (isAuthRequest(req)) {
    return next(req);
  }

  const token = authService.getAccessToken();

  if (token && isApiRequest(req)) {
    const cloned = addToken(req, token);
    
    return next(cloned).pipe(
      catchError((error: HttpErrorResponse) => {
        if (error.status === 401 && !req.url.includes('/auth/refresh')) {
          return handle401Error(authService, router, req, next);
        }
        return throwError(() => error);
      })
    );
  }

  return next(req);
};

// === FONCTIONS UTILITAIRES ===

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

function handle401Error(
  authService: AuthService,
  router: Router,
  req: HttpRequest<any>,
  next: HttpHandlerFn
) {
  return authService.refreshToken().pipe(
    switchMap((response: LoginResponseDto) => {
      const newRequest = addToken(req, response.access_token);
      return next(newRequest);
    }),
    catchError((refreshError) => {
      authService.logout().subscribe();
      router.navigate(['/auth/sign-in']);
      return throwError(() => refreshError);
    })
  );
}

function isApiRequest(req: HttpRequest<any>): boolean {
  return req.url.includes('/api/') || req.url.includes('/auth/');
}

function isAuthRequest(req: HttpRequest<any>): boolean {
  const authEndpoints = [
    '/auth/login',
    '/auth/refresh',
    '/auth/logout'
  ];
  
  return authEndpoints.some(endpoint => req.url.includes(endpoint));
}