import { Overlay } from '@angular/cdk/overlay';
import { ComponentPortal } from '@angular/cdk/portal';
import * as i0 from '@angular/core';
import { input, signal, inject, ElementRef, TemplateRef, Component, computed, booleanAttribute, output, HostListener, Directive, NgModule } from '@angular/core';
import { calculateOverlayArrowPosition, hasTrigger, getOverlay, getPositionStrategy } from '@siemens/element-ng/common';
import { Subject, takeUntil } from 'rxjs';
import { NgTemplateOutlet } from '@angular/common';
import { SiIconComponent } from '@siemens/element-ng/icon';

class PopoverComponent {
    popover = input(...(ngDevMode ? [undefined, { debugName: "popover" }] : []));
    /** @defaultValue '' */
    popoverTitle = input('', ...(ngDevMode ? [{ debugName: "popoverTitle" }] : []));
    /** @defaultValue '' */
    containerClass = input('', ...(ngDevMode ? [{ debugName: "containerClass" }] : []));
    icon = input(...(ngDevMode ? [undefined, { debugName: "icon" }] : []));
    popoverContext = input(...(ngDevMode ? [undefined, { debugName: "popoverContext" }] : []));
    positionClass = signal('', ...(ngDevMode ? [{ debugName: "positionClass" }] : []));
    arrowPos = signal(undefined, ...(ngDevMode ? [{ debugName: "arrowPos" }] : []));
    popoverTemplate = null;
    elementRef = inject(ElementRef);
    ngOnInit() {
        const popover = this.popover();
        if (popover instanceof TemplateRef) {
            this.popoverTemplate = popover;
        }
    }
    /** @internal */
    updateArrow(change, anchor) {
        const positionClass = `popover-${change.connectionPair.overlayX}-${change.connectionPair.overlayY}`;
        // need two updates as class changes affect the position
        this.positionClass.set(positionClass);
        const arrowPos = calculateOverlayArrowPosition(change, this.elementRef, anchor);
        this.arrowPos.set(arrowPos);
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: PopoverComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
    static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.8", type: PopoverComponent, isStandalone: true, selector: "si-popover", inputs: { popover: { classPropertyName: "popover", publicName: "popover", isSignal: true, isRequired: false, transformFunction: null }, popoverTitle: { classPropertyName: "popoverTitle", publicName: "popoverTitle", isSignal: true, isRequired: false, transformFunction: null }, containerClass: { classPropertyName: "containerClass", publicName: "containerClass", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, popoverContext: { classPropertyName: "popoverContext", publicName: "popoverContext", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div\n  class=\"popover position-relative focus-outline-padding\"\n  [class]=\"[containerClass(), positionClass()]\"\n>\n  <div\n    class=\"popover-arrow\"\n    [style.left.px]=\"arrowPos()?.left\"\n    [style.right.px]=\"arrowPos()?.right\"\n  ></div>\n  @if (popoverTitle()) {\n    <div class=\"popover-header\">\n      @let iconValue = icon();\n      @if (iconValue) {\n        <si-icon class=\"icon me-2\" [icon]=\"iconValue\" />\n      }\n      <span class=\"si-h5\">{{ popoverTitle() }}</span>\n    </div>\n  }\n  <div class=\"popover-body\">\n    @if (!popoverTemplate) {\n      <div class=\"si-body\" [innerHTML]=\"popover()\"></div>\n    } @else {\n      <ng-template\n        [ngTemplateOutlet]=\"popoverTemplate\"\n        [ngTemplateOutletContext]=\"popoverContext()\"\n      />\n    }\n  </div>\n</div>\n", dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: SiIconComponent, selector: "si-icon", inputs: ["icon"] }] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: PopoverComponent, decorators: [{
            type: Component,
            args: [{ selector: 'si-popover', imports: [NgTemplateOutlet, SiIconComponent], template: "<div\n  class=\"popover position-relative focus-outline-padding\"\n  [class]=\"[containerClass(), positionClass()]\"\n>\n  <div\n    class=\"popover-arrow\"\n    [style.left.px]=\"arrowPos()?.left\"\n    [style.right.px]=\"arrowPos()?.right\"\n  ></div>\n  @if (popoverTitle()) {\n    <div class=\"popover-header\">\n      @let iconValue = icon();\n      @if (iconValue) {\n        <si-icon class=\"icon me-2\" [icon]=\"iconValue\" />\n      }\n      <span class=\"si-h5\">{{ popoverTitle() }}</span>\n    </div>\n  }\n  <div class=\"popover-body\">\n    @if (!popoverTemplate) {\n      <div class=\"si-body\" [innerHTML]=\"popover()\"></div>\n    } @else {\n      <ng-template\n        [ngTemplateOutlet]=\"popoverTemplate\"\n        [ngTemplateOutletContext]=\"popoverContext()\"\n      />\n    }\n  </div>\n</div>\n" }]
        }], propDecorators: { popover: [{ type: i0.Input, args: [{ isSignal: true, alias: "popover", required: false }] }], popoverTitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "popoverTitle", required: false }] }], containerClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "containerClass", required: false }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], popoverContext: [{ type: i0.Input, args: [{ isSignal: true, alias: "popoverContext", required: false }] }] } });

