// ── position-tooltip.js ───────────────────────────────────────────────────────
//
// Hover-triggered rich tooltips on the gate-position circles (1–6), portalled
// to #id_position_tooltip_portal (page-root, position:fixed) so they escape
// the tray's overflow / any mask-image clip. Mirrors tray-tooltip.js's
// hover + viewport-clamp + document-mousemove union-hide shape, but reads its
// content from each circle's data-tt-* attrs (filled server-side) rather than
// a sibling .tt.
//
// On .gate-slot mouseenter:
//   • skip empty circles (no data-tt-title)
//   • copy the circle's .tt-pos-* state class onto the portal (themes per
//     occupant kind: empty / gamer / bud / me-current / me-also)
//   • fill .tt-title (@handle) / .tt-description (title) / .tt-shoptalk /
//     .tt-expiry (seat clock) + the top-right .tt-sign stack (seat
//     significator rank + suit icon; hidden when the seat has no sig yet)
//
// The @handle/title/etc. are computed server-side (at_handle, NOT email) so
// no email leaks into the portal.

var PositionTooltip = (function () {
    var _portal     = null;
    var _activeTrig = null;
    var _posClasses = [];      // .tt-pos-* classes copied onto the portal
    var _onDocMove  = null;

    function _inRect(x, y, r) {
        return x >= r.left && x <= r.right && y >= r.top && y <= r.bottom;
    }

    function _set(sel, val) {
        var el = _portal.querySelector(sel);
        if (el) el.textContent = val || "";
    }

    function _hide() {
        if (!_portal) return;
        _portal.classList.remove("active");
        if (_posClasses.length) {
            _portal.classList.remove.apply(_portal.classList, _posClasses);
            _posClasses = [];
        }
        _portal.style.display = "none";
        _activeTrig = null;
    }

    function _fmtExpiry(iso) {
        if (!iso) return "";
        var d = new Date(iso);
        if (isNaN(d.getTime())) return "";
        return "seat held to " + d.toLocaleDateString();
    }

    // Clamp the fixed portal to the viewport, centred under (or over) the
    // trigger — same shape as tray-tooltip.js _position. The circles sit at
    // the top of the page so the tooltip renders BELOW them.
    function _position(triggerEl) {
        var rect  = triggerEl.getBoundingClientRect();
        var halfW = _portal.offsetWidth / 2;
        var rawLeft = rect.left + rect.width / 2;
        var minLeft = halfW + 8;
        var maxLeft = window.innerWidth - halfW - 8;
        _portal.style.left = Math.round(Math.max(minLeft, Math.min(rawLeft, maxLeft))) + "px";

        var cy = rect.top + rect.height / 2;
        if (cy < window.innerHeight / 2) {
            _portal.style.top       = Math.round(rect.bottom) + "px";
            _portal.style.transform = "translate(-50%, 0.5rem)";
        } else {
            _portal.style.top       = Math.round(rect.top) + "px";
            _portal.style.transform = "translate(-50%, calc(-100% - 0.5rem))";
        }
    }

    function _show(circle) {
        if (!_portal) return;
        var title = circle.dataset.ttTitle;
        if (!title) return;   // empty slot — no occupant tooltip

        var classes = circle.className.match(/tt-pos-[\w-]+/g) || [];
        _posClasses = classes;
        if (classes.length) _portal.classList.add.apply(_portal.classList, classes);

        _set(".tt-title", title);
        _set(".tt-description", circle.dataset.ttDescription);
        _set(".tt-shoptalk", circle.dataset.ttShoptalk);
        _set(".tt-expiry", _fmtExpiry(circle.dataset.ttExpiry));

        var sign = _portal.querySelector(".tt-sign");
        if (sign) {
            var rank = circle.dataset.ttSignRank;
            if (rank) {
                var rankEl = sign.querySelector(".fan-corner-rank");
                if (rankEl) rankEl.textContent = rank;
                var icon = sign.querySelector("i");
                if (icon) icon.className = "fa-solid tt-sign-suit " + (circle.dataset.ttSignSuit || "");
                sign.style.display = "";
            } else {
                sign.style.display = "none";
            }
        }

        _portal.classList.add("active");
        _portal.style.display = "block";
        _activeTrig = circle;
        _position(circle);
    }

    function _bind() {
        document.querySelectorAll(".position-strip .gate-slot").forEach(function (circle) {
            if (circle._posTooltipBound) return;
            circle._posTooltipBound = true;
            circle.addEventListener("mouseenter", function () {
                if (_activeTrig === circle) return;
                _show(circle);
            });
        });
    }

    function init() {
        _portal = document.getElementById("id_position_tooltip_portal");
        if (!_portal) return;
        _portal.style.display = "none";
        _bind();

        _onDocMove = function (e) {
            if (!_portal.classList.contains("active") || !_activeTrig) return;
            var rects = [
                _activeTrig.getBoundingClientRect(),
                _portal.getBoundingClientRect(),
            ];
            var union = {
                left:   Math.min.apply(null, rects.map(function (r) { return r.left;   })),
                top:    Math.min.apply(null, rects.map(function (r) { return r.top;    })),
                right:  Math.max.apply(null, rects.map(function (r) { return r.right;  })),
                bottom: Math.max.apply(null, rects.map(function (r) { return r.bottom; })),
            };
            if (!_inRect(e.clientX, e.clientY, union)) _hide();
        };
        document.addEventListener("mousemove", _onDocMove);
    }

    function reset() {
        if (_onDocMove) document.removeEventListener("mousemove", _onDocMove);
        _onDocMove = null;
        _hide();
        _portal = null;
        document.querySelectorAll(".position-strip .gate-slot").forEach(function (c) {
            delete c._posTooltipBound;
        });
    }

    return { init: init, reset: reset };
})();

if (typeof document !== "undefined") {
    document.addEventListener("DOMContentLoaded", function () {
        PositionTooltip.init();
    });
}
