import * as i0 from '@angular/core';
import { TemplateRef, Component, Inject, Optional, ViewChild, ContentChild, NgModule } from '@angular/core';
import * as i2 from '@angular/common';
import { CommonModule } from '@angular/common';
import * as i4 from 'ngx-bootstrap/popover';
import { PopoverDirective, PopoverModule as PopoverModule$1 } from 'ngx-bootstrap/popover';
import { PROP_STRING, PROP_ANY, PROP_BOOLEAN, PROP_NUMBER, register, StylableComponent, AUTOCLOSE_TYPE, styler, getContainerTargetClass, provideAsWidgetRef, WmComponentsModule } from '@wm/components/base';
import * as i3 from '@wm/components/basic';
import { BasicModule } from '@wm/components/basic';
import * as i1 from '@wm/core';
import { adjustContainerPosition, adjustContainerRightEdges, findRootContainer, setCSSFromObj, addClass } from '@wm/core';

const registerProps = () => {
    register('wm-popover', new Map([
        ['autoclose', { value: 'outsideClick', ...PROP_STRING }],
        ['badgevalue', PROP_STRING],
        ['caption', { value: 'Link', ...PROP_STRING }],
        ['class', PROP_STRING],
        ['conditionalclass', PROP_ANY],
        ['content', PROP_STRING],
        ['contentanimation', PROP_STRING],
        ['contentsource', { value: 'partial', ...PROP_STRING }],
        ['encodeurl', PROP_BOOLEAN],
        ['hint', PROP_STRING],
        ['arialabel', PROP_STRING],
        ['hyperlink', { value: 'javascript:void(0)', PROP_STRING }],
        ['iconclass', PROP_STRING],
        ['iconheight', PROP_STRING],
        ['iconmargin', PROP_STRING],
        ['iconposition', PROP_STRING],
        ['iconurl', PROP_STRING],
        ['iconwidth', PROP_STRING],
        ['interaction', { value: 'click', ...PROP_STRING }],
        ['name', PROP_STRING],
        ['popoverarrow', { value: true, ...PROP_BOOLEAN }],
        ['popoverheight', PROP_STRING],
        ['popoverplacement', { value: 'bottom', ...PROP_STRING }],
        ['popoverwidth', PROP_STRING],
        ['shortcutkey', PROP_STRING],
        ['show', { value: true, ...PROP_BOOLEAN }],
        ['tabindex', { value: 0, ...PROP_NUMBER }],
        ['title', PROP_STRING],
        ['adaptiveposition', { value: true, ...PROP_BOOLEAN }]
    ]));
};

