/**
 * Fixed-position tooltip for any `[data-tooltip]` element on the page.
 *
 * Rendered in `document.body` with `position: fixed`, positioned from
 * `getBoundingClientRect()` rather than a CSS `::after` on the target itself,
 * since several call sites (editor toolbar rail/pill, admin tables) sit
 * inside scrollable ancestors that would otherwise clip an in-flow tooltip.
 */
export function initTooltips(root: ParentNode = document): void {
    const targets = root.querySelectorAll<HTMLElement>('[data-tooltip]');
    if (!targets.length) {
        return;
    }

    const tooltip = document.createElement('div');
    tooltip.className = 'toolbar-tooltip';
    document.body.appendChild(tooltip);

    const show = (target: HTMLElement): void => {
        const text = target.getAttribute('data-tooltip');
        if (!text) {
            return;
        }
        tooltip.textContent = text;
        tooltip.classList.add('is-visible');

        const rect = target.getBoundingClientRect();
        const tooltipRect = tooltip.getBoundingClientRect();
        const gap = 8;

        let left = rect.right + gap;
        let top = rect.top + rect.height / 2 - tooltipRect.height / 2;

        if (left + tooltipRect.width > window.innerWidth) {
            left = rect.left + rect.width / 2 - tooltipRect.width / 2;
            top = rect.top - tooltipRect.height - gap;

            if (top < 0) {
                top = rect.bottom + gap;
            }
        }

        left = Math.max(gap, Math.min(left, window.innerWidth - tooltipRect.width - gap));

        tooltip.style.left = `${left}px`;
        tooltip.style.top = `${top}px`;
    };

    const hide = (): void => {
        tooltip.classList.remove('is-visible');
    };

    targets.forEach((target) => {
        target.addEventListener('mouseenter', () => show(target));
        target.addEventListener('mouseleave', hide);
        target.addEventListener('focus', () => show(target));
        target.addEventListener('blur', hide);
    });

    window.addEventListener('scroll', hide, true);
}
