import * as i0 from '@angular/core';
import { EventEmitter, Directive, Input, Output, Component, NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { isNullOrUndefined } from '@ironsource/fusion-ui/utils';
import { Subject, fromEvent } from 'rxjs';
import { takeUntil } from 'rxjs/operators';

const DRAG_OVER_CSS_CLASS = 'fu-file-drag-over';
const DISABLED_CSS_CLASS = 'fu-file-drag-drop-disabled';
const LOADING_CSS_CLASS = 'fu-file-drag-drop-loading';

/**
 * Directive 'fusionFileDragAndDrop' for file selection by file select dialog
 * or by files drag and drop to the host area
 */
class FileDragAndDropDirective {
    //
    /**
     * for disabling file selection
     */
    set disabled(value) {
        this._disabled = value;
        this.toggleCssClass(DISABLED_CSS_CLASS, this._disabled);
    }
    /**
     * for loading file selection
     */
    set loading(value) {
        this._loading = value;
        this.toggleCssClass(LOADING_CSS_CLASS, this._loading);
    }
    constructor(_element, _renderer) {
        this._element = _element;
        this._renderer = _renderer;
        /**
         * input.file multiple attribute (file select dialog only, not grad&&drop)
         */
        this.multiple = false;
        /**
         * output event emitter (files: FileList)
         */
        this.handleFiles = new EventEmitter();
        this.onDestroy$ = new Subject();
        this._disabled = false;
        this._loading = false;
    }
    ngOnInit() {
        fromEvent(this._element.nativeElement, 'click').pipe(takeUntil(this.onDestroy$)).subscribe(this.onClick.bind(this));
        fromEvent(this._element.nativeElement, 'dragenter').pipe(takeUntil(this.onDestroy$)).subscribe(this.onDragEnter.bind(this));
        fromEvent(this._element.nativeElement, 'dragleave').pipe(takeUntil(this.onDestroy$)).subscribe(this.onDragLeave.bind(this));
        fromEvent(this._element.nativeElement, 'dragover').pipe(takeUntil(this.onDestroy$)).subscribe(this.onDragOver.bind(this));
        fromEvent(this._element.nativeElement, 'drop').pipe(takeUntil(this.onDestroy$)).subscribe(this.onDrop.bind(this));
    }
    ngAfterViewInit() {
        const parent = this._renderer.parentNode(this._element.nativeElement);
        this.inputElement = this._renderer.createElement('input');
        this._renderer.setAttribute(this.inputElement, 'type', 'file');
        this._renderer.setAttribute(this.inputElement, 'name', `input_file_${this.buttonId}`);
        this._renderer.setAttribute(this.inputElement, 'id', `input_file_${this.buttonId}`);
        if (this.multiple) {
            this._renderer.setAttribute(this.inputElement, 'multiple', '');
        }
        if (this.accept) {
            this._renderer.setAttribute(this.inputElement, 'accept', this.accept);
        }
        this._renderer.setStyle(this.inputElement, 'display', 'none');
        fromEvent(this.inputElement, 'change')
            .pipe(takeUntil(this.onDestroy$))
            .subscribe((event) => {
            if (this._disabled) {
                return;
            }
            const target = event.target;
            this.handleFiles.emit(target.files);
            setTimeout(() => {
                // set input value to be empty to fix issue when user tries to upload same file again
                target.value = '';
            }, 1500);
        });
        if (!parent.querySelector(`#input_file_${this.buttonId}`)) {
            this._renderer.appendChild(parent, this.inputElement);
        }
    }
    ngOnDestroy() {
        this.onDestroy$.next();
        this.onDestroy$.complete();
    }
    onDragEnter(event) {
        this.suppressDefaultEvent(event);
        if (this.isDraggable()) {
            this._renderer.addClass(this._element.nativeElement, DRAG_OVER_CSS_CLASS);
        }
    }
    onDragLeave(event) {
        this.suppressDefaultEvent(event);
        if (this.isDraggable() && !event.relatedTarget.closest('[fusionfiledraganddrop]')) {
            this._renderer.removeClass(this._element.nativeElement, DRAG_OVER_CSS_CLASS);
        }
    }
    onDragOver(event) {
        this.suppressDefaultEvent(event);
    }
    onDrop(event) {
        this.suppressDefaultEvent(event);
        if (this.isDraggable()) {
            this._renderer.removeClass(this._element.nativeElement, DRAG_OVER_CSS_CLASS);
            const files = event.dataTransfer.files;
            this.handleFiles.emit(files);
        }
    }
    onClick(event) {
        event.preventDefault();
        event.stopPropagation();
        if (!isNullOrUndefined(this.buttonId) &&
            (!this._disabled || !this._loading) &&
            (event.target.id === this.buttonId || event.target.closest('#' + this.buttonId))) {
            this.inputElement.click();
        }
    }
    suppressDefaultEvent(event) {
        if (event) {
            event.preventDefault();
            event.stopPropagation();
        }
    }
    isDraggable() {
        return !(this._disabled || this._loading);
    }
    toggleCssClass(className, toggled) {
        if (toggled) {
            this._renderer.addClass(this._element.nativeElement, className);
        }
        else {
            this._renderer.removeClass(this._element.nativeElement, className);
        }
    }
    static { this.ɵfac = function FileDragAndDropDirective_Factory(t) { return new (t || FileDragAndDropDirective)(i0.ɵɵdirectiveInject(i0.ElementRef), i0.ɵɵdirectiveInject(i0.Renderer2)); }; }
    static { this.ɵdir = /*@__PURE__*/ i0.ɵɵdefineDirective({ type: FileDragAndDropDirective, selectors: [["", "fusionFileDragAndDrop", ""]], inputs: { buttonId: "buttonId", disabled: "disabled", loading: "loading", accept: "accept", multiple: "multiple" }, outputs: { handleFiles: "handleFiles" } }); }
}
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(FileDragAndDropDirective, [{
        type: Directive,
        args: [{
                selector: '[fusionFileDragAndDrop]'
            }]
    }], () => [{ type: i0.ElementRef }, { type: i0.Renderer2 }], { buttonId: [{
            type: Input
        }], disabled: [{
            type: Input
        }], loading: [{
            type: Input
        }], accept: [{
            type: Input
        }], multiple: [{
            type: Input
        }], handleFiles: [{
            type: Output
        }] }); })();

