/*!
 * KoliBri - The accessible HTML-Standard
 */
import { a as alignFloatingElements, b as autoUpdate } from './align-floating-elements.js';
import './common.js';
import { n as getDocument } from './prop.validators.js';
import { t as tooltipClosed, a as tooltipOpened } from './tooltip-open-tracking.js';
import { c as createPropDefinition, n as normalizeString } from './normalizers.js';
import { a as alignPropTypeOptions } from './align.js';
import { l as labelProp } from './label2.js';
import './variant-quote.js';
import { B as BaseController } from './base-controller.js';

const VISIBLE_OVERLAYS = new Set();
let lastOverlay = null;
function showOverlay(overlay) {
    if (lastOverlay !== overlay) {
        if (lastOverlay) {
            lastOverlay.style.setProperty('z-index', '999');
        }
        VISIBLE_OVERLAYS.delete(overlay);
        VISIBLE_OVERLAYS.add(overlay);
        overlay.style.setProperty('z-index', '1000');
        lastOverlay = overlay;
    }
}
function hideOverlay(overlay) {
    if (!VISIBLE_OVERLAYS.delete(overlay)) {
        return;
    }
    if (lastOverlay === overlay) {
        lastOverlay = null;
        for (const el of VISIBLE_OVERLAYS) {
            lastOverlay = el;
        }
        if (lastOverlay) {
            lastOverlay.style.setProperty('z-index', '1000');
        }
    }
}

const alignProp = createPropDefinition('align', 'top', (value) => {
    const str = normalizeString(value);
    if (alignPropTypeOptions.includes(str)) {
        return str;
    }
    throw new Error(`Invalid align value: ${str}`);
}, (v) => alignPropTypeOptions.includes(v));

const badgeTextProp = createPropDefinition('badgeText', '', normalizeString);

const idProp = createPropDefinition('id', '', normalizeString);

const tooltipPropsConfig = {
    required: [labelProp],
    optional: [alignProp, badgeTextProp, idProp],
};

