import * as i0 from '@angular/core';
import { inject, ElementRef, NgZone, input, Directive, ViewEncapsulation, ChangeDetectionStrategy, Component, Injectable, ViewContainerRef, DestroyRef, computed, TemplateRef } from '@angular/core';
import { AvatarComponent } from '@agorapulse/ui-components/avatar';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import DOMPurify from 'dompurify';

/**
 * Directive that triggers a tooltip to show/hide
 *
 * ```html
 * <div #myTooltip="apTooltip" apTooltip>Content</div>
 * <div [apTooltipExternalTrigger]="myTooltip">Click me</div>
 * ```
 */
class TooltipExternalTriggerDirective {
    elementRef = inject(ElementRef);
    zone = inject(NgZone);
    // Accept a TooltipDirective reference for sibling usage
    apTooltipExternalTrigger = input(...(ngDevMode ? [undefined, { debugName: "apTooltipExternalTrigger" }] : /* istanbul ignore next */ []));
    clickListener = undefined;
    get targetTooltip() {
        // Prefer explicit reference, fall back to parent
        return this.apTooltipExternalTrigger() ?? null;
    }
    ngAfterViewInit() {
        if (!this.targetTooltip) {
            return;
        }
        this.setupEventListeners();
    }
    setupEventListeners() {
        this.cleanupEventListeners();
        this.zone.runOutsideAngular(() => {
            const nativeElement = this.elementRef.nativeElement;
            this.clickListener = this.onClick.bind(this);
            nativeElement.addEventListener('click', this.clickListener, true);
        });
    }
    cleanupEventListeners() {
        const nativeElement = this.elementRef.nativeElement;
        if (this.clickListener) {
            nativeElement.removeEventListener('click', this.clickListener, true);
            this.clickListener = undefined;
        }
    }
    ngOnDestroy() {
        this.cleanupEventListeners();
    }
    onClick() {
        this.zone.run(() => {
            const tooltip = this.targetTooltip;
            if (!tooltip)
                return;
            if (tooltip.container) {
                tooltip.deactivate();
            }
            else {
                tooltip.externallyTriggerred = true;
                tooltip.activate();
            }
        });
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.16", ngImport: i0, type: TooltipExternalTriggerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
    static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.16", type: TooltipExternalTriggerDirective, isStandalone: true, selector: "[apTooltipExternalTrigger]", inputs: { apTooltipExternalTrigger: { classPropertyName: "apTooltipExternalTrigger", publicName: "apTooltipExternalTrigger", isSignal: true, isRequired: false, transformFunction: null } }, exportAs: ["apTooltipExternalTrigger"], ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.16", ngImport: i0, type: TooltipExternalTriggerDirective, decorators: [{
            type: Directive,
            args: [{
                    selector: '[apTooltipExternalTrigger]',
                    standalone: true,
                    exportAs: 'apTooltipExternalTrigger',
                }]
        }], propDecorators: { apTooltipExternalTrigger: [{ type: i0.Input, args: [{ isSignal: true, alias: "apTooltipExternalTrigger", required: false }] }] } });

const CustomTooltipType = {
    DEFAULT: 'DEFAULT', // default type
    PRESENTATION: 'PRESENTATION',
    LIST: 'LIST',
};
/**
 * A tooltip component that is used for predefined templates: Presentation and List.
 * Not to be used directly, use TooltipDirective instead.
 */