const _c0 = ["*"];
class FileDragAndDropComponent {
    constructor() {
        /**
         * input.file multiple attribute (file select dialog only, not grad&&drop)
         */
        this.multiple = false;
        /**
         * output event emitter (files: FileList)
         */
        this.handleFiles = new EventEmitter();
    }
    handleSelectedFiles(files) {
        this.handleFiles.emit(files);
    }
    static { this.ɵfac = function FileDragAndDropComponent_Factory(t) { return new (t || FileDragAndDropComponent)(); }; }
    static { this.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: FileDragAndDropComponent, selectors: [["fusion-file-drag-and-drop"]], inputs: { buttonId: "buttonId", disabled: "disabled", loading: "loading", accept: "accept", multiple: "multiple" }, outputs: { handleFiles: "handleFiles" }, ngContentSelectors: _c0, decls: 2, vars: 5, consts: [["fusionFileDragAndDrop", "", 3, "buttonId", "disabled", "loading", "accept", "multiple", "handleFiles"]], template: function FileDragAndDropComponent_Template(rf, ctx) { if (rf & 1) {
            i0.ɵɵprojectionDef();
            i0.ɵɵelementStart(0, "div", 0);
            i0.ɵɵlistener("handleFiles", function FileDragAndDropComponent_Template_div_handleFiles_0_listener($event) { return ctx.handleSelectedFiles($event); });
            i0.ɵɵprojection(1);
            i0.ɵɵelementEnd();
        } if (rf & 2) {
            i0.ɵɵproperty("buttonId", ctx.buttonId)("disabled", ctx.disabled)("loading", ctx.loading)("accept", ctx.accept)("multiple", ctx.multiple);
        } }, dependencies: [FileDragAndDropDirective] }); }
}
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(FileDragAndDropComponent, [{
        type: Component,
        args: [{ selector: 'fusion-file-drag-and-drop', template: "<div fusionFileDragAndDrop\n     [buttonId]=\"buttonId\"\n     [disabled]=\"disabled\"\n     [loading]=\"loading\"\n     [accept]=\"accept\"\n     [multiple]=\"multiple\"\n     (handleFiles)=\"handleSelectedFiles($event)\"\n>\n    <ng-content></ng-content>\n</div>\n" }]
    }], null, { buttonId: [{
            type: Input
        }], disabled: [{
            type: Input
        }], loading: [{
            type: Input
        }], accept: [{
            type: Input
        }], multiple: [{
            type: Input
        }], handleFiles: [{
            type: Output
        }] }); })();
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(FileDragAndDropComponent, { className: "FileDragAndDropComponent", filePath: "file-drag-and-drop.component.ts", lineNumber: 8 }); })();

class FileDragAndDropModule {
    static { this.ɵfac = function FileDragAndDropModule_Factory(t) { return new (t || FileDragAndDropModule)(); }; }
    static { this.ɵmod = /*@__PURE__*/ i0.ɵɵdefineNgModule({ type: FileDragAndDropModule }); }
    static { this.ɵinj = /*@__PURE__*/ i0.ɵɵdefineInjector({ imports: [CommonModule] }); }
}
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(FileDragAndDropModule, [{
        type: NgModule,
        args: [{
                imports: [CommonModule],
                declarations: [FileDragAndDropDirective, FileDragAndDropComponent],
                exports: [FileDragAndDropDirective, FileDragAndDropComponent]
            }]
    }], null, null); })();
(function () { (typeof ngJitMode === "undefined" || ngJitMode) && i0.ɵɵsetNgModuleScope(FileDragAndDropModule, { declarations: [FileDragAndDropDirective, FileDragAndDropComponent], imports: [CommonModule], exports: [FileDragAndDropDirective, FileDragAndDropComponent] }); })();

/**
 * Generated bundle index. Do not edit.
 */

export { FileDragAndDropComponent, FileDragAndDropDirective, FileDragAndDropModule };
//# sourceMappingURL=ironsource-fusion-ui-components-file-drag-and-drop.mjs.map
