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';
import { BehaviorSubject } from 'rxjs';

@Injectable({ providedIn: 'root' })
export class FileDropOverlayService {
    readonly #dropOverlayRef: OverlayRef;
    readonly #importingRedactions$ = new BehaviorSubject(false);
    #dossierId: string;

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

    get #importingRedactions() {
        return this.#importingRedactions$.getValue();
    }

    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() && !this.#importingRedactions) {
            const component = new ComponentPortal(FileDropComponent, null, this._createInjector());
            this.#dropOverlayRef.attach(component);
        }
    }

    closeFileDropOverlay() {
        if (this.#dropOverlayRef) {
            this.#dropOverlayRef.detach();
        }
    }

    toggleImportingRedactions() {
        this.#importingRedactions$.next(!this.#importingRedactions);
    }

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