import { Inject, Injectable, InjectionToken } from '@angular/core';
import {
  HttpRequest,
  HttpHandler,
  HttpEvent,
  HttpInterceptor,
  HttpResponse,
  HttpErrorResponse,
} from '@angular/common/http';
import { interval, Observable, throwError } from 'rxjs';
import { repeat, retry, timeout } from 'rxjs/operators';
import { MatSnackBar } from '@angular/material/snack-bar';

export const DEFAULT_TIMEOUT = new InjectionToken<number>('defaultTimeout');

@Injectable()
export class ServerErrorInterceptor implements HttpInterceptor {
  constructor(@Inject(DEFAULT_TIMEOUT) protected defaultTimeout: number, private _snackBar: MatSnackBar) {}

  intercept(
    request: HttpRequest<unknown>,
    next: HttpHandler
  ): Observable<HttpEvent<unknown>> {
    //Conexión a Internet ?
    if (!window.navigator.onLine) {

      this._snackBar.open("Sin conexión a internet..", 'Cerrar', {
        duration: 5000,
      });

      const offline = {
        status: 666,
        error: {
          description: 'Favor de revisar su conexión a Internert'
        },
        statusText: 'Sin conexión a Internet'
      };      

      return throwError(() => new HttpErrorResponse(offline));
    } else {
      const timeoutValue = request.headers.get('timeout') || this.defaultTimeout;
      const timeoutValueNumeric = Number(timeoutValue);

      const error_timeout = {
        status: 408,
        error: {
          description: 'Tiempo de espera agotado'
        },
        statusText: 'Su conexión a Internet no pudo establecerse'
      };
      
      return next.handle(request).pipe(timeout({
        each: timeoutValueNumeric,
        with: () => throwError(() => new HttpErrorResponse(error_timeout))
      }), retry(5))
    }
  }
}