class TooltipComponent {
    CUSTOM_TOOLTIP_TYPE = CustomTooltipType;
    type = input(CustomTooltipType.DEFAULT, ...(ngDevMode ? [{ debugName: "type" }] : /* istanbul ignore next */ []));
    presentationContext = input(...(ngDevMode ? [undefined, { debugName: "presentationContext" }] : /* istanbul ignore next */ []));
    tooltipListItems = input([], ...(ngDevMode ? [{ debugName: "tooltipListItems" }] : /* istanbul ignore next */ []));
    showCaption = input(true, ...(ngDevMode ? [{ debugName: "showCaption" }] : /* istanbul ignore next */ []));
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.16", ngImport: i0, type: TooltipComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
    static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.16", type: TooltipComponent, isStandalone: true, selector: "ap-tooltip", inputs: { type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, presentationContext: { classPropertyName: "presentationContext", publicName: "presentationContext", isSignal: true, isRequired: false, transformFunction: null }, tooltipListItems: { classPropertyName: "tooltipListItems", publicName: "tooltipListItems", isSignal: true, isRequired: false, transformFunction: null }, showCaption: { classPropertyName: "showCaption", publicName: "showCaption", isSignal: true, isRequired: false, transformFunction: null } }, providers: [], ngImport: i0, template: "<div class=\"custom-tooltip-container\">\n    @switch (type()) {\n        @case (CUSTOM_TOOLTIP_TYPE.PRESENTATION) {\n            @let presentation = presentationContext();\n            @if (presentation) {\n                <div class=\"tooltip-presentation-title\">{{ presentation.title }}</div>\n                <div class=\"tooltip-presentation-caption\">{{ presentation.description }}</div>\n            }\n        }\n        @case (CUSTOM_TOOLTIP_TYPE.LIST) {\n            <div class=\"tooltip-list-container\">\n                @for (avatar of tooltipListItems(); track avatar) {\n                    <div class=\"tooltip-item\">\n                        <ap-avatar\n                            [profilePicture]=\"avatar.profilePicture\"\n                            [alt]=\"avatar.alt ?? ''\"\n                            [network]=\"avatar.network\"\n                            [size]=\"showCaption() && avatar.caption ? 32 : 24\"\n                            [username]=\"avatar.username\"\n                            [showInitials]=\"avatar.showInitials\"\n                            [bigNetwork]=\"avatar.bigNetwork ?? false\"\n                            [anonymous]=\"avatar.anonymous ?? false\"\n                            [online]=\"avatar.online ?? false\"\n                            [rounded]=\"avatar.rounded ?? true\" />\n\n                        <div class=\"tooltip-item-info\">\n                            <div class=\"tooltip-item-title\">\n                                {{ avatar.username }}\n                            </div>\n                            @if (showCaption() && avatar.caption) {\n                                <div class=\"tooltip-item-caption\">\n                                    {{ avatar.caption }}\n                                </div>\n                            }\n                        </div>\n                    </div>\n                }\n            </div>\n        }\n        @default {\n\n        }\n    }\n\n</div>\n", styles: [".custom-tooltip-container{display:flex;flex-direction:column;width:100%;height:100%;max-height:280px;overflow:auto;padding:var(--ref-spacing-xs);gap:var(--ref-spacing-xxxs);scrollbar-color:var(--ref-color-grey-20) transparent;scrollbar-width:thin}.custom-tooltip-container .tooltip-presentation-title{color:var(--ref-color-grey-100);font-family:Averta;font-size:var(--ref-font-size-md);font-style:normal;font-weight:var(--ref-font-weight-bold);line-height:var(--ref-font-line-height-lg)}.custom-tooltip-container .tooltip-presentation-caption{color:var(--ref-color-grey-80);font-family:Averta;font-size:var(--ref-font-size-sm);font-style:normal;font-weight:var(--ref-font-weight-regular);line-height:var(--ref-font-line-height-sm)}.custom-tooltip-container .tooltip-list-container{display:flex;flex-direction:column;align-items:flex-start;gap:var(--ref-spacing-xs)}.custom-tooltip-container .tooltip-list-container .tooltip-item{display:flex;flex-direction:row;align-items:center;gap:var(--ref-spacing-xxs)}.custom-tooltip-container .tooltip-list-container .tooltip-item .tooltip-item-info{display:flex;flex-direction:column;justify-content:center;align-items:flex-start;flex:1 0 0}.custom-tooltip-container .tooltip-list-container .tooltip-item .tooltip-item-info .tooltip-item-title{display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:1;align-self:stretch;overflow:hidden;color:var(--ref-color-grey-100);text-overflow:ellipsis;font-family:Averta;font-size:var(--ref-font-size-sm);font-style:normal;font-weight:var(--ref-font-weight-bold);line-height:var(--ref-font-line-height-sm)}.custom-tooltip-container .tooltip-list-container .tooltip-item .tooltip-item-info .tooltip-item-caption{display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:1;align-self:stretch;overflow:hidden;color:var(--ref-color-grey-80);text-overflow:ellipsis;font-family:Averta;font-size:var(--ref-font-size-xs);font-style:normal;font-weight:var(--ref-font-weight-regular);line-height:var(--ref-font-line-height-xs)}\n"], dependencies: [{ kind: "component", type: AvatarComponent, selector: "ap-avatar", inputs: ["profilePicture", "alt", "network", "size", "username", "showInitials", "bigNetwork", "anonymous", "online", "youtubeAvatarMode", "rounded"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.16", ngImport: i0, type: TooltipComponent, decorators: [{
            type: Component,
            args: [{ changeDetection: ChangeDetectionStrategy.OnPush, selector: 'ap-tooltip', imports: [AvatarComponent], providers: [], encapsulation: ViewEncapsulation.None, template: "<div class=\"custom-tooltip-container\">\n    @switch (type()) {\n        @case (CUSTOM_TOOLTIP_TYPE.PRESENTATION) {\n            @let presentation = presentationContext();\n            @if (presentation) {\n                <div class=\"tooltip-presentation-title\">{{ presentation.title }}</div>\n                <div class=\"tooltip-presentation-caption\">{{ presentation.description }}</div>\n            }\n        }\n        @case (CUSTOM_TOOLTIP_TYPE.LIST) {\n            <div class=\"tooltip-list-container\">\n                @for (avatar of tooltipListItems(); track avatar) {\n                    <div class=\"tooltip-item\">\n                        <ap-avatar\n                            [profilePicture]=\"avatar.profilePicture\"\n                            [alt]=\"avatar.alt ?? ''\"\n                            [network]=\"avatar.network\"\n                            [size]=\"showCaption() && avatar.caption ? 32 : 24\"\n                            [username]=\"avatar.username\"\n                            [showInitials]=\"avatar.showInitials\"\n                            [bigNetwork]=\"avatar.bigNetwork ?? false\"\n                            [anonymous]=\"avatar.anonymous ?? false\"\n                            [online]=\"avatar.online ?? false\"\n                            [rounded]=\"avatar.rounded ?? true\" />\n\n                        <div class=\"tooltip-item-info\">\n                            <div class=\"tooltip-item-title\">\n                                {{ avatar.username }}\n                            </div>\n                            @if (showCaption() && avatar.caption) {\n                                <div class=\"tooltip-item-caption\">\n                                    {{ avatar.caption }}\n                                </div>\n                            }\n                        </div>\n                    </div>\n                }\n            </div>\n        }\n        @default {\n\n        }\n    }\n\n</div>\n", styles: [".custom-tooltip-container{display:flex;flex-direction:column;width:100%;height:100%;max-height:280px;overflow:auto;padding:var(--ref-spacing-xs);gap:var(--ref-spacing-xxxs);scrollbar-color:var(--ref-color-grey-20) transparent;scrollbar-width:thin}.custom-tooltip-container .tooltip-presentation-title{color:var(--ref-color-grey-100);font-family:Averta;font-size:var(--ref-font-size-md);font-style:normal;font-weight:var(--ref-font-weight-bold);line-height:var(--ref-font-line-height-lg)}.custom-tooltip-container .tooltip-presentation-caption{color:var(--ref-color-grey-80);font-family:Averta;font-size:var(--ref-font-size-sm);font-style:normal;font-weight:var(--ref-font-weight-regular);line-height:var(--ref-font-line-height-sm)}.custom-tooltip-container .tooltip-list-container{display:flex;flex-direction:column;align-items:flex-start;gap:var(--ref-spacing-xs)}.custom-tooltip-container .tooltip-list-container .tooltip-item{display:flex;flex-direction:row;align-items:center;gap:var(--ref-spacing-xxs)}.custom-tooltip-container .tooltip-list-container .tooltip-item .tooltip-item-info{display:flex;flex-direction:column;justify-content:center;align-items:flex-start;flex:1 0 0}.custom-tooltip-container .tooltip-list-container .tooltip-item .tooltip-item-info .tooltip-item-title{display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:1;align-self:stretch;overflow:hidden;color:var(--ref-color-grey-100);text-overflow:ellipsis;font-family:Averta;font-size:var(--ref-font-size-sm);font-style:normal;font-weight:var(--ref-font-weight-bold);line-height:var(--ref-font-line-height-sm)}.custom-tooltip-container .tooltip-list-container .tooltip-item .tooltip-item-info .tooltip-item-caption{display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:1;align-self:stretch;overflow:hidden;color:var(--ref-color-grey-80);text-overflow:ellipsis;font-family:Averta;font-size:var(--ref-font-size-xs);font-style:normal;font-weight:var(--ref-font-weight-regular);line-height:var(--ref-font-line-height-xs)}\n"] }]
        }], propDecorators: { type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }], presentationContext: [{ type: i0.Input, args: [{ isSignal: true, alias: "presentationContext", required: false }] }], tooltipListItems: [{ type: i0.Input, args: [{ isSignal: true, alias: "tooltipListItems", required: false }] }], showCaption: [{ type: i0.Input, args: [{ isSignal: true, alias: "showCaption", required: false }] }] } });