const _c0 = ["partial"];
const _c1 = ["anchor"];
const _c2 = a0 => ({ "disable-popover": a0 });
const DEFAULT_CLS = 'app-popover-wrapper';
const WIDGET_CONFIG = {
    widgetType: 'wm-popover',
    hostClass: DEFAULT_CLS
};
const eventsMap = {
    click: 'click',
    hover: 'mouseenter:click',
    default: 'click mouseenter'
};
let activePopover;
class PopoverComponent extends StylableComponent {
    static { this.initializeProps = registerProps(); }
    static { this.activePopovers = []; }
    constructor(inj, app, explicitContext, cdr) {
        super(inj, WIDGET_CONFIG, explicitContext);
        this.app = app;
        this.cdr = cdr;
        this.isOpen = false;
        this.canPopoverOpen = true;
        this.isClosingProgrammatically = false;
        this.popoverContainerCls = `app-popover-${this.widgetId}`;
    }
    setupDocumentClickHandler() {
        if (this.documentClickHandler) {
            document.removeEventListener('click', this.documentClickHandler, true);
        }
        this.documentClickHandler = (event) => {
            if (!this.isOpen)
                return;
            const target = event.target;
            // Check if the clicked element or any of its parents is part of the datepicker, dropdown, or typeahead containers
            const isInsideSpecialContainer = !!(target.closest('.bs-datepicker-container') ||
                target.closest(".dropdown-menu"));
            if (isInsideSpecialContainer) {
                // If the click was inside one of these containers, we do not close the popover
                return;
            }
            const clickedPopoverIndex = PopoverComponent.activePopovers.findIndex(popover => {
                const popoverContainer = document.querySelector(`.${popover.popoverContainerCls}`);
                return popoverContainer?.contains(target);
            });
            if (this.anchorRef.nativeElement.contains(target)) {
                event.preventDefault();
                event.stopPropagation();
                this.isOpen ? this.close() : this.open();
                return;
            }
            if (clickedPopoverIndex === -1) {
                // Click is outside all popovers
                if (this.outsideclick) {
                    this.closeAllPopovers();
                }
            }
            else {
                // Click is inside a popover
                this.closeInnerPopovers(clickedPopoverIndex);
            }
        };
        document.addEventListener('click', this.documentClickHandler, true);
    }
    closeAllPopovers() {
        PopoverComponent.activePopovers.forEach(popover => {
            if (popover.outsideclick) {
                popover.isClosingProgrammatically = true;
                popover.close();
            }
        });
    }
    closeInnerPopovers(clickedIndex) {
        for (let i = clickedIndex + 1; i < PopoverComponent.activePopovers.length; i++) {
            const popover = PopoverComponent.activePopovers[i];
            if (popover.outsideclick) {
                popover.isClosingProgrammatically = true;
                popover.close();
            }
        }
    }
    isChildPopover() {
        return !!$(this.nativeElement).closest('.popover').length;
    }
    // This mehtod is used to show/open the popover. This refers to the same method showPopover.
    open() {
        this.showPopover();
        if (!PopoverComponent.activePopovers.includes(this)) {
            PopoverComponent.activePopovers.push(this);
        }
        this.cdr.detectChanges();
    }
    // This mehtod is used to hide/close the popover.
    close() {
        if (this.isOpen) {
            this.isClosingProgrammatically = true;
            this.isOpen = false;
            this.bsPopoverDirective.hide();
            const index = PopoverComponent.activePopovers.indexOf(this);
            if (index > -1) {
                PopoverComponent.activePopovers.splice(index, 1);
            }
            this.cdr.detectChanges();
        }
    }
    // Trigger on hiding popover
    onHidden() {
        if (!this.isChildPopover() || this.isClosingProgrammatically) {
            this.invokeEventCallback('hide', { $event: { type: 'hide' } });
            this.isOpen = false;
            if (activePopover === this) {
                activePopover = null;
            }
        }
        this.isClosingProgrammatically = false;
    }
    setFocusToPopoverLink() {
        setTimeout(() => this.anchorRef.nativeElement.focus(), 10);
    }
    adjustPopoverArrowPosition(popoverElem, popoverLeftShift) {
        this.bsPopoverDirective._popover._ngZone.onStable.subscribe(() => {
            popoverElem.find('.popover-arrow').css('left', popoverLeftShift + 'px');
        });
    }
    calculatePopoverPostion(element) {
        const popoverElem = $(element);
        let popoverLeft = popoverElem.offset().left;
        const popoverWidth = popoverElem[0].offsetWidth;
        const viewPortWidth = $(window).width();
        const parentDimesion = this.anchorRef.nativeElement.getBoundingClientRect();
        // Adjusting popover position, if it is not visible at left side
        if (popoverLeft < 0) {
            adjustContainerPosition(popoverElem, this.nativeElement, this.bsPopoverDirective._popover);
            const popoverLeftShift = 4;
            const arrowLeftShift = (parentDimesion.left + (parentDimesion.width / 2)) - popoverLeftShift;
            this.adjustPopoverArrowPosition(popoverElem, arrowLeftShift);
        }
        // Adjusting popover position, if it is not visible at right side
        if (popoverLeft + popoverWidth > viewPortWidth) {
            adjustContainerRightEdges(popoverElem, this.nativeElement, this.bsPopoverDirective._popover);
            setTimeout(() => {
                popoverLeft = popoverElem.offset().left;
                const popoverLeftAdjust = (popoverLeft + popoverWidth) - viewPortWidth;
                const popoverLeftShift = popoverLeft - popoverLeftAdjust;
                let arrowLeftShift;
                if (popoverLeft <= 100) {
                    arrowLeftShift = (parentDimesion.left + (parentDimesion.width / 2)) - popoverLeft;
                }
                else {
                    arrowLeftShift = (parentDimesion.left + (parentDimesion.width / 2)) - popoverLeftShift;
                }
                if (viewPortWidth > 500) {
                    arrowLeftShift += 30;
                }
                this.adjustPopoverArrowPosition(popoverElem, arrowLeftShift);
            });
        }
    }
    // Trigger on showing popover
    onShown() {
        const root = findRootContainer(this.$element);
        // if page styles have to be applied to popover then popover has to be child of page element.
        if (root) {
            $('body > popover-container').wrap('<' + root + '/>');
        }
        // Fix for [WMS-25125]: Not closing the existing opened popovers when the autoclose property is DISABLED
        if (!this.isChildPopover()) {
            if (activePopover && activePopover !== this &&
                activePopover.autoclose !== AUTOCLOSE_TYPE.DISABLED) {
                activePopover.isClosingProgrammatically = true;
                activePopover.close();
            }
            activePopover = this;
        }
        this.isOpen = true;
        if (!PopoverComponent.activePopovers.includes(this)) {
            PopoverComponent.activePopovers.push(this);
        }
        const popoverContainer = document.querySelector(`.${this.popoverContainerCls}`);
        if (popoverContainer) {
            popoverContainer.setAttribute('data-popover-id', this.widgetId);
            // Add click event listener to stop propagation
            popoverContainer.addEventListener('click', (event) => {
                event.stopPropagation();
            });
        }
        setCSSFromObj(popoverContainer, {
            height: this.popoverheight,
            minWidth: this.popoverwidth,
            width: this.popoverwidth
        });
        if (!this.popoverarrow) {
            addClass(popoverContainer.querySelector('.arrow'), 'hidden');
        }
        if (this.interaction === 'hover' || this.interaction === 'default') {
            // do not use addEventListener here
            // attaching the event this way will override the existing event handlers
            popoverContainer.onmouseenter = () => clearTimeout(this.closePopoverTimeout);
            popoverContainer.onmouseleave = () => this.hidePopover();
            this.anchorRef.nativeElement.onmouseenter = () => clearTimeout(this.closePopoverTimeout);
            this.anchorRef.nativeElement.onmouseleave = () => this.hidePopover();
        }
        if (this.outsideclick) {
            this.setupDocumentClickHandler();
        }
        setTimeout(() => {
            this.anchorRef.nativeElement.removeAttribute('aria-describedby');
        });
        const deRegister = this.eventManager.addEventListener(popoverContainer, 'keydown.esc', () => {
            this.isOpen = false;
            this.setFocusToPopoverLink();
            deRegister();
        });
        const popoverStartBtn = popoverContainer.querySelector('.popover-start');
        const popoverEndBtn = popoverContainer.querySelector('.popover-end');
        popoverStartBtn.onkeydown = (event) => {
            // Check for Shift+Tab key
            if (event.shiftKey && event.key === 'Tab') {
                this.bsPopoverDirective.hide();
                event.preventDefault();
                this.setFocusToPopoverLink();
                this.isOpen = false;
            }
        };
        popoverEndBtn.onkeydown = (event) => {
            // Check for Tab key
            if (!event.shiftKey && event.key === 'Tab') {
                this.bsPopoverDirective.hide();
                event.preventDefault();
                this.setFocusToPopoverLink();
                this.isOpen = false;
            }
        };
        //Whenever autoclose property is set to 'always', adding the onclick listener to the popover container to close the popover.
        if (this.autoclose === AUTOCLOSE_TYPE.ALWAYS) {
            popoverContainer.onclick = () => this.close();
        }
        setTimeout(() => popoverStartBtn.focus(), 50);
        // Adjusting popover position if the popover placement is top or bottom
        setTimeout(() => {
            if (!this.adaptiveposition) {
                this.calculatePopoverPostion(popoverContainer);
            }
            // triggering onload and onshow events after popover content has rendered
            this.triggerPopoverEvents();
        });
    }
    triggerPopoverEvents() {
        if (this.contentsource === 'partial') {
            const cancelSubscription = this.app.subscribe('partialLoaded', (data) => {
                const parEle = this.partialRef.nativeElement;
                let partialScope;
                if (parEle) {
                    partialScope = parEle.widget;
                    this.Widgets = partialScope.Widgets;
                    this.Variables = partialScope.Variables;
                    this.Actions = partialScope.Actions;
                    this.invokeEventCallback('load');
                    this.invokeEventCallback('show', { $event: { type: 'show' } });
                }
                cancelSubscription();
            });
        }
        else {
            this.Widgets = this.viewParent.Widgets;
            this.Variables = this.viewParent.Variables;
            this.Actions = this.viewParent.Actions;
            this.invokeEventCallback('show', { $event: { type: 'show' } });
        }
    }
    hidePopover() {
        this.isClosingProgrammatically = true;
        this.closePopoverTimeout = setTimeout(() => this.isOpen = false, 500);
    }
    showPopover() {
        this.bsPopoverDirective.show();
    }
    onPopoverAnchorKeydown($event) {
        // if there is no content available, the popover should not open through enter key. So checking whether the canPopoverOpen flag is true or not.
        if (!this.canPopoverOpen) {
            return;
        }
        if ($event.key === 'Enter') {
            $event.stopPropagation();
            $event.preventDefault();
            this.showPopover();
        }
    }
    onPropertyChange(key, nv, ov) {
        if (key === 'class' || key === 'tabindex') {
            return;
        }
        if (key === 'contentsource') {
            // if there is no partial content available, the popover should not open
            if (this.contentsource === 'partial' && !this.content) {
                this.canPopoverOpen = false;
            }
        }
        if (key === 'content' && nv) {
            this.canPopoverOpen = true;
        }
        if (key === 'autoclose') {
            this.outsideclick = (nv === AUTOCLOSE_TYPE.OUTSIDECLICK || nv === AUTOCLOSE_TYPE.ALWAYS) ? true : false;
        }
        super.onPropertyChange(key, nv, ov);
    }
    ngOnInit() {
        super.ngOnInit();
        this.event = eventsMap[this.interaction];
    }
    ngAfterViewInit() {
        super.ngAfterViewInit();
        styler(this.anchorRef.nativeElement, this);
        this.containerTarget = getContainerTargetClass(this.nativeElement);
        // let parentElemPopover = $(this.nativeElement).parents();
        // if (parentElemPopover.closest('[wmTable]').length ||
        //     parentElemPopover.closest('[wmtabs]').length ||
        //     parentElemPopover.closest('modal-container').length) {
        //     this.adaptiveposition = false;
        // }
    }
    ngOnDetach() {
        // Hide the popover container while attaching the next component as part of page reuse strategy.
        this.bsPopoverDirective.hide();
    }
    OnDestroy() {
        if (this.documentClickHandler) {
            document.removeEventListener('click', this.documentClickHandler, true);
        }
        const index = PopoverComponent.activePopovers.indexOf(this);
        if (index > -1) {
            PopoverComponent.activePopovers.splice(index, 1);
        }
    }
    static { this.ɵfac = function PopoverComponent_Factory(t) { return new (t || PopoverComponent)(i0.ɵɵdirectiveInject(i0.Injector), i0.ɵɵdirectiveInject(i1.App), i0.ɵɵdirectiveInject('EXPLICIT_CONTEXT', 8), i0.ɵɵdirectiveInject(i0.ChangeDetectorRef)); }; }
    static { this.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: PopoverComponent, selectors: [["wm-popover"]], contentQueries: function PopoverComponent_ContentQueries(rf, ctx, dirIndex) { if (rf & 1) {
            i0.ɵɵcontentQuery(dirIndex, TemplateRef, 5);
            i0.ɵɵcontentQuery(dirIndex, _c0, 5);
        } if (rf & 2) {
            let _t;
            i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.popoverTemplate = _t.first);
            i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.partialRef = _t.first);
        } }, viewQuery: function PopoverComponent_Query(rf, ctx) { if (rf & 1) {
            i0.ɵɵviewQuery(PopoverDirective, 5);
            i0.ɵɵviewQuery(_c1, 7);
        } if (rf & 2) {
            let _t;
            i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.bsPopoverDirective = _t.first);
            i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.anchorRef = _t.first);
        } }, features: [i0.ɵɵProvidersFeature([
                provideAsWidgetRef(PopoverComponent)
            ]), i0.ɵɵInheritDefinitionFeature], decls: 2, vars: 21, consts: [["anchor", ""], ["boundariesElement", "window", "role", "button", "name.bind", "name", "wmAnchor", "", "animation.bind", "animation", "badgevalue.bind", "badgevalue", "caption.bind", "caption", "encodeurl.bind", "encodeurl", "hint.bind", "hint", "hyperlink.bind", "hyperlink", "iconurl.bind", "iconurl", "iconwidth.bind", "iconwidth", "iconheight.bind", "iconheight", "iconmargin.bind", "iconmargin", "iconclass.bind", "iconclass", "iconposition.bind", "iconposition", "shortcutkey.bind", "shortcutkey", "tabindex.bind", "tabindex", 3, "onShown", "onHidden", "keydown", "popover", "popoverContext", "popoverTitle", "placement", "outsideClick", "triggers", "containerClass", "container", "isOpen", "tabindex", "name", "ngClass", "adaptivePosition"]], template: function PopoverComponent_Template(rf, ctx) { if (rf & 1) {
            const _r1 = i0.ɵɵgetCurrentView();
            i0.ɵɵelementStart(0, "a", 1, 0);
            i0.ɵɵlistener("onShown", function PopoverComponent_Template_a_onShown_0_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onShown()); })("onHidden", function PopoverComponent_Template_a_onHidden_0_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onHidden()); })("keydown", function PopoverComponent_Template_a_keydown_0_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onPopoverAnchorKeydown($event)); });
            i0.ɵɵelementEnd();
        } if (rf & 2) {
            i0.ɵɵclassMap(ctx.class);
            i0.ɵɵpropertyInterpolate2("containerClass", "app-popover animated ", ctx.contentanimation, " ", ctx.popoverContainerCls, "");
            i0.ɵɵproperty("popover", ctx.popoverTemplate)("popoverContext", ctx.context)("popoverTitle", ctx.title)("placement", ctx.popoverplacement)("outsideClick", ctx.outsideclick)("triggers", ctx.event)("container", ctx.containerTarget || ".wm-app")("isOpen", ctx.isOpen)("tabindex", ctx.tabindex)("name", ctx.name)("ngClass", i0.ɵɵpureFunction1(19, _c2, !ctx.canPopoverOpen))("adaptivePosition", ctx.adaptiveposition);
            i0.ɵɵattribute("aria-label", ctx.arialabel || (ctx.badgevalue ? ctx.caption + " " + ctx.badgevalue : ctx.caption) || "Popover menu")("aria-expanded", ctx.isOpen);
        } }, dependencies: [i2.NgClass, i3.AnchorComponent, i4.PopoverDirective], encapsulation: 2 }); }
}
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(PopoverComponent, [{
        type: Component,
        args: [{ selector: 'wm-popover', providers: [
                    provideAsWidgetRef(PopoverComponent)
                ], template: "<a [popover]=\"popoverTemplate\"\n    [popoverContext]=\"context\"\n    [popoverTitle]=\"title\"\n    [placement]=\"popoverplacement\"\n    [outsideClick]=\"outsideclick\"\n    [triggers]=\"event\"\n    (onShown)=\"onShown()\"\n    (onHidden)=\"onHidden()\"\n    containerClass=\"app-popover animated {{contentanimation}} {{popoverContainerCls}}\"\n    [container]=\"containerTarget || '.wm-app'\"\n    [isOpen]=\"isOpen\"\n    [tabindex]=\"tabindex\"\n    [name]=\"name\"\n    [class]=\"class\"\n    [ngClass]=\"{'disable-popover': !canPopoverOpen}\"\n    [adaptivePosition]=\"adaptiveposition\"\n   boundariesElement=\"window\"\n   [attr.aria-label]=\"arialabel || (badgevalue ? caption + ' ' + badgevalue : caption) || 'Popover menu'\"\n    [attr.aria-expanded]=\"isOpen\"\n    role=\"button\"\n    #anchor\n    name.bind=\"name\"\n    wmAnchor\n    animation.bind=\"animation\"\n    badgevalue.bind=\"badgevalue\"\n    caption.bind=\"caption\"\n    encodeurl.bind=\"encodeurl\"\n    hint.bind=\"hint\"\n    hyperlink.bind=\"hyperlink\"\n    iconurl.bind=\"iconurl\"\n    iconwidth.bind=\"iconwidth\"\n    iconheight.bind=\"iconheight\"\n    iconmargin.bind=\"iconmargin\"\n    iconclass.bind=\"iconclass\"\n    iconposition.bind=\"iconposition\"\n    shortcutkey.bind=\"shortcutkey\"\n    tabindex.bind=\"tabindex\"\n    (keydown)=\"onPopoverAnchorKeydown($event)\">\n</a>\n" }]
    }], () => [{ type: i0.Injector }, { type: i1.App }, { type: undefined, decorators: [{
                type: Inject,
                args: ['EXPLICIT_CONTEXT']
            }, {
                type: Optional
            }] }, { type: i0.ChangeDetectorRef }], { bsPopoverDirective: [{
            type: ViewChild,
            args: [PopoverDirective]
        }], anchorRef: [{
            type: ViewChild,
            args: ['anchor', { static: true }]
        }], popoverTemplate: [{
            type: ContentChild,
            args: [TemplateRef]
        }], partialRef: [{
            type: ContentChild,
            args: ['partial']
        }] }); })();
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(PopoverComponent, { className: "PopoverComponent", filePath: "popover.component.ts", lineNumber: 60 }); })();

const components = [
    PopoverComponent
];
class PopoverModule {
    static { this.ɵfac = function PopoverModule_Factory(t) { return new (t || PopoverModule)(); }; }
    static { this.ɵmod = /*@__PURE__*/ i0.ɵɵdefineNgModule({ type: PopoverModule }); }
    static { this.ɵinj = /*@__PURE__*/ i0.ɵɵdefineInjector({ imports: [CommonModule,
            BasicModule,
            PopoverModule$1,
            WmComponentsModule] }); }
}
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(PopoverModule, [{
        type: NgModule,
        args: [{
                imports: [
                    CommonModule,
                    BasicModule,
                    PopoverModule$1,
                    WmComponentsModule
                ],
                declarations: [...components],
                exports: [...components]
            }]
    }], null, null); })();
(function () { (typeof ngJitMode === "undefined" || ngJitMode) && i0.ɵɵsetNgModuleScope(PopoverModule, { declarations: [PopoverComponent], imports: [CommonModule,
        BasicModule,
        PopoverModule$1,
        WmComponentsModule], exports: [PopoverComponent] }); })();

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

export { PopoverComponent, PopoverModule };
//# sourceMappingURL=index.mjs.map
