import { ApplicationRef, Injectable, Injector } from '@angular/core';
import { CustomError } from '@msfa-models/error/custom-error';
import { BehaviorSubject, Observable } from 'rxjs';
import { map } from 'rxjs/operators';

@Injectable({
  providedIn: 'root',
})
export class ErrorService {
  private appRef: ApplicationRef;
  private errorQueue$ = new BehaviorSubject<CustomError[]>([]);

  public errors$: Observable<CustomError[]> = this.errorQueue$.pipe(
    map(errors => errors.sort((a, b) => (a.timestamp > b.timestamp ? -1 : 1)))
  );

  constructor(private injector: Injector) {
    // Workaround to fix change-detection when using Error interceptor
    // See https://stackoverflow.com/a/37793791
    setTimeout(() => (this.appRef = this.injector.get(ApplicationRef)));
  }

  public add(error: CustomError): void {
    this.errorQueue$.next([...this.errorQueue$.value, error]);
    this.appRef.tick();
  }

  public remove(error: CustomError): void {
    const newErrorQueue = this.errorQueue$.value.filter(currentError => currentError.id !== error.id);
    this.errorQueue$.next(newErrorQueue);
    this.appRef.tick();
  }
}
