// ── tray-tooltip.js ───────────────────────────────────────────────────────────
//
// Hover-triggered tooltips on the tray's two card cells, both portalled to
// #id_tooltip_portal so they escape the tray's overflow:hidden clip.
//
//   Phase 1 — .tray-role-card > img:
//     Copies its sibling .tt's innerHTML into the portal. No btns.
//   Phase 2 — .tray-sig-card > .sig-stage-card:
//     Builds an FYI panel via StageCard.buildInfoData / renderFyi from the
//     stage card's data-energies + data-operations attrs. PRV/NXT btns cycle
//     through entries. NO click-to-dismiss (departure from the fan stage's
//     #id_fan_fyi_panel — the panel-body click is reserved for future
//     drag-and-drop on .tray-sig-card:active).
//
// Mouseleave: a document-level mousemove listener hides the portal when the
// pointer leaves the union of [trigger, portal] rects (Game-Kit pattern).
// For the sig branch, the union additionally covers .fyi-prev / .fyi-next
// since their absolute positioning makes them spill past the portal's edges.
//
// ─────────────────────────────────────────────────────────────────────────────

var TrayTooltip = (function () {
    var _portal      = null;
    var _activeTrig  = null;
    var _activeCell  = null;   // .tray-role-card / .tray-sig-card holding the tilt class
    var _activeKind  = null;   // "role" | "sig"
    var _infoData    = [];
    var _infoIdx     = 0;
    var _onDocMove   = null;
    var _observer    = null;

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

    function _hide() {
        if (!_portal) return;
        _portal.classList.remove("active");
        _portal.style.display = "none";
        _portal.innerHTML = "";
        if (_activeCell) _activeCell.classList.remove("tt-active");
        _activeCell = null;
        _activeTrig = null;
        _activeKind = null;
        _infoData   = [];
        _infoIdx    = 0;
    }

    // Find the .tray-role-card / .tray-sig-card ancestor of a trigger so we
    // can keep its hover-tilt locked while the portal is open.
    function _cellOf(triggerEl) {
        return triggerEl.closest && triggerEl.closest(".tray-role-card, .tray-sig-card");
    }

    function _position(triggerEl) {
        var triggerRect = triggerEl.getBoundingClientRect();
        var halfW       = _portal.offsetWidth / 2;
        var rawLeft     = triggerRect.left + triggerRect.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 triggerCY  = triggerRect.top + triggerRect.height / 2;
        if (triggerCY < window.innerHeight / 2) {
            _portal.style.top       = Math.round(triggerRect.bottom) + "px";
            _portal.style.transform = "translate(-50%, 0.5rem)";
        } else {
            _portal.style.top       = Math.round(triggerRect.top) + "px";
            _portal.style.transform = "translate(-50%, calc(-100% - 0.5rem))";
        }
    }

    function _showRole(triggerEl) {
        var tt = triggerEl.parentElement && triggerEl.parentElement.querySelector(".tt");
        if (!tt || !_portal) return;
        _portal.innerHTML = tt.innerHTML;
        _portal.classList.add("active");
        _portal.style.display = "block";
        _activeTrig = triggerEl;
        _activeKind = "role";
        _activeCell = _cellOf(triggerEl);
        if (_activeCell) _activeCell.classList.add("tt-active");
        _position(triggerEl);
    }

    // Build the FYI panel HTML used by the sig branch — same DOM shape as
    // _partials/_sig_fyi_panel.html so SCSS rules and StageCard.renderFyi work
    // unchanged. Kept here (not loaded from the partial) so the portal remains
    // a single page-level element with no per-trigger duplication.
    var _SIG_PANEL_HTML = ''
        + '<div class="sig-info">'
        +   '<div class="sig-info-header">'
        +     '<h4 class="sig-info-title"></h4>'
        +     '<p class="sig-info-type"></p>'
        +   '</div>'
        +   '<p class="sig-info-effect"></p>'
        +   '<span class="sig-info-index"></span>'
        + '</div>'
        + '<button class="btn btn-nav-left fyi-prev" type="button">PRV</button>'
        + '<button class="btn btn-nav-right fyi-next" type="button">NXT</button>';

    function _showSig(triggerEl) {
        if (!_portal) return;
        var card = (typeof StageCard !== "undefined")
            ? StageCard.fromDataset(triggerEl)
            : { energies: [], operations: [] };
        _infoData = (typeof StageCard !== "undefined")
            ? StageCard.buildInfoData(card)
            : [];
        _infoIdx  = 0;

        _portal.innerHTML = _SIG_PANEL_HTML;
        var infoPanel = _portal.querySelector(".sig-info");
        if (typeof StageCard !== "undefined") {
            StageCard.renderFyi(infoPanel, _infoData, _infoIdx);
        }
        _portal.classList.add("active");
        _portal.style.display = "block";
        _activeTrig = triggerEl;
        _activeKind = "sig";
        _activeCell = _cellOf(triggerEl);
        if (_activeCell) _activeCell.classList.add("tt-active");

        _portal.querySelector(".fyi-prev").addEventListener("click", function (e) {
            e.stopPropagation();
            if (!_infoData.length) return;
            _infoIdx = (_infoIdx - 1 + _infoData.length) % _infoData.length;
            StageCard.renderFyi(infoPanel, _infoData, _infoIdx);
        });
        _portal.querySelector(".fyi-next").addEventListener("click", function (e) {
            e.stopPropagation();
            if (!_infoData.length) return;
            _infoIdx = (_infoIdx + 1) % _infoData.length;
            StageCard.renderFyi(infoPanel, _infoData, _infoIdx);
        });

        _position(triggerEl);
    }

    function _bindTriggers() {
        var roleImgs = document.querySelectorAll("#id_tray_grid .tray-role-card > img");
        roleImgs.forEach(function (img) {
            if (img._trayTooltipBound) return;
            img._trayTooltipBound = true;
            img.addEventListener("mouseenter", function () {
                if (_activeTrig === img) return;
                _showRole(img);
            });
        });

        var sigStages = document.querySelectorAll("#id_tray_grid .tray-sig-card > .sig-stage-card");
        sigStages.forEach(function (stage) {
            if (stage._trayTooltipBound) return;
            stage._trayTooltipBound = true;
            stage.addEventListener("mouseenter", function () {
                if (_activeTrig === stage) return;
                _showSig(stage);
            });
        });
    }

    function _activeUnion() {
        if (!_activeTrig || !_portal) return null;
        var rects = [
            _activeTrig.getBoundingClientRect(),
            _portal.getBoundingClientRect(),
        ];
        if (_activeKind === "sig") {
            var prv = _portal.querySelector(".fyi-prev");
            var nxt = _portal.querySelector(".fyi-next");
            if (prv) rects.push(prv.getBoundingClientRect());
            if (nxt) rects.push(nxt.getBoundingClientRect());
        }
        return {
            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; })),
        };
    }

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

        _bindTriggers();

        var grid = document.getElementById("id_tray_grid");
        if (grid && typeof MutationObserver !== "undefined") {
            _observer = new MutationObserver(_bindTriggers);
            _observer.observe(grid, { childList: true, subtree: true });
        }

        _onDocMove = function (e) {
            if (!_portal.classList.contains("active") || !_activeTrig) return;
            var union = _activeUnion();
            if (!union) return;
            if (!_inRect(e.clientX, e.clientY, union)) _hide();
        };
        document.addEventListener("mousemove", _onDocMove);
    }

    function reset() {
        if (_onDocMove) document.removeEventListener("mousemove", _onDocMove);
        if (_observer) _observer.disconnect();
        _onDocMove = null;
        _observer = null;
        _hide();
        _portal = null;
        // Drop the bind sentinel so a re-init re-binds the same DOM nodes
        // (Jasmine afterEach pattern).
        document.querySelectorAll("[data-tray-tt-bound]").forEach(function (el) {
            delete el._trayTooltipBound;
        });
    }

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

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