import { Directive, ElementRef, EventEmitter, Input, OnDestroy, OnInit, Output } from '@angular/core';

@Directive({ selector: '[uiIsInViewport]' })
export class IsInViewportDirective implements OnInit, OnDestroy {
  public observer: IntersectionObserver;

  @Input() observee: ElementRef | HTMLElement;

  @Input() options: IntersectionObserverInit = {
    root: null,
    rootMargin: '0px',
    threshold: 0,
  };

  @Output() viewportEntered = new EventEmitter<HTMLElement>();

  private get target(): HTMLElement {
    if (this.observee) {
      return this.observee instanceof ElementRef ? this.observee.nativeElement : this.observee;
    }

    return this.elementRef.nativeElement;
  }

  constructor(private elementRef: ElementRef) {}

  ngOnInit() {
    this.observer = new IntersectionObserver(this.intersectionCallback, this.options);

    this.observer.observe(this.target);
  }

  ngOnDestroy() {
    this.observer.unobserve(this.target);
    this.observer.disconnect();
  }

  private intersectionCallback = (entries: IntersectionObserverEntry[]) => {
    entries.forEach((entry) => {
      if (entry.isIntersecting) {
        this.viewportEntered.emit(this.target);
      }
    });
  };
}