class TooltipService {
    static defaultOffset = 12;
    static getOuterWidth(el) {
        return el.offsetWidth;
    }
    static getOuterHeight(el) {
        return el.offsetHeight;
    }
    static getViewport() {
        const win = window, d = document, e = d.documentElement, g = d.getElementsByTagName('body')[0], w = win.innerWidth || e.clientWidth || g.clientWidth, h = win.innerHeight || e.clientHeight || g.clientHeight;
        return { width: w, height: h };
    }
    static getWindowScrollLeft() {
        const doc = document.documentElement;
        return (window.pageXOffset || doc.scrollLeft) - (doc.clientLeft || 0);
    }
    static getWindowScrollTop() {
        const doc = document.documentElement;
        return (window.pageYOffset || doc.scrollTop) - (doc.clientTop || 0);
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.16", ngImport: i0, type: TooltipService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
    static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.16", ngImport: i0, type: TooltipService });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.16", ngImport: i0, type: TooltipService, decorators: [{
            type: Injectable
        }] });

class TooltipDirective {
    elementRef = inject(ElementRef);
    zone = inject(NgZone);
    viewContainerRef = inject(ViewContainerRef);
    destroyRef = inject(DestroyRef);
    documentClickListener;
    apTooltip = input.required(...(ngDevMode ? [{ debugName: "apTooltip" }] : /* istanbul ignore next */ []));
    apTooltipPosition = input('top', ...(ngDevMode ? [{ debugName: "apTooltipPosition" }] : /* istanbul ignore next */ []));
    apTooltipShowDelay = input(80, ...(ngDevMode ? [{ debugName: "apTooltipShowDelay" }] : /* istanbul ignore next */ []));
    apTooltipHideDelay = input(0, ...(ngDevMode ? [{ debugName: "apTooltipHideDelay" }] : /* istanbul ignore next */ []));
    apTooltipDuration = input(0, ...(ngDevMode ? [{ debugName: "apTooltipDuration" }] : /* istanbul ignore next */ []));
    apTooltipDisabled = input(false, ...(ngDevMode ? [{ debugName: "apTooltipDisabled" }] : /* istanbul ignore next */ []));
    apTooltipTruncatedTextOnly = input(false, ...(ngDevMode ? [{ debugName: "apTooltipTruncatedTextOnly" }] : /* istanbul ignore next */ []));
    apTooltipTemplateContext = input(...(ngDevMode ? [undefined, { debugName: "apTooltipTemplateContext" }] : /* istanbul ignore next */ []));
    apTooltipVirtualScrollElement = input(...(ngDevMode ? [undefined, { debugName: "apTooltipVirtualScrollElement" }] : /* istanbul ignore next */ []));
    apTooltipTrigger = input('hover', ...(ngDevMode ? [{ debugName: "apTooltipTrigger" }] : /* istanbul ignore next */ []));
    // Predefined template variables
    apTooltipType = input(CustomTooltipType.DEFAULT, ...(ngDevMode ? [{ debugName: "apTooltipType" }] : /* istanbul ignore next */ []));
    apTooltipPresentationContext = input(...(ngDevMode ? [undefined, { debugName: "apTooltipPresentationContext" }] : /* istanbul ignore next */ []));
    apTooltipListItems = input([], ...(ngDevMode ? [{ debugName: "apTooltipListItems" }] : /* istanbul ignore next */ []));
    apTooltipShowAvatarCaption = input(true, ...(ngDevMode ? [{ debugName: "apTooltipShowAvatarCaption" }] : /* istanbul ignore next */ []));
    isDefaultTooltipType = computed(() => !this.apTooltipType() || this.apTooltipType() === CustomTooltipType.DEFAULT, ...(ngDevMode ? [{ debugName: "isDefaultTooltipType" }] : /* istanbul ignore next */ []));
    isValidPredefinedTooltip = computed(() => (this.apTooltipType() === CustomTooltipType.PRESENTATION &&
        this.apTooltipPresentationContext()?.title &&
        this.apTooltipPresentationContext()?.description) ||
        (this.apTooltipType() === CustomTooltipType.LIST && this.apTooltipListItems().length > 0), ...(ngDevMode ? [{ debugName: "isValidPredefinedTooltip" }] : /* istanbul ignore next */ []));
    triggeredByClick = computed(() => this.apTooltipTrigger() === 'click' || this.externallyTriggerred, ...(ngDevMode ? [{ debugName: "triggeredByClick" }] : /* istanbul ignore next */ []));
    clickListener = undefined;
    container = undefined;
    hideTimeout;
    mouseEnterListener = undefined;
    mouseLeaveListener = undefined;
    nativeElement = this.elementRef.nativeElement;
    showTimeout;
    tooltipText;
    _externallyTriggerred = false;
    ngOnInit() {
        const apTooltipVirtualScrollElement = this.apTooltipVirtualScrollElement();
        if (apTooltipVirtualScrollElement) {
            apTooltipVirtualScrollElement.renderedRangeStream.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(range => {
                if (range.start === 0 && range.end === 0) {
                    this.deactivate();
                }
            });
        }
    }
    ngAfterViewInit() {
        this.setupEventListeners(this.apTooltipTrigger());
    }
    setupEventListeners(trigger) {
        // Close any open tooltip when switching modes
        if (this.container) {
            this.remove();
        }
        this.cleanupEventListeners();
        this.zone.runOutsideAngular(() => {
            this.clickListener = this.onInputClick.bind(this);
            this.nativeElement.addEventListener('click', this.clickListener, true);
            if (trigger === 'hover') {
                this.mouseEnterListener = this.onMouseEnter.bind(this);
                this.mouseLeaveListener = this.onMouseLeave.bind(this);
                this.nativeElement.addEventListener('mouseenter', this.mouseEnterListener);
                this.nativeElement.addEventListener('mouseleave', this.mouseLeaveListener);
            }
        });
    }
    cleanupEventListeners() {
        if (this.mouseEnterListener) {
            this.nativeElement.removeEventListener('mouseenter', this.mouseEnterListener);
            this.mouseEnterListener = undefined;
        }
        if (this.clickListener) {
            this.nativeElement.removeEventListener('click', this.clickListener, true);
            this.clickListener = undefined;
        }
        if (this.mouseLeaveListener) {
            this.nativeElement.removeEventListener('mouseleave', this.mouseLeaveListener);
            this.mouseLeaveListener = undefined;
        }
    }
    ngOnDestroy() {
        if (this.container) {
            this.deactivate();
        }
        this.cleanupEventListeners();
    }
    onMouseEnter() {
        if (!this.container) {
            this.activate();
        }
    }
    onMouseLeave() {
        if (!this._externallyTriggerred) {
            this.deactivate();
        }
    }
    onInputClick() {
        this.zone.run(() => {
            const trigger = this.apTooltipTrigger();
            if (trigger === 'click') {
                if (this.container) {
                    this.deactivate();
                }
                else {
                    this.activate();
                }
            }
            else {
                this.deactivate();
            }
        });
    }
    activate() {
        this.clearHideTimeout();
        if (this.triggeredByClick()) {
            this.addDocumentClickListener();
        }
        if (this.apTooltipShowDelay()) {
            this.showTimeout = window.setTimeout(() => {
                this.show();
            }, this.apTooltipShowDelay());
        }
        else {
            this.show();
        }
        if (this.apTooltipDuration()) {
            const duration = this.apTooltipShowDelay() ? this.apTooltipDuration() + this.apTooltipShowDelay() : this.apTooltipDuration();
            this.hideTimeout = window.setTimeout(() => {
                this.remove();
            }, duration);
        }
    }
    deactivate() {
        this.clearShowTimeout();
        this.removeDocumentClickListener();
        if (this.apTooltipHideDelay()) {
            this.clearHideTimeout();
            this.hideTimeout = window.setTimeout(() => {
                this.remove();
            }, this.apTooltipHideDelay());
        }
        else {
            this.remove();
        }
    }
    show() {
        if (this.apTooltipTruncatedTextOnly() && this.elementRef.nativeElement.scrollWidth === this.elementRef.nativeElement.clientWidth) {
            return;
        }
        if ((this.isDefaultTooltipType() && !this.apTooltip()) ||
            (!this.isDefaultTooltipType() && !this.isValidPredefinedTooltip()) ||
            this.apTooltipDisabled()) {
            return;
        }
        // Prevent tooltip from showing if the host element is not connected to the DOM
        const hostRect = this.nativeElement.getBoundingClientRect();
        if (!this.nativeElement.isConnected || (hostRect.width === 0 && hostRect.height === 0)) {
            return;
        }
        this.create();
        // For predefined tooltips, alignment is deferred after component rendering
        if (this.isDefaultTooltipType()) {
            this.align();
        }
    }
    create() {
        if (this.container) {
            this.clearHideTimeout();
            this.remove();
        }
        if (this.isDefaultTooltipType()) {
            this.createDefaultTooltip();
        }
        else {
            this.createPredefinedTooltip();
        }
    }
    createDefaultTooltip() {
        this.container = document.createElement('div');
        this.container.setAttribute('role', 'tooltip');
        this.tooltipText = document.createElement('div');
        this.tooltipText.className = 'ap-tooltip-text';
        this.updateText();
        const contentContainer = document.createElement('div');
        contentContainer.classList.add('ap-content-container');
        contentContainer.appendChild(this.tooltipText);
        contentContainer.appendChild(this.createSvgElement());
        this.container.appendChild(contentContainer);
        document.body.appendChild(this.container);
        this.container.classList.add('ap-tooltip');
        if (this.apTooltip() instanceof TemplateRef) {
            this.container.classList.add('ap-tooltip-custom-template');
        }
        this.setCssVariables();
    }
    createPredefinedTooltip() {
        const componentRef = this.viewContainerRef.createComponent(TooltipComponent);
        // Set inputs
        componentRef.setInput('type', this.apTooltipType());
        componentRef.setInput('presentationContext', this.apTooltipPresentationContext());
        componentRef.setInput('tooltipListItems', this.apTooltipListItems());
        componentRef.setInput('showCaption', this.apTooltipShowAvatarCaption());
        // Force change detection to render the component immediately
        componentRef.changeDetectorRef.detectChanges();
        this.container = document.createElement('div');
        this.container.setAttribute('role', 'tooltip');
        const contentContainer = document.createElement('div');
        contentContainer.classList.add('ap-content-container', 'ap-content-predefined-container');
        contentContainer.appendChild(componentRef.location.nativeElement);
        contentContainer.appendChild(this.createSvgElement());
        this.container.appendChild(contentContainer);
        document.body.appendChild(this.container);
        this.container.classList.add('ap-tooltip', 'ap-predefined-tooltip');
        if (this.triggeredByClick()) {
            this.container.classList.add('ap-tooltip-click-trigger');
        }
        // Has to wait for the TooltipComponent to be rendered in order to align and then set the CSS variable --ap-tooltip-height
        requestAnimationFrame(() => {
            this.align();
            this.setCssVariables();
        });
    }
    createSvgElement() {
        const svgNamespace = 'http://www.w3.org/2000/svg';
        const arrowSvg = document.createElementNS(svgNamespace, 'svg');
        arrowSvg.classList.add('ap-tooltip-arrow');
        arrowSvg.setAttribute('xmlns', svgNamespace);
        arrowSvg.setAttribute('viewBox', '0 0 16 8');
        arrowSvg.setAttribute('fill', 'none');
        const path = document.createElementNS(svgNamespace, 'path');
        path.setAttribute('d', 'M6.68299 1.15238C7.43705 0.492586 8.56296 0.492588 9.31701 1.15238L16 7L0 7L6.68299 1.15238Z');
        arrowSvg.appendChild(path);
        return arrowSvg;
    }
    align() {
        switch (this.apTooltipPosition()) {
            case 'top-left':
                this.alignTopLeft();
                if (this.isOutOfBounds()) {
                    this.alignBottom();
                    if (this.isOutOfBounds()) {
                        this.alignRight();
                        if (this.isOutOfBounds()) {
                            this.alignLeft();
                        }
                    }
                }
                break;
            case 'top-right':
                this.alignTopRight();
                if (this.isOutOfBounds()) {
                    this.alignBottom();
                    if (this.isOutOfBounds()) {
                        this.alignRight();
                        if (this.isOutOfBounds()) {
                            this.alignLeft();
                        }
                    }
                }
                break;
            case 'top':
                this.alignTop();
                if (this.isOutOfBounds()) {
                    this.alignBottom();
                    if (this.isOutOfBounds()) {
                        this.alignRight();
                        if (this.isOutOfBounds()) {
                            this.alignLeft();
                        }
                    }
                }
                break;
            case 'bottom':
                this.alignBottom();
                if (this.isOutOfBounds()) {
                    this.alignTop();
                    if (this.isOutOfBounds()) {
                        this.alignRight();
                        if (this.isOutOfBounds()) {
                            this.alignLeft();
                        }
                    }
                }
                break;
            case 'bottom-left':
                this.alignBottomLeft();
                if (this.isOutOfBounds()) {
                    this.alignTop();
                    if (this.isOutOfBounds()) {
                        this.alignRight();
                        if (this.isOutOfBounds()) {
                            this.alignLeft();
                        }
                    }
                }
                break;
            case 'bottom-right':
                this.alignBottomRight();
                if (this.isOutOfBounds()) {
                    this.alignTop();
                    if (this.isOutOfBounds()) {
                        this.alignRight();
                        if (this.isOutOfBounds()) {
                            this.alignLeft();
                        }
                    }
                }
                break;
            case 'left':
                this.alignLeft();
                if (this.isOutOfBounds()) {
                    this.alignRight();
                    if (this.isOutOfBounds()) {
                        this.alignTop();
                        if (this.isOutOfBounds()) {
                            this.alignBottom();
                        }
                    }
                }
                break;
            case 'right':
                this.alignRight();
                if (this.isOutOfBounds()) {
                    this.alignLeft();
                    if (this.isOutOfBounds()) {
                        this.alignTop();
                        if (this.isOutOfBounds()) {
                            this.alignBottom();
                        }
                    }
                }
                break;
        }
    }
    alignRight() {
        this.preAlign('right');
        if (this.container) {
            const hostOffset = this.getHostOffset();
            const left = hostOffset.left + TooltipService.getOuterWidth(this.nativeElement) + TooltipService.defaultOffset;
            const top = hostOffset.top + (TooltipService.getOuterHeight(this.nativeElement) - TooltipService.getOuterHeight(this.container)) / 2;
            this.container.style.left = left + 'px';
            this.container.style.top = top + 'px';
        }
    }
    alignLeft() {
        this.preAlign('left');
        if (this.container) {
            const hostOffset = this.getHostOffset();
            const left = hostOffset.left - TooltipService.getOuterWidth(this.container) - TooltipService.defaultOffset;
            const top = hostOffset.top + (TooltipService.getOuterHeight(this.nativeElement) - TooltipService.getOuterHeight(this.container)) / 2;
            this.container.style.left = left + 'px';
            this.container.style.top = top + 'px';
        }
    }
    alignTop() {
        this.preAlign('top');
        if (this.container) {
            const hostOffset = this.getHostOffset();
            const left = hostOffset.left + (TooltipService.getOuterWidth(this.nativeElement) - TooltipService.getOuterWidth(this.container)) / 2;
            const top = hostOffset.top - TooltipService.getOuterHeight(this.container) - TooltipService.defaultOffset;
            this.container.style.left = left + 'px';
            this.container.style.top = top + 'px';
        }
    }
    alignTopLeft() {
        this.preAlign('top-left');
        if (this.container) {
            const hostOffset = this.getHostOffset();
            const left = hostOffset.left;
            const top = hostOffset.top - TooltipService.getOuterHeight(this.container) - TooltipService.defaultOffset;
            this.container.style.left = left + 'px';
            this.container.style.top = top + 'px';
        }
    }
    alignTopRight() {
        this.preAlign('top-right');
        if (this.container) {
            const hostOffset = this.getHostOffset();
            const left = hostOffset.left + TooltipService.getOuterWidth(this.nativeElement) - TooltipService.getOuterWidth(this.container);
            const top = hostOffset.top - TooltipService.getOuterHeight(this.container) - TooltipService.defaultOffset;
            this.container.style.left = left + 'px';
            this.container.style.top = top + 'px';
        }
    }
    alignBottom() {
        this.preAlign('bottom');
        if (this.container) {
            const hostOffset = this.getHostOffset();
            const left = hostOffset.left + (TooltipService.getOuterWidth(this.nativeElement) - TooltipService.getOuterWidth(this.container)) / 2;
            const top = hostOffset.top + TooltipService.getOuterHeight(this.nativeElement) + TooltipService.defaultOffset;
            this.container.style.left = left + 'px';
            this.container.style.top = top + 'px';
        }
    }
    alignBottomLeft() {
        this.preAlign('bottom-left');
        if (this.container) {
            const hostOffset = this.getHostOffset();
            const left = hostOffset.left;
            const top = hostOffset.top + TooltipService.getOuterHeight(this.nativeElement) + TooltipService.defaultOffset;
            this.container.style.left = left + 'px';
            this.container.style.top = top + 'px';
        }
    }
    alignBottomRight() {
        this.preAlign('bottom-right');
        if (this.container) {
            const hostOffset = this.getHostOffset();
            const left = hostOffset.left + (TooltipService.getOuterWidth(this.nativeElement) - TooltipService.getOuterWidth(this.container));
            const top = hostOffset.top + TooltipService.getOuterHeight(this.nativeElement) + TooltipService.defaultOffset;
            this.container.style.left = left + 'px';
            this.container.style.top = top + 'px';
        }
    }
    preAlign(position) {
        this.removePreviousAlignHtmlClasses();
        if (this.container) {
            this.container.style.left = -999 + 'px';
            this.container.style.top = -999 + 'px';
            const defaultClassName = 'ap-tooltip-' + position;
            this.container.classList.add(defaultClassName);
        }
    }
    getHostOffset() {
        const offset = this.nativeElement.getBoundingClientRect();
        const targetLeft = offset.left + TooltipService.getWindowScrollLeft();
        const targetTop = offset.top + TooltipService.getWindowScrollTop();
        return { left: targetLeft, top: targetTop };
    }
    isOutOfBounds() {
        if (this.container) {
            const offset = this.container.getBoundingClientRect();
            const targetTop = offset.top;
            const targetLeft = offset.left;
            const width = TooltipService.getOuterWidth(this.container);
            const height = TooltipService.getOuterHeight(this.container);
            const viewport = TooltipService.getViewport();
            return targetLeft + width > viewport.width || targetLeft < 0 || targetTop < 0 || targetTop + height > viewport.height;
        }
        else {
            return false;
        }
    }
    remove() {
        if (this.container && this.container.parentElement) {
            document.body.removeChild(this.container);
        }
        this.clearTimeouts();
        this._externallyTriggerred = false;
        this.container = undefined;
    }
    clearShowTimeout() {
        if (this.showTimeout) {
            clearTimeout(this.showTimeout);
            this.showTimeout = undefined;
        }
    }
    clearHideTimeout() {
        if (this.hideTimeout) {
            clearTimeout(this.hideTimeout);
            this.hideTimeout = undefined;
        }
    }
    clearTimeouts() {
        this.clearShowTimeout();
        this.clearHideTimeout();
    }
    updateText() {
        const apTooltip = this.apTooltip();
        if (apTooltip instanceof TemplateRef) {
            const embeddedViewRef = this.viewContainerRef.createEmbeddedView(apTooltip);
            embeddedViewRef.context = this.apTooltipTemplateContext();
            embeddedViewRef.detectChanges();
            embeddedViewRef.rootNodes.forEach(node => this.tooltipText?.appendChild(node));
        }
        else if (this.tooltipText) {
            this.tooltipText.innerHTML = apTooltip ? DOMPurify.sanitize(apTooltip) : '';
        }
    }
    setCssVariables() {
        if (this.container) {
            this.container.style.setProperty('--ap-tooltip-height', this.container.offsetHeight + 'px');
        }
    }
    removePreviousAlignHtmlClasses() {
        if (this.container) {
            this.container.classList.remove('ap-tooltip-top', 'ap-tooltip-top-left', 'ap-tooltip-top-right', 'ap-tooltip-bottom', 'ap-tooltip-bottom-left', 'ap-tooltip-bottom-right', 'ap-tooltip-left', 'ap-tooltip-right');
        }
    }
    addDocumentClickListener() {
        if (this.documentClickListener)
            return;
        this.zone.runOutsideAngular(() => {
            this.documentClickListener = (event) => {
                const target = event.target;
                if (this.container && !this.container.contains(target) && !this.nativeElement.contains(target)) {
                    this.deactivate();
                }
            };
            document.addEventListener('click', this.documentClickListener);
        });
    }
    removeDocumentClickListener() {
        if (!this.documentClickListener)
            return;
        document.removeEventListener('click', this.documentClickListener);
        this.documentClickListener = undefined;
    }
    get externallyTriggerred() {
        return this._externallyTriggerred;
    }
    set externallyTriggerred(value) {
        this._externallyTriggerred = value;
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.16", ngImport: i0, type: TooltipDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
    static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.16", type: TooltipDirective, isStandalone: true, selector: "[apTooltip]", inputs: { apTooltip: { classPropertyName: "apTooltip", publicName: "apTooltip", isSignal: true, isRequired: true, transformFunction: null }, apTooltipPosition: { classPropertyName: "apTooltipPosition", publicName: "apTooltipPosition", isSignal: true, isRequired: false, transformFunction: null }, apTooltipShowDelay: { classPropertyName: "apTooltipShowDelay", publicName: "apTooltipShowDelay", isSignal: true, isRequired: false, transformFunction: null }, apTooltipHideDelay: { classPropertyName: "apTooltipHideDelay", publicName: "apTooltipHideDelay", isSignal: true, isRequired: false, transformFunction: null }, apTooltipDuration: { classPropertyName: "apTooltipDuration", publicName: "apTooltipDuration", isSignal: true, isRequired: false, transformFunction: null }, apTooltipDisabled: { classPropertyName: "apTooltipDisabled", publicName: "apTooltipDisabled", isSignal: true, isRequired: false, transformFunction: null }, apTooltipTruncatedTextOnly: { classPropertyName: "apTooltipTruncatedTextOnly", publicName: "apTooltipTruncatedTextOnly", isSignal: true, isRequired: false, transformFunction: null }, apTooltipTemplateContext: { classPropertyName: "apTooltipTemplateContext", publicName: "apTooltipTemplateContext", isSignal: true, isRequired: false, transformFunction: null }, apTooltipVirtualScrollElement: { classPropertyName: "apTooltipVirtualScrollElement", publicName: "apTooltipVirtualScrollElement", isSignal: true, isRequired: false, transformFunction: null }, apTooltipTrigger: { classPropertyName: "apTooltipTrigger", publicName: "apTooltipTrigger", isSignal: true, isRequired: false, transformFunction: null }, apTooltipType: { classPropertyName: "apTooltipType", publicName: "apTooltipType", isSignal: true, isRequired: false, transformFunction: null }, apTooltipPresentationContext: { classPropertyName: "apTooltipPresentationContext", publicName: "apTooltipPresentationContext", isSignal: true, isRequired: false, transformFunction: null }, apTooltipListItems: { classPropertyName: "apTooltipListItems", publicName: "apTooltipListItems", isSignal: true, isRequired: false, transformFunction: null }, apTooltipShowAvatarCaption: { classPropertyName: "apTooltipShowAvatarCaption", publicName: "apTooltipShowAvatarCaption", isSignal: true, isRequired: false, transformFunction: null } }, exportAs: ["apTooltip"], ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.16", ngImport: i0, type: TooltipDirective, decorators: [{
            type: Directive,
            args: [{ selector: '[apTooltip]', standalone: true, exportAs: 'apTooltip' }]
        }], propDecorators: { apTooltip: [{ type: i0.Input, args: [{ isSignal: true, alias: "apTooltip", required: true }] }], apTooltipPosition: [{ type: i0.Input, args: [{ isSignal: true, alias: "apTooltipPosition", required: false }] }], apTooltipShowDelay: [{ type: i0.Input, args: [{ isSignal: true, alias: "apTooltipShowDelay", required: false }] }], apTooltipHideDelay: [{ type: i0.Input, args: [{ isSignal: true, alias: "apTooltipHideDelay", required: false }] }], apTooltipDuration: [{ type: i0.Input, args: [{ isSignal: true, alias: "apTooltipDuration", required: false }] }], apTooltipDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "apTooltipDisabled", required: false }] }], apTooltipTruncatedTextOnly: [{ type: i0.Input, args: [{ isSignal: true, alias: "apTooltipTruncatedTextOnly", required: false }] }], apTooltipTemplateContext: [{ type: i0.Input, args: [{ isSignal: true, alias: "apTooltipTemplateContext", required: false }] }], apTooltipVirtualScrollElement: [{ type: i0.Input, args: [{ isSignal: true, alias: "apTooltipVirtualScrollElement", required: false }] }], apTooltipTrigger: [{ type: i0.Input, args: [{ isSignal: true, alias: "apTooltipTrigger", required: false }] }], apTooltipType: [{ type: i0.Input, args: [{ isSignal: true, alias: "apTooltipType", required: false }] }], apTooltipPresentationContext: [{ type: i0.Input, args: [{ isSignal: true, alias: "apTooltipPresentationContext", required: false }] }], apTooltipListItems: [{ type: i0.Input, args: [{ isSignal: true, alias: "apTooltipListItems", required: false }] }], apTooltipShowAvatarCaption: [{ type: i0.Input, args: [{ isSignal: true, alias: "apTooltipShowAvatarCaption", required: false }] }] } });

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

export { CustomTooltipType, TooltipDirective, TooltipExternalTriggerDirective };
//# sourceMappingURL=agorapulse-ui-components-tooltip.mjs.map
