// Hover tooltips — v1
// Icon-first UI: every actionable control carries a [data-tip] label that
// surfaces on hover. UXP's CSS engine can't be trusted with
// `content: attr(data-tip)` on ::after, so we position a single floating
// bubble with plain DOM + getBoundingClientRect (both well supported).

(function () {
  let bubble = null;
  let timer  = null;

  function ensure() {
    if (bubble) return bubble;
    bubble = document.createElement('div');
    bubble.className = 'tip-bubble';
    document.body.appendChild(bubble);
    return bubble;
  }

  function show(el) {
    const text = el.getAttribute('data-tip');
    if (!text) return;
    const tip = ensure();
    tip.textContent = text;
    tip.style.display = 'block';
    tip.style.opacity = '0';

    const r = el.getBoundingClientRect();
    const t = tip.getBoundingClientRect();
    // position:absolute on a body-level node is offset from the document
    // origin; add scroll offset (0 in practice, body doesn't scroll) for safety.
    const sx = window.pageXOffset || document.documentElement.scrollLeft || 0;
    const sy = window.pageYOffset || document.documentElement.scrollTop || 0;
    const gap = 7;
    const pos = el.getAttribute('data-tip-pos') || 'down';
    let x, y;

    if (pos === 'right') {
      x = r.right + gap;            y = r.top + (r.height - t.height) / 2;
    } else if (pos === 'up') {
      x = r.left + (r.width - t.width) / 2; y = r.top - t.height - gap;
    } else if (pos === 'up-left') {
      x = r.right - t.width;        y = r.top - t.height - gap;
    } else if (pos === 'down-left') {
      x = r.right - t.width;        y = r.bottom + gap;
    } else {
      x = r.left + (r.width - t.width) / 2; y = r.bottom + gap;
    }

    const vw = window.innerWidth || document.documentElement.clientWidth || 99999;
    const vh = window.innerHeight || document.documentElement.clientHeight || 99999;
    x = Math.max(4, Math.min(x, vw - t.width - 4));
    y = Math.max(4, Math.min(y, vh - t.height - 4));
    tip.style.left = (x + sx) + 'px';
    tip.style.top  = (y + sy) + 'px';
    tip.style.opacity = '1';
  }

  function hide() {
    clearTimeout(timer);
    if (bubble) { bubble.style.opacity = '0'; bubble.style.display = 'none'; }
  }

  function bind(el) {
    el.addEventListener('mouseenter', () => {
      clearTimeout(timer);
      timer = setTimeout(() => show(el), 240);
    });
    el.addEventListener('mouseleave', hide);
    el.addEventListener('click', hide);
  }

  function init() {
    document.querySelectorAll('[data-tip]').forEach(bind);
  }

  if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', init);
  else init();
})();