class TooltipController extends BaseController {
    constructor(stateAccess) {
        super(stateAccess, tooltipPropsConfig);
        this.hasFocusIn = false;
        this.hasMouseIn = false;
        this.isHiddenForCurrentVisit = false;
        this.setTooltipElementRef = (el) => {
            this.tooltipElement = el;
            if (this.tooltipElement) {
                this.addListeners(this.tooltipElement);
            }
        };
        this.hideTooltipByEscape = (event) => {
            if (event.key === 'Escape') {
                this.hideTooltip();
            }
        };
        this.handleMouseEnter = () => {
            const isNewVisit = this.isNewVisit();
            this.hasMouseIn = true;
            if (isNewVisit) {
                this.isHiddenForCurrentVisit = false;
            }
            this.showOrHideTooltip();
        };
        this.handleMouseLeave = () => {
            this.hasMouseIn = false;
            this.resetHideFlag();
            this.showOrHideTooltip();
        };
        this.handleFocusIn = () => {
            const isNewVisit = this.isNewVisit();
            this.hasFocusIn = true;
            if (isNewVisit) {
                this.isHiddenForCurrentVisit = false;
            }
            this.showOrHideTooltip();
        };
        this.handleFocusOut = () => {
            this.hasFocusIn = false;
            this.resetHideFlag();
            this.showOrHideTooltip();
        };
    }
    componentWillLoad(props) {
        this.watchLabel(props.label);
        this.watchAlign(props.align);
        this.watchBadgeText(props.badgeText);
        this.watchId(props.id);
    }
    watchLabel(value) {
        labelProp.apply(value, (v) => {
            this.setRenderProp('label', v);
        });
    }
    watchAlign(value) {
        alignProp.apply(value, (v) => {
            this.setRenderProp('align', v);
        });
    }
    watchBadgeText(value) {
        badgeTextProp.apply(value, (v) => {
            this.setRenderProp('badgeText', v);
        });
    }
    watchId(value) {
        idProp.apply(value, (v) => {
            this.setRenderProp('id', v);
        });
    }
    initContext(previousSibling) {
        this.previousSibling = previousSibling;
    }
    syncListeners(last, next, replacePreviousSibling = false) {
        if (last) {
            this.removeListeners(last);
        }
        if (next) {
            if (replacePreviousSibling) {
                this.previousSibling = next;
            }
            this.addListeners(next);
        }
    }
    handleEventListeners(host) {
        const nextSibling = host.previousElementSibling;
        this.syncListeners(this.previousSibling, nextSibling, true);
    }
    hideTooltip() {
        this.isHiddenForCurrentVisit = true;
        if (this.tooltipElement) {
            hideOverlay(this.tooltipElement);
            tooltipClosed();
            this.tooltipElement.classList.remove('show');
            this.tooltipElement.classList.add('hide');
            if (this.cleanupAutoPositioning) {
                this.cleanupAutoPositioning();
                this.cleanupAutoPositioning = undefined;
            }
        }
        getDocument().removeEventListener('keyup', this.hideTooltipByEscape);
    }
    destroy() {
        clearTimeout(this.overFocusTimeout);
        if (this.previousSibling) {
            this.removeListeners(this.previousSibling);
            this.previousSibling = undefined;
        }
        if (this.tooltipElement) {
            this.removeListeners(this.tooltipElement);
        }
        if (this.cleanupAutoPositioning) {
            this.cleanupAutoPositioning();
            this.cleanupAutoPositioning = undefined;
        }
        getDocument().removeEventListener('keyup', this.hideTooltipByEscape);
    }
    isNewVisit() {
        return !this.hasMouseIn && !this.hasFocusIn;
    }
    resetHideFlag() {
        if (this.isNewVisit()) {
            this.isHiddenForCurrentVisit = false;
        }
    }
    async alignTooltip() {
        if (this.tooltipElement && this.previousSibling) {
            await alignFloatingElements({
                align: this.getRenderProp('align'),
                arrowElement: this.tooltipElement.querySelector('.kol-tooltip__arrow'),
                floatingElement: this.tooltipElement,
                referenceElement: this.previousSibling,
            });
        }
    }
    showTooltip() {
        if (this.isHiddenForCurrentVisit) {
            return;
        }
        if (this.previousSibling && this.tooltipElement) {
            showOverlay(this.tooltipElement);
            tooltipOpened();
            this.tooltipElement.classList.remove('hide');
            this.tooltipElement.classList.add('show');
            this.tooltipElement.style.setProperty('display', 'block');
            getDocument().addEventListener('keyup', this.hideTooltipByEscape, { once: true });
            const target = this.previousSibling;
            const tooltipEl = this.tooltipElement;
            this.cleanupAutoPositioning = autoUpdate(target, tooltipEl, () => {
                void this.alignTooltip();
            });
        }
    }
    showOrHideTooltip() {
        clearTimeout(this.overFocusTimeout);
        this.overFocusTimeout = setTimeout(() => {
            if (this.hasMouseIn || this.hasFocusIn) {
                this.showTooltip();
            }
            else {
                this.hideTooltip();
            }
        }, 300);
    }
    addListeners(el) {
        el.addEventListener('mouseover', this.handleMouseEnter);
        el.addEventListener('mouseout', this.handleMouseLeave);
        el.addEventListener('focusin', this.handleFocusIn);
        el.addEventListener('focusout', this.handleFocusOut);
    }
    removeListeners(el) {
        el.removeEventListener('mouseover', this.handleMouseEnter);
        el.removeEventListener('mouseout', this.handleMouseLeave);
        el.removeEventListener('focusin', this.handleFocusIn);
        el.removeEventListener('focusout', this.handleFocusOut);
    }
}

export { TooltipController as T };
//# sourceMappingURL=controller.js.map

//# sourceMappingURL=controller.js.map