import {
  Injectable,
  Output,
  EventEmitter,
  Inject,
  ComponentRef,
  ComponentFactoryResolver,
  ApplicationRef,
  Injector,
  EmbeddedViewRef,
  Renderer2,
  RendererFactory2
} from '@angular/core';
import { AlertComponent } from './alert.component';

@Injectable()
export class AlertEventService {
  numberOfAlerts = 0;
  private renderer: Renderer2;

  constructor(
    private componentFactoryResolver: ComponentFactoryResolver,
    private applicationRef: ApplicationRef,
    private injector: Injector,
    rendererFactory: RendererFactory2
  ) {
    this.renderer = rendererFactory.createRenderer(null, null);
  }

  alert(message: string) {
    this.appendComponentToBody(null, message);
  }

  // instanitate component and inject into dom
  appendComponentToBody(
    componentRef: ComponentRef<AlertComponent>,
    message: string
  ): ComponentRef<AlertComponent> {
    this.numberOfAlerts++;

    if (componentRef === null) {
      componentRef = this.componentFactoryResolver
        .resolveComponentFactory(AlertComponent)
        .create(this.injector);

      // passing instance into component, so it can close itself
      componentRef.instance.componentRef = componentRef;
      componentRef.instance.message = message;
      componentRef.instance.alertNo = this.numberOfAlerts;
      componentRef.instance.noOfAlerts.next(this.numberOfAlerts);
      componentRef.instance.noOfAlerts.subscribe(x => {
        this.numberOfAlerts = x;
      });

      this.applicationRef.attachView(componentRef.hostView);

      const domElem = (componentRef.hostView as EmbeddedViewRef<any>)
        .rootNodes[0] as HTMLElement;

      document.body.appendChild(domElem);

      return componentRef;
    } else {
      return componentRef;
    }
  }
}
