import { inject, Injectable, Injector } from '@angular/core';
import {
  HttpInterceptor,
  HttpEvent,
  HttpHandler,
  HttpRequest,
  HttpErrorResponse,
} from '@angular/common/http';
import { from, NEVER, Observable, throwError } from 'rxjs';
import { catchError, filter, mergeMap, takeUntil } from 'rxjs/operators';
import { AuthService, LoginStrategy } from '@core/auth';
import { injectOnline$ } from '../services/network-status.service';
import { logger } from '@isa/core/logging';

@Injectable()
export class HttpErrorInterceptor implements HttpInterceptor {
  #logger = logger(() => ({
    'http-interceptor': 'HttpErrorInterceptor',
  }));
  #offline$ = injectOnline$().pipe(filter((online) => !online));
  #injector = inject(Injector);
  #auth = inject(AuthService);

  intercept(
    req: HttpRequest<any>,
    next: HttpHandler,
  ): Observable<HttpEvent<any>> {
    return next.handle(req).pipe(
      takeUntil(this.#offline$),
      catchError((error: HttpErrorResponse, caught: any) =>
        this.handleError(error),
      ),
    );
  }

  handleError(error: HttpErrorResponse): Observable<any> {
    return this.#auth.initialized$.pipe(
      mergeMap((initialized) => {
        if (initialized && error.status === 401) {
          const strategy = this.#injector.get(LoginStrategy);

          return from(strategy.login('Sie sind nicht mehr angemeldet')).pipe(
            mergeMap(() => NEVER),
          );
        }

        if (!error.url.endsWith('/isa/logging')) {
          this.#logger.error('Http Error', error);
        }

        return throwError(() => error);
      }),
    );
  }
}
