export class VisibilityManager {
    constructor(options) {
        this.observers = [];
        this.rootVisibility = new Map();
        this.hasEmittedOutOfView = false;
        this.options = options;
        this.handleVisibilityChange = this.onDocumentVisibilityChange.bind(this);
    }
    setup() {
        const { target, enableVisibilityEffect, enableTabClose, } = this.options;
        if (!enableVisibilityEffect || !target)
            return;
        this.cleanup();
        const parentRoot = this.getScrollableAncestors(this.options.host)[0] ?? null;
        const scrollContainers = parentRoot ? [parentRoot, null] : [null];
        scrollContainers.forEach(rootContainer => {
            const observer = new IntersectionObserver(entries => {
                for (const entry of entries) {
                    if (!entry.isIntersecting && this.options.isOpen?.()) {
                        this.options.onAnchorOutOfView?.(rootContainer);
                        this.options.emit?.('visibility-change', {
                            visible: false,
                            reason: 'anchor-out-of-view',
                            root: rootContainer,
                        });
                        return;
                    }
                    if (!this.options.isOpen?.())
                        return;
                    const visible = entry.intersectionRatio > 0;
                    this.rootVisibility.set(rootContainer, visible);
                    const reported = [...this.rootVisibility.values()];
                    const anyOutOfView = reported.length > 0 && reported.some(v => v === false);
                    if (anyOutOfView && !this.hasEmittedOutOfView) {
                        this.hasEmittedOutOfView = true;
                        this.options.onAnchorOutOfView?.(rootContainer);
                        this.options.emit?.('visibility-change', {
                            visible: false,
                            reason: 'anchor-out-of-view',
                            root: rootContainer,
                        });
                    }
                    if (!anyOutOfView) {
                        this.hasEmittedOutOfView = false;
                    }
                }
            }, { root: rootContainer, threshold: 0.1 });
            observer.observe(this.options.host);
            this.observers.push(observer);
        });
        if (enableTabClose) {
            document.addEventListener('visibilitychange', this.handleVisibilityChange);
        }
    }
    cleanup() {
        this.observers.forEach(o => o.disconnect());
        this.observers = [];
        this.rootVisibility.clear();
        document.removeEventListener('visibilitychange', this.handleVisibilityChange);
    }
    onDocumentVisibilityChange() {
        const { enableTabClose, isOpen, onDocumentHidden, emit } = this.options;
        if (!enableTabClose)
            return;
        if (document.visibilityState === 'hidden' && isOpen?.()) {
            onDocumentHidden?.();
            emit?.('visibility-change', {
                visible: false,
                reason: 'document-hidden',
            });
        }
    }
    getScrollableAncestors(element) {
        const scrollables = [];
        let parent = element.parentElement;
        while (parent) {
            const style = getComputedStyle(parent);
            const canScroll = /(auto|scroll)/.test(style.overflow + style.overflowY + style.overflowX);
            if (canScroll)
                scrollables.push(parent);
            parent = parent.parentElement;
        }
        return scrollables;
    }
}
//# sourceMappingURL=visibility-manager.js.map