import { Directive, ElementRef, Host, HostListener, Input, OnChanges, OnInit, Output, Renderer2, SimpleChanges } from '@angular/core';
import { Subject } from 'rxjs';
import { filter } from 'rxjs/operators';

@Directive({ selector: '[uiScrollContainer]' })
export class UiScrollContainerDirective implements OnChanges, OnInit {
  @Input('uiScrollContainer')
  direction: 'horizontal' | 'vertical' = 'vertical';

  @Input()
  deltaStart = 0;

  @Input()
  deltaEnd = 0;

  private scrollEvent$ = new Subject<Event>();

  @Output()
  reachStart = this.scrollEvent$.pipe(
    filter((event) => {
      if (this.direction === 'vertical') {
        const top = this.nativeElement.scrollTop;
        return top <= this.deltaStart;
      } else {
        throw new Error('not implemented');
      }
    })
  );

  @Output()
  reachEnd = this.scrollEvent$.pipe(
    filter((event) => {
      if (this.direction === 'vertical') {
        const top = this.nativeElement.scrollTop;
        const height = this.nativeElement.scrollHeight - this.nativeElement.clientHeight - this.deltaEnd;
        return top >= height;
      } else {
        throw new Error('not implemented');
      }
    })
  );

  get nativeElement(): HTMLElement {
    return this.elementRef.nativeElement;
  }

  constructor(@Host() private elementRef: ElementRef, private renderer: Renderer2) {}
  ngOnInit(): void {
    if (!this.direction) {
      this.direction = 'vertical';
    }
  }

  ngOnChanges({ direction }: SimpleChanges): void {
    if (direction) {
      if (this.direction === 'horizontal') {
        this.renderer.setStyle(this.elementRef.nativeElement, 'overflow-x', 'auto');
        this.renderer.setStyle(this.elementRef.nativeElement, 'overflow-y', 'auto');
      } else {
        this.renderer.setStyle(this.elementRef.nativeElement, 'overflow-y', 'auto');
        this.renderer.setStyle(this.elementRef.nativeElement, 'overflow-x', 'hidden');
      }
    }
  }

  @HostListener('scroll', ['$event'])
  onScroll(event: Event) {
    this.scrollEvent$.next(event);
  }
}
