import { Directive, ElementRef, AfterViewInit, OnDestroy, output } from '@angular/core';

/**
 * Directive that emits an event when its host element enters or leaves the viewport.
 */
@Directive({
  selector: '[uiInViewport]',
  exportAs: 'uiInViewport',
})
export class InViewportDirective implements AfterViewInit, OnDestroy {
  /**
   * Emits true when the element enters the viewport and false when it leaves.
   */
  inViewport = output<boolean>({ alias: 'uiInViewport' });

  /**
   * Emits when the element enters the viewport.
   */
  enteredViewport = output<void>();

  /**
   * Emits when the element leaves the viewport.
   */
  leftViewport = output<void>();

  private observer: IntersectionObserver | null = null;

  constructor(private elementRef: ElementRef<HTMLElement>) {}

  ngAfterViewInit(): void {
    this.observer = new IntersectionObserver(
      (entries) => {
        entries.forEach((entry) => {
          if (entry.isIntersecting) {
            this.inViewport.emit(true);
            this.enteredViewport.emit();
          } else {
            this.inViewport.emit(false);
            this.leftViewport.emit();
          }
        });
      },
      { threshold: [0, 0.1, 0.5, 1.0] },
    );

    this.observer.observe(this.elementRef.nativeElement);
  }

  ngOnDestroy(): void {
    if (this.observer) {
      this.observer.disconnect();
    }
  }
}
