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

class ClickOutsideDirective {
    set clickOutsideActivate(value) {
        this.listenClickOutside$.next(value);
    }
    /**
     * Use this when the click event will remove the host element from the DOM
     * @param value
     */
    set clickOutsideByCoordinates(value) {
        this.byCoordinatesMode = value;
    }
    constructor(elementRef) {
        this.elementRef = elementRef;
        this.fusionClickOutside = new EventEmitter();
        this.onDestroy$ = new Subject();
        this.listenClickOutside$ = new BehaviorSubject(true);
        this.byCoordinatesMode = false;
    }
    ngOnInit() {
        this.listenClickOutside$.asObservable().pipe(takeUntil(this.onDestroy$)).subscribe(this.handleClickOutSideListener.bind(this));
    }
    ngOnDestroy() {
        this.onDestroy$.next();
        this.onDestroy$.complete();
    }
    handleClickOutSideListener(value) {
        if (value && !this.clickOutSideSubscription) {
            this.clickOutSideSubscription = fromEvent(document, 'click').subscribe((event) => {
                const clickedInside = this.byCoordinatesMode && event.clientY !== 0 && event.clientY !== 0
                    ? this.isClickInsideByCoordinates(event)
                    : this.isInsideByTargetPath(event);
                if (!clickedInside) {
                    this.fusionClickOutside.emit(event.target);
                }
            });
        }
        else {
            if (this.clickOutSideSubscription && typeof this.clickOutSideSubscription.unsubscribe === 'function') {
                this.clickOutSideSubscription.unsubscribe();
                this.clickOutSideSubscription = null;
            }
        }
    }
    isClickInsideByCoordinates(event) {
        const parentRect = this.elementRef.nativeElement.getBoundingClientRect();
        return (parentRect.left <= event.clientX &&
            parentRect.right >= event.clientX &&
            parentRect.top <= event.clientY &&
            parentRect.bottom >= event.clientY);
    }
    isInsideByTargetPath(event) {
        if (isFunction(event.composedPath)) {
            const elements = event.composedPath();
            return elements.some(el => {
                return el == this.elementRef.nativeElement;
            });
        }
        else {
            return this.elementRef.nativeElement.contains(this.getEventElement(event));
        }
    }
    getEventElement(event) {
        let element;
        console.log('--', this.elementRef.nativeElement, event.composedPath());
        if (isFunction(event.composedPath)) {
            // event.composedPath()[0] support opened shadow root
            const elements = event.composedPath();
            elements.forEach(el => {
                console.log(':', el, el == this.elementRef.nativeElement);
            });
            element = elements.length > 0 ? elements[0] : null;
        }
        return element || event.target;
    }
    static { this.ɵfac = function ClickOutsideDirective_Factory(t) { return new (t || ClickOutsideDirective)(i0.ɵɵdirectiveInject(i0.ElementRef)); }; }
    static { this.ɵdir = /*@__PURE__*/ i0.ɵɵdefineDirective({ type: ClickOutsideDirective, selectors: [["", "fusionClickOutside", ""]], inputs: { clickOutsideActivate: "clickOutsideActivate", clickOutsideByCoordinates: "clickOutsideByCoordinates" }, outputs: { fusionClickOutside: "fusionClickOutside" } }); }
}
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ClickOutsideDirective, [{
        type: Directive,
        args: [{
                selector: '[fusionClickOutside]'
            }]
    }], () => [{ type: i0.ElementRef }], { clickOutsideActivate: [{
            type: Input
        }], clickOutsideByCoordinates: [{
            type: Input
        }], fusionClickOutside: [{
            type: Output
        }] }); })();

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

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

export { ClickOutsideDirective, ClickOutsideModule };
//# sourceMappingURL=ironsource-fusion-ui-directives-click-outside.mjs.map
