import { DOCUMENT } from '@angular/common';
import {
  AfterViewInit,
  Directive,
  ElementRef,
  HostListener,
  Inject,
  Input,
  OnChanges,
  OnDestroy,
  Renderer2,
  SimpleChanges,
  Type,
} from '@angular/core';
// eslint-disable-next-line import/no-cycle
import { AppDragDropService } from './app-drag-drop.service';

@Directive({
  selector: '[appDropList]',
})
export class DropListDirective implements OnDestroy, AfterViewInit, OnChanges {
  public static SCROLL_PLACE_SENSITIVITY = 20;
  @Input('appDropList') dropZone;

  /**
   * Unique id. Drag directive checks this to decide to recreate its preview or not
   */
  @Input() dropListId?;
  @Input() isDropZoneDisabled?: boolean = false;

  public onMouseMove: any;

  constructor(
    private renderer: Renderer2,
    private el: ElementRef,
    @Inject(DOCUMENT) private document: Document,
    private appDragDropService: AppDragDropService
  ) {
    this.appDragDropService.registerDropList(this);

    this.onMouseMove = (event) => {
      if (this.appDragDropService.isDragOn()) {
        let bond = this.getDOMNode().getBoundingClientRect();
        if (
          event.clientY > bond.top &&
          event.clientY < bond.top + DropListDirective.SCROLL_PLACE_SENSITIVITY
        ) {
          this.scroll(0, -50);
        } else if (
          event.clientY < bond.top + bond.height &&
          event.clientY > bond.top + bond.height - DropListDirective.SCROLL_PLACE_SENSITIVITY
        ) {
          this.scroll(0, 50);
        }
      }
    };
  }

  public ngAfterViewInit() {
    this.getDOMNode().dataset.appDropListId = this.dropListId;
  }

  public ngOnChanges(changes: SimpleChanges): void {
    if (changes['dropListId']) {
      this.getDOMNode().dataset.appDropListId = this.dropListId;
    }
  }

  public getDropListId() {
    return this.dropListId;
  }

  public getDropZone() {
    return this.dropZone;
  }

  public getDOMNode(): HTMLElement {
    return this.el.nativeElement;
  }

  private scroll(left, top) {
    this.getDOMNode().scrollBy({
      top: top,
      left: left,
      behavior: 'smooth',
    });
  }

  ngOnDestroy() {
    this.appDragDropService.deregisterDropList(this);
  }
}