/**
 * Copyright (c) Siemens 2016 - 2026
 * SPDX-License-Identifier: MIT
 */
/**
 * @deprecated Use {@link SiPopoverDirective} instead.
 */
class SiPopoverLegacyDirective {
    /**
     * The popover text to be displayed
     */
    siPopoverLegacy = input(...(ngDevMode ? [undefined, { debugName: "siPopoverLegacy" }] : []));
    /**
     * The placement of the popover. One of 'top', 'start', end', 'bottom'
     *
     * @defaultValue 'auto'
     */
    placement = input('auto', ...(ngDevMode ? [{ debugName: "placement" }] : []));
    placementInternal = computed(() => {
        if (this.placement() !== 'top' &&
            this.placement() !== 'bottom' &&
            this.placement() !== 'start' &&
            this.placement() !== 'end') {
            return 'auto';
        }
        else {
            return this.placement();
        }
    }, ...(ngDevMode ? [{ debugName: "placementInternal" }] : []));
    /**
     * The trigger event(s) on which the popover shall be displayed.
     * Applications can pass multiple triggers separated by space.
     * Supported events are 'click', 'hover' and 'focus'.
     *
     * **Limitations:**
     * Safari browsers do not raise a 'focus' event on host element click and 'focus'
     * on tab key has to be enabled in the advanced browser settings.
     *
     * @defaultValue 'click'
     */
    triggers = input('click', ...(ngDevMode ? [{ debugName: "triggers" }] : []));
    /**
     * The title to be displayed on top for the popover
     *
     * @defaultValue ''
     */
    popoverTitle = input('', ...(ngDevMode ? [{ debugName: "popoverTitle" }] : []));
    /**
     * The class that will be applied to container of the popover
     *
     * @defaultValue ''
     */
    containerClass = input('', ...(ngDevMode ? [{ debugName: "containerClass" }] : []));
    /**
     * The flag determines whether to close popover on clicking outside
     *
     * @defaultValue true
     */
    outsideClick = input(true, { ...(ngDevMode ? { debugName: "outsideClick" } : {}), transform: booleanAttribute });
    /**
     * The icon to be displayed besides popover title
     */
    icon = input(...(ngDevMode ? [undefined, { debugName: "icon" }] : []));
    /**
     * Specify whether or not the popover is currently shown
     *
     * @defaultValue false
     */
    isOpen = input(false, { ...(ngDevMode ? { debugName: "isOpen" } : {}), transform: booleanAttribute });
    /**
     * The context for the attached template
     */
    popoverContext = input(...(ngDevMode ? [undefined, { debugName: "popoverContext" }] : []));
    /**
     * Emits an event when the popover is shown
     */
    shown = output();
    /**
     * Emits an event when the popover is hidden
     */
    hidden = output();
    overlayref;
    overlay = inject(Overlay);
    elementRef = inject(ElementRef);
    destroyer = new Subject();
    ngOnInit() {
        if (this.isOpen()) {
            this.show();
        }
    }
    ngOnDestroy() {
        this.overlayref?.dispose();
        this.destroyer.next();
        this.destroyer.complete();
    }
    /**
     * Displays popover and emits 'shown' event.
     */
    show() {
        if (!this.overlayref?.hasAttached()) {
            const triggers = this.triggers();
            const backdrop = this.outsideClick() && !hasTrigger('focus', triggers) && !hasTrigger('hover', triggers);
            this.overlayref = getOverlay(this.elementRef, this.overlay, backdrop, this.placementInternal());
            if (backdrop) {
                this.overlayref
                    .backdropClick()
                    .pipe(takeUntil(this.destroyer))
                    .subscribe(() => this.hide());
            }
        }
        if (this.overlayref.hasAttached()) {
            return;
        }
        const popoverPortal = new ComponentPortal(PopoverComponent);
        const popoverRef = this.overlayref.attach(popoverPortal);
        popoverRef.setInput('popover', this.siPopoverLegacy());
        popoverRef.setInput('popoverTitle', this.popoverTitle());
        popoverRef.setInput('icon', this.icon());
        popoverRef.setInput('containerClass', this.containerClass());
        popoverRef.setInput('popoverContext', this.popoverContext());
        const positionStrategy = getPositionStrategy(this.overlayref);
        positionStrategy?.positionChanges
            .pipe(takeUntil(this.destroyer))
            .subscribe(change => popoverRef.instance.updateArrow(change, this.elementRef));
        this.shown.emit();
    }
    /**
     * Hides the popover and emits 'hidden' event.
     */
    hide() {
        if (this.overlayref?.hasAttached()) {
            this.overlayref?.detach();
            this.hidden.emit();
            this.destroyer.next();
        }
    }
    /**
     * Updates the position of the popover based on the position strategy.
     */
    updatePosition() {
        this.overlayref?.updatePosition();
    }
    onTrigger(trigger) {
        if (hasTrigger(trigger, this.triggers())) {
            if (this.overlayref?.hasAttached()) {
                this.hide();
            }
            else {
                this.show();
            }
        }
    }
    focusOut() {
        if (hasTrigger('focus', this.triggers())) {
            if (this.outsideClick()) {
                this.hide();
            }
        }
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: SiPopoverLegacyDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
    static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.0.8", type: SiPopoverLegacyDirective, isStandalone: true, selector: "[siPopoverLegacy]", inputs: { siPopoverLegacy: { classPropertyName: "siPopoverLegacy", publicName: "siPopoverLegacy", isSignal: true, isRequired: false, transformFunction: null }, placement: { classPropertyName: "placement", publicName: "placement", isSignal: true, isRequired: false, transformFunction: null }, triggers: { classPropertyName: "triggers", publicName: "triggers", isSignal: true, isRequired: false, transformFunction: null }, popoverTitle: { classPropertyName: "popoverTitle", publicName: "popoverTitle", isSignal: true, isRequired: false, transformFunction: null }, containerClass: { classPropertyName: "containerClass", publicName: "containerClass", isSignal: true, isRequired: false, transformFunction: null }, outsideClick: { classPropertyName: "outsideClick", publicName: "outsideClick", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, isOpen: { classPropertyName: "isOpen", publicName: "isOpen", isSignal: true, isRequired: false, transformFunction: null }, popoverContext: { classPropertyName: "popoverContext", publicName: "popoverContext", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { shown: "shown", hidden: "hidden" }, host: { listeners: { "mouseenter": "onTrigger(\"hover\")", "mouseleave": "onTrigger(\"hover\")", "focus": "onTrigger(\"focus\")", "click": "onTrigger(\"click\")", "touchstart": "focusOut()", "focusout": "focusOut()" } }, exportAs: ["si-popover"], ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: SiPopoverLegacyDirective, decorators: [{
            type: Directive,
            args: [{
                    selector: '[siPopoverLegacy]',
                    exportAs: 'si-popover'
                }]
        }], propDecorators: { siPopoverLegacy: [{ type: i0.Input, args: [{ isSignal: true, alias: "siPopoverLegacy", required: false }] }], placement: [{ type: i0.Input, args: [{ isSignal: true, alias: "placement", required: false }] }], triggers: [{ type: i0.Input, args: [{ isSignal: true, alias: "triggers", required: false }] }], popoverTitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "popoverTitle", required: false }] }], containerClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "containerClass", required: false }] }], outsideClick: [{ type: i0.Input, args: [{ isSignal: true, alias: "outsideClick", required: false }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], isOpen: [{ type: i0.Input, args: [{ isSignal: true, alias: "isOpen", required: false }] }], popoverContext: [{ type: i0.Input, args: [{ isSignal: true, alias: "popoverContext", required: false }] }], shown: [{ type: i0.Output, args: ["shown"] }], hidden: [{ type: i0.Output, args: ["hidden"] }], onTrigger: [{
                type: HostListener,
                args: ['mouseenter', ['"hover"']]
            }, {
                type: HostListener,
                args: ['mouseleave', ['"hover"']]
            }, {
                type: HostListener,
                args: ['focus', ['"focus"']]
            }, {
                type: HostListener,
                args: ['click', ['"click"']]
            }], focusOut: [{
                type: HostListener,
                args: ['touchstart']
            }, {
                type: HostListener,
                args: ['focusout']
            }] } });

/**
 * Copyright (c) Siemens 2016 - 2026
 * SPDX-License-Identifier: MIT
 */
/**
 * @deprecated Use {@link SiPopoverDirective} instead.
 */
class SiPopoverLegacyModule {
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: SiPopoverLegacyModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
    static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.0.8", ngImport: i0, type: SiPopoverLegacyModule, imports: [SiPopoverLegacyDirective], exports: [SiPopoverLegacyDirective] });
    static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: SiPopoverLegacyModule });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.8", ngImport: i0, type: SiPopoverLegacyModule, decorators: [{
            type: NgModule,
            args: [{
                    imports: [SiPopoverLegacyDirective],
                    exports: [SiPopoverLegacyDirective]
                }]
        }] });

/**
 * Copyright (c) Siemens 2016 - 2026
 * SPDX-License-Identifier: MIT
 */

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

export { SiPopoverLegacyDirective, SiPopoverLegacyModule };
//# sourceMappingURL=siemens-element-ng-popover-legacy.mjs.map
