import { Injectable, Injector } from '@angular/core';
import { Overlay, OverlayRef } from '@angular/cdk/overlay';
import { FileDropComponent } from '../file-drop/file-drop.component';
import { ComponentPortal } from '@angular/cdk/portal';
import { DOSSIER_ID } from '../../../tokens';

@Injectable()
export class FileDropOverlayService {
    private readonly _dropOverlayRef: OverlayRef;
    private _dossierId: string;

    constructor(private readonly _overlay: Overlay, private readonly _injector: Injector) {
        this._dropOverlayRef = this._overlay.create({
            height: '100vh',
            width: '100vw',
        });
    }

    dragEnter = e => {
        e.preventDefault();
        e.stopPropagation();
        if (e.dataTransfer.types.includes('Files')) {
            this.openFileDropOverlay();
        }
        return false;
    };

    dragLeave = e => {
        e.preventDefault();
        e.stopPropagation();
        if (e.relatedTarget == null) {
            setTimeout(() => {
                this.closeFileDropOverlay();
            }, 250);
        }
        return false;
    };

    initFileDropHandling(dossierId: string) {
        this._dossierId = dossierId;
        document.getElementsByTagName('body')[0].addEventListener('dragenter', this.dragEnter, false);
        document.getElementsByTagName('body')[0].addEventListener('dragleave', this.dragLeave, false);
    }

    cleanupFileDropHandling() {
        document.getElementsByTagName('body')[0].removeEventListener('dragenter', this.dragEnter, false);
        document.getElementsByTagName('body')[0].removeEventListener('dragleave', this.dragLeave, false);
    }

    openFileDropOverlay() {
        if (!this._dropOverlayRef.hasAttached()) {
            const component = new ComponentPortal(FileDropComponent, null, this._createInjector());
            this._dropOverlayRef.attach(component);
        }
    }

    closeFileDropOverlay() {
        if (this._dropOverlayRef) {
            this._dropOverlayRef.detach();
        }
    }

    private _createInjector() {
        return Injector.create({
            providers: [
                { provide: OverlayRef, useValue: this._dropOverlayRef },
                { provide: DOSSIER_ID, useValue: this._dossierId },
            ],
            parent: this._injector,
        });
    }
}
