import {
  Directive,
  EventEmitter,
  ElementRef,
  HostListener,
  Input,
  Output
} from '@angular/core'
import { FileUploader } from '../models/FileUploader.class'

@Directive({
  selector: '[appFileDrop]',
  standalone: false
})
export class FileDropDirective {
  @Input() uploader?: FileUploader
  @Output() fileOver: EventEmitter<any> = new EventEmitter()
  @Output() fileDrop: EventEmitter<File[]> = new EventEmitter<File[]>()

  protected element: ElementRef

  constructor(element: ElementRef) {
    this.element = element
  }

  /**
   * Dragging element drop event
   */
  @HostListener('drop', ['$event'])
  onDrop(event: DragEvent): void {
    this._preventAndStop(event)
    const files = event.dataTransfer?.files
    const fileList: File[] = []

    if (files) {
      for (let i = 0; i < files.length; i++) {
        fileList.push(files[i])
      }
    }

    this.uploader?.addToQueue(fileList)
    this.fileOver.emit(false)
    this.fileDrop.emit(fileList)
  }

  /**
   * Dragging element drag over event
   */
  @HostListener('dragover', ['$event'])
  onDragOver(event: DragEvent): void {
    this._preventAndStop(event)

    const transfer = event.dataTransfer
    if (transfer) {
      if (transfer.types.indexOf('Files') === -1) return

      transfer.dropEffect = 'copy'
    }

    this.fileOver.emit(true)
  }

  @HostListener('dragleave', ['$event'])
  onDragLeave(event: DragEvent): void {
    this._preventAndStop(event)
    this.fileOver.emit(false)
  }

  /**
   * Prevent propagation trough elements and stop default behavior
   * For particular event
   */
  protected _preventAndStop(event: MouseEvent): void {
    event.preventDefault()
    event.stopPropagation()
  }
}
