import {Injectable} from "@angular/core";
import {AppProgressIndicationComponent} from "../component/app-progress-indication.component";
import {NgbModal, NgbModalOptions, NgbModalRef} from "@ng-bootstrap/ng-bootstrap";

@Injectable({providedIn: 'root'})
export class AppProgressIndicationService {

  private static readonly EVENT_INTERCEPTOR = (event) => {
    event.preventDefault();
    event.stopPropagation();
  };

  private counter: number = 0;
  private focused: any;
  private ngbModalRef: NgbModalRef;
  private options: NgbModalOptions = {
    backdrop: 'static',
    keyboard: false,
    windowClass: 'modal-center loader'
  };

  constructor(private ngbModal: NgbModal) {
  }

  public showProgressBar(): boolean {
    if (this.counter == 0) {
      this.disableEvents();
      this.saveFocus();
      this.showProgressIndicator();
    }
    ++this.counter;
    return this.counter == 1;
  }

  public hideProgressBar(): boolean {
    if (this.counter == 0) {
      return false;
    }
    if (this.counter == 1) {
      this.hideProgressIndicator();
      this.restoreFocus();
      this.enableEvents();
    }
    --this.counter;
    return this.counter == 0;
  }

  public unconditionallyHideProgressBar(): void {
    this.enableEvents();
    this.hideProgressIndicator();
  }

  public restoreProgressBar(): void {

    if (this.counter > 0 && this.ngbModalRef == null) {
      this.disableEvents();
      this.showProgressIndicator();
    }
  }

  private showProgressIndicator() {
    this.ngbModalRef = this.ngbModal.open(AppProgressIndicationComponent, this.options);
  }

  private hideProgressIndicator() {
    this.ngbModalRef.dismiss('cancel');
    this.ngbModalRef = null;
  }

  private saveFocus() {
    this.focused = document.querySelector(':focus');
  }

  private restoreFocus() {
    if (this.focused) {
      this.focused.focus();
      this.focused = null;
    }
  }

  private disableEvents() {
    document.body.addEventListener('keydown', AppProgressIndicationService.EVENT_INTERCEPTOR);
    document.body.addEventListener('keyup', AppProgressIndicationService.EVENT_INTERCEPTOR);
    document.body.addEventListener('contextmenu', AppProgressIndicationService.EVENT_INTERCEPTOR);
  }

  private enableEvents() {
    document.body.removeEventListener('keydown', AppProgressIndicationService.EVENT_INTERCEPTOR);
    document.body.removeEventListener('keyup', AppProgressIndicationService.EVENT_INTERCEPTOR);
    document.body.removeEventListener('contextmenu', AppProgressIndicationService.EVENT_INTERCEPTOR);
  }
}