export class PortalUtils {
    static calculateAvailableSpace(referenceElement) {
        const rect = referenceElement.getBoundingClientRect();
        const viewportHeight = window.innerHeight;
        const viewportWidth = window.innerWidth;
        const spaceBelow = viewportHeight - rect.bottom;
        const spaceAbove = rect.top;
        const spaceRight = viewportWidth - rect.right;
        const spaceLeft = rect.left;
        return { spaceAbove, spaceBelow, spaceLeft, spaceRight, viewportHeight, viewportWidth };
    }
    static getOptimalPlacement(referenceElement) {
        const { spaceAbove, spaceBelow, spaceLeft, spaceRight } = this.calculateAvailableSpace(referenceElement);
        if (spaceBelow >= 200 && spaceBelow >= spaceAbove) {
            return 'bottom';
        }
        else if (spaceAbove >= 200 && spaceAbove > spaceBelow) {
            return 'top';
        }
        if (spaceRight >= 200 && spaceRight >= spaceLeft) {
            return 'right';
        }
        else if (spaceLeft >= 200) {
            return 'left';
        }
        return 'bottom';
    }
    static findBoundaryElements(component) {
        const boundaryElements = [];
        let currentElement = component.parentElement;
        while (currentElement && currentElement !== document.body) {
            const computedStyle = window.getComputedStyle(currentElement);
            const overflow = computedStyle.overflow;
            const overflowY = computedStyle.overflowY;
            const overflowX = computedStyle.overflowX;
            if (overflow === 'auto' || overflow === 'scroll' ||
                overflowY === 'auto' || overflowY === 'scroll' ||
                overflowX === 'auto' || overflowX === 'scroll') {
                boundaryElements.push(currentElement);
            }
            if (currentElement.hasAttribute('data-floating-boundary') ||
                currentElement.classList.contains('floating-boundary') ||
                currentElement.classList.contains('scroll-container')) {
                boundaryElements.push(currentElement);
            }
            currentElement = currentElement.parentElement;
        }
        return boundaryElements.length > 0 ? boundaryElements : undefined;
    }
    static calculateOptimalHeight(referenceRect, viewportHeight, placement) {
        const spaceBelow = viewportHeight - (referenceRect.y + referenceRect.height);
        const spaceAbove = referenceRect.y;
        if (placement.startsWith('top')) {
            return Math.max(spaceAbove - 20, 100);
        }
        else if (placement.startsWith('bottom')) {
            return Math.max(spaceBelow - 20, 100);
        }
        else if (placement.startsWith('left') || placement.startsWith('right')) {
            return Math.max(Math.min(spaceAbove, spaceBelow) - 20, 100);
        }
        return Math.max(Math.min(spaceAbove, spaceBelow) - 20, 100);
    }
    static extractStylesAsCSS(styles) {
        if (typeof styles === 'string') {
            return styles;
        }
        if (Array.isArray(styles)) {
            return styles.map(style => this.extractStylesAsCSS(style)).join('\n');
        }
        if (styles && typeof styles === 'object' && styles.cssText) {
            return styles.cssText;
        }
        return '';
    }
    static generateStyleId() {
        return `nile-popover-styles-${Math.random().toString(36).substring(2, 11)}`;
    }
    static isPositioningOptimal(placement, referenceElement) {
        const { spaceAbove, spaceBelow, spaceLeft, spaceRight } = this.calculateAvailableSpace(referenceElement);
        const isAbove = placement.startsWith('top');
        const isBelow = placement.startsWith('bottom');
        const isLeft = placement.startsWith('left');
        const isRight = placement.startsWith('right');
        if (isAbove && spaceBelow > spaceAbove)
            return false;
        if (isBelow && spaceAbove > spaceBelow)
            return false;
        if (isLeft && spaceRight > spaceLeft)
            return false;
        if (isRight && spaceLeft > spaceRight)
            return false;
        return true;
    }
    static applyCollisionData(element, middlewareData, placement) {
        if (middlewareData.flip) {
            const { overflows } = middlewareData.flip;
            element.setAttribute('data-placement', placement);
            if (overflows && overflows.length > 0) {
                const overflowPlacements = overflows.map(overflow => overflow.placement).join(',');
                element.setAttribute('data-overflow', overflowPlacements);
            }
            else {
                element.removeAttribute('data-overflow');
            }
        }
        if (middlewareData.shift) {
            const { x, y } = middlewareData.shift;
            if (x !== undefined && y !== undefined && (x !== 0 || y !== 0)) {
                element.setAttribute('data-shift', `${x},${y}`);
            }
            else {
                element.removeAttribute('data-shift');
            }
        }
        if (middlewareData.size) {
            const { availableWidth, availableHeight } = middlewareData.size;
            if (availableWidth !== undefined) {
                element.setAttribute('data-available-width', availableWidth.toString());
            }
            if (availableHeight !== undefined) {
                element.setAttribute('data-available-height', availableHeight.toString());
            }
        }
    }
}
export class PortalContentUtils {
    static createBasePopover(component) {
        const popoverBox = document.createElement('div');
        popoverBox.className = 'popover__box';
        popoverBox.setAttribute('part', 'popover');
        return popoverBox;
    }
    static addTitleSection(popoverBox, component) {
        if (!component.title)
            return;
        const titleDiv = document.createElement('div');
        titleDiv.className = 'popover__title';
        titleDiv.textContent = component.title;
        popoverBox.appendChild(titleDiv);
    }
    static addContentSection(popoverBox, component) {
        const contentDiv = document.createElement('div');
        contentDiv.setAttribute('part', 'base');
        contentDiv.style.display = 'contents';
        // Clone all child elements that are not explicitly slotted
        const allChildren = Array.from(component.children);
        allChildren.forEach((child) => {
            const slot = child.getAttribute('slot');
            // Only clone elements that don't have slot="anchor", "title", or "action"
            if (!slot || (slot !== 'anchor' && slot !== 'title' && slot !== 'action')) {
                const clonedChild = child.cloneNode(true);
                contentDiv.appendChild(clonedChild);
            }
        });
        popoverBox.appendChild(contentDiv);
    }
    static cloneContent(originalContent, targetContent) {
        Array.from(originalContent.childNodes).forEach(node => {
            const clonedNode = node.cloneNode(true);
            targetContent.appendChild(clonedNode);
        });
        Array.from(originalContent.attributes).forEach(attr => {
            targetContent.setAttribute(attr.name, attr.value);
        });
    }
    static addActionSection(popoverBox, component) {
        const actionDiv = document.createElement('div');
        actionDiv.className = 'popover__action';
        const actionSlots = component.querySelectorAll('[slot="action"]');
        actionSlots.forEach((slot) => {
            const clonedSlot = slot.cloneNode(true);
            actionDiv.appendChild(clonedSlot);
        });
        popoverBox.appendChild(actionDiv);
    }
    static addArrowElement(popoverBox, component) {
        const arrowDiv = document.createElement('div');
        arrowDiv.className = 'popup__arrow';
        arrowDiv.setAttribute('part', 'arrow');
        arrowDiv.setAttribute('role', 'presentation');
        popoverBox.appendChild(arrowDiv);
    }
    static createPortalPopover(component) {
        const popoverBox = this.createBasePopover(component);
        this.addTitleSection(popoverBox, component);
        this.addContentSection(popoverBox, component);
        this.addActionSection(popoverBox, component);
        if (component.arrow) {
            this.addArrowElement(popoverBox, component);
        }
        return popoverBox;
    }
    static updatePortalContent(clonedPopover, component) {
        if (!clonedPopover)
            return;
        const titleElement = clonedPopover.querySelector('.popover__title');
        if (titleElement && component.title) {
            titleElement.textContent = component.title;
        }
        const contentElement = clonedPopover.querySelector('[part="base"]');
        if (contentElement) {
            contentElement.innerHTML = '';
            const allChildren = Array.from(component.children);
            allChildren.forEach((child) => {
                const slot = child.getAttribute('slot');
                if (!slot || (slot !== 'anchor' && slot !== 'title' && slot !== 'action')) {
                    const clonedChild = child.cloneNode(true);
                    contentElement.appendChild(clonedChild);
                }
            });
        }
        const actionElement = clonedPopover.querySelector('.popover__action');
        if (actionElement) {
            actionElement.innerHTML = '';
            const actionSlots = component.querySelectorAll('[slot="action"]');
            actionSlots.forEach((slot) => {
                const clonedSlot = slot.cloneNode(true);
                actionElement.appendChild(clonedSlot);
            });
        }
    }
}
export class PortalEventUtils {
    static setupPortalEventListeners(clonedPopover, component) {
        if (!clonedPopover)
            return;
        this.setupClickListeners(clonedPopover, component);
        this.setupContentListeners(clonedPopover, component);
        this.setupActionListeners(clonedPopover, component);
    }
    static setupClickListeners(clonedPopover, component) {
        if (!clonedPopover)
            return;
        clonedPopover.addEventListener('click', (event) => {
            event.stopPropagation();
        });
    }
    static setupContentListeners(clonedPopover, component) {
        if (!clonedPopover)
            return;
        const contentElement = clonedPopover.querySelector('[part="base"]');
        if (contentElement) {
            contentElement.addEventListener('nile-click', (event) => {
                if (component.handleContentClick) {
                    component.handleContentClick(event);
                }
            });
            contentElement.addEventListener('nile-input', (event) => {
                if (component.handleContentInput) {
                    component.handleContentInput(event);
                }
            });
            contentElement.addEventListener('nile-change', (event) => {
                if (component.handleContentChange) {
                    component.handleContentChange(event);
                }
            });
        }
    }
    static setupActionListeners(clonedPopover, component) {
        if (!clonedPopover)
            return;
        const actionElement = clonedPopover.querySelector('.popover__action');
        if (actionElement) {
            actionElement.addEventListener('click', (event) => {
                const target = event.target;
                if (target.tagName === 'BUTTON' || target.closest('button')) {
                    if (component.handleActionClick) {
                        component.handleActionClick(event);
                    }
                }
            });
            actionElement.addEventListener('nile-click', (event) => {
                if (component.handleActionClick) {
                    component.handleActionClick(event);
                }
            });
        }
    }
    static forwardEventToOriginal(event, component, eventType) {
        const syntheticEvent = new CustomEvent(eventType, {
            bubbles: true,
            cancelable: true,
            detail: event.detail
        });
        component.dispatchEvent(syntheticEvent);
    }
}
//# sourceMappingURL=portal-utils.js.map