(function () {
    var SCENE_W = 360, SCENE_H = 320;

    function scaleTable() {
        var scene = document.querySelector('.room-table-scene');
        var container = document.getElementById('id_game_table');
        if (!scene || !container) return;
        var w = container.clientWidth, h = container.clientHeight;
        if (!w || !h) return;
        var scale = Math.min(w / SCENE_W, h / SCENE_H);
        scene.style.transform = 'scale(' + scale + ')';
        document.documentElement.style.setProperty('--table-scale', scale);
    }

    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', scaleTable);
    } else {
        scaleTable();
    }
    window.addEventListener('resize',     scaleTable);
    window.addEventListener('resize:end', scaleTable);
}());

(function () {
    // Size the sig-select overlay so the card grid clears the tray handle
    // (portrait: right strip 48px; landscape: bottom strip 48px) and any
    // fixed gear/kit buttons that protrude further into the viewport.
    // Mirrors the scaleTable() pattern — runs on load (after tray.js has
    // positioned the tray) and on every resize.
    function sizeSigModal() {
        var overlay = document.querySelector('.sig-overlay');
        if (!overlay) return;

        var vw = window.innerWidth;
        var vh = window.innerHeight;
        var rightInset  = 0;
        var bottomInset = 0;

        var isLandscape = vw > vh;

        // Tray handle: portrait → vertical strip on right; landscape → tray is easily
        // dismissed, so skip the bottomInset calculation (would over-shrink the modal).
        var trayHandle = document.getElementById('id_tray_handle');
        if (trayHandle && !isLandscape) {
            var hr = trayHandle.getBoundingClientRect();
            if (hr.width < hr.height) {
                // Portrait: handle strips the right edge
                rightInset = vw - hr.left;
            }
        }

        // Gear / kit buttons: update right inset if near right edge.
        // In landscape they sit at bottom-right but are also dismissible — skip bottomInset.
        document.querySelectorAll('.room-page > .gear-btn').forEach(function (btn) {
            var br = btn.getBoundingClientRect();
            if (br.right > vw - 30) {
                rightInset = Math.max(rightInset, vw - br.left);
            }
            if (!isLandscape && br.bottom > vh - 30) {
                bottomInset = Math.max(bottomInset, vh - br.top);
            }
        });

        // Landscape: right clears gear/kit buttons; bottom is fixed 60px for the
        // kit-bag handle strip — tray is ignored so the stage has room to breathe.
        // At ≥1800px the right sidebar doubles to 8rem so clear 128px.
        if (isLandscape) {
            var xlBreak = vw >= 1800;
            rightInset  = Math.max(rightInset, xlBreak ? 128 : 64);
            bottomInset = 60;
        }

        overlay.style.paddingRight  = rightInset  + 'px';
        overlay.style.paddingBottom = bottomInset + 'px';

        // Stage card: smaller of 40% stage width OR (80% stage height × 5/8 aspect).
        // libsass can't handle cqw/cqh inside min(), so we compute it here.
        var stageEl = overlay.querySelector('.sig-stage');
        if (stageEl) {
            var sw = stageEl.offsetWidth  - 24;  // subtract padding (0.75rem × 2)
            var sh = stageEl.offsetHeight - 24;
            if (sw > 0 && sh > 0) {
                // Clamp between 90px (never tiny in landscape) and 160px (never
                // dominant on very wide/tall viewports).  In portrait, skip the
                // floor so small modals still scale down naturally.
                var cardW = Math.min(sw * 0.4, sh * 0.8 * 5 / 8, 160);
                if (isLandscape) { cardW = Math.max(cardW, 90); }
                overlay.style.setProperty('--sig-card-w', cardW + 'px');
            }
        }
    }

    window.addEventListener('load',       sizeSigModal);
    window.addEventListener('resize',     sizeSigModal);
    window.addEventListener('resize:end', sizeSigModal);
}());

// Dispatch a custom 'resize:end' event 500 ms after the last 'resize' fires.
// scaleTable, sizeSigModal, and Tray._reposition all subscribe to it so they
// re-measure with settled viewport dimensions after rapid resize sequences.
(function () {
    var t;
    window.addEventListener('resize', function () {
        clearTimeout(t);
        t = setTimeout(function () { window.dispatchEvent(new Event('resize:end')); }, 500);
    });
}());

(function () {
    const roomPage = document.querySelector('.room-page');
    if (!roomPage) return;

    const roomId = roomPage.dataset.roomId;
    const wsScheme = window.location.protocol === 'https:' ? 'wss' : 'ws';
    const ws = new WebSocket(`${wsScheme}://${window.location.host}/ws/room/${roomId}/`);
    window._roomSocket = ws;  // exposed for sig-select.js hover broadcast

    ws.onmessage = function (event) {
        const data = JSON.parse(event.data);
        window.dispatchEvent(new CustomEvent('room:' + data.type, { detail: data }));
    };

    ws.onclose = function (event) {
        if (!event.wasClean) {
            console.warn('Room WebSocket closed unexpectedly');
        }
    };
}());
