import { Directive, ElementRef, EventEmitter, Input, OnDestroy, Output } from '@angular/core';
import { fromEvent, merge, of, Subscription } from 'rxjs';
import { delay, mergeMap, takeUntil, throttleTime } from 'rxjs/operators';

@Directive({
  selector: '[appLongPress]',
})
export class LongpressDirective implements OnDestroy {
  private eventSubscribe: Subscription;
  private threshold = 500;

  @Input('appLongPress') value?: any;
  @Output() readonly longPress: EventEmitter<any> = new EventEmitter<any>();

  constructor(private elementRef: ElementRef) {
    var touchBeginEvent = fromEvent(elementRef.nativeElement, 'touchstart');
    var touchEndEvent = fromEvent(elementRef.nativeElement, 'touchend');
    var touchMoveEvent = fromEvent(elementRef.nativeElement, 'touchmove').pipe(throttleTime(500));
    var touchCancelEvent = fromEvent(elementRef.nativeElement, 'touchcancel');

    let cancelEvents = merge(touchEndEvent, touchMoveEvent, touchCancelEvent);

    const longpressEvent = touchBeginEvent.pipe(
      mergeMap((event) => {
        return of(event).pipe(delay(this.threshold), takeUntil(cancelEvents));
      })
    );

    longpressEvent.subscribe(() => {
      this.longPress.emit(this.value);
    });
  }

  ngOnDestroy(): void {
    if (this.eventSubscribe) {
      this.eventSubscribe.unsubscribe();
    }
  }
}
