const App = (() => {
    let _ws = null;
    let _reconnectDelay = 1000;
    let _reconnectTimer = null;
    let _serverConfig = null;

    // Tooltip global position:fixed
    const tip = document.getElementById('tooltip');
    let _tt;
    document.addEventListener('mouseover', e => {
        const el = e.target.closest('[data-tip]');
        if (!el) return;
        clearTimeout(_tt);
        _tt = setTimeout(() => {
            tip.textContent = el.dataset.tip;
            tip.classList.add('show');
        }, 120);
    });
    document.addEventListener('mousemove', e => {
        if (!tip.classList.contains('show')) return;
        const w = tip.offsetWidth, h = tip.offsetHeight;
        let x = e.clientX - w / 2, y = e.clientY - h - 10;
        x = Math.max(6, Math.min(x, window.innerWidth - w - 6));
        if (y < 6) y = e.clientY + 18;
        tip.style.left = x + 'px';
        tip.style.top = y + 'px';
    });
    document.addEventListener('mouseout', e => {
        if (!e.target.closest('[data-tip]')) return;
        clearTimeout(_tt);
        tip.classList.remove('show');
    });

    function toggleTheme() {
        const h = document.documentElement;
        h.dataset.theme = h.dataset.theme === 'dark' ? 'light' : 'dark';
        document.getElementById('theme-icon').className =
            h.dataset.theme === 'dark' ? 'fa-solid fa-moon' : 'fa-solid fa-sun';
    }

    function updateClock() {
        document.getElementById('f-time').textContent =
            new Date().toLocaleTimeString('fr-FR');
    }

    function updateServerStats(stats) {
        const cpu = stats.cpu_percent ?? 0;
        const memPct = stats.mem_total > 0 ? (stats.mem_used / stats.mem_total * 100) : 0;
        const cpuEl = document.getElementById('srv-cpu');
        const memEl = document.getElementById('srv-mem');
        const cpuBar = document.getElementById('srv-cpu-bar');
        const memBar = document.getElementById('srv-mem-bar');
        if (cpuEl) {
            cpuEl.textContent = cpu.toFixed(0) + '%';
            cpuEl.className = 'f-val' + (cpu >= 70 ? ' w' : '');
        }
        if (cpuBar) {
            cpuBar.style.width = cpu.toFixed(0) + '%';
            cpuBar.className = 'f-minifill' + (cpu >= 70 ? ' w' : '');
        }
        if (memEl) {
            memEl.textContent = memPct.toFixed(0) + '%';
            memEl.className = 'f-val' + (memPct >= 70 ? ' w' : '');
        }
        if (memBar) {
            memBar.style.width = memPct.toFixed(0) + '%';
            memBar.className = 'f-minifill' + (memPct >= 70 ? ' w' : '');
        }
    }

    function connectWS() {
        const proto = location.protocol === 'https:' ? 'wss' : 'ws';
        _ws = new WebSocket(`${proto}://${location.host}/ws`);

        _ws.onopen = () => {
            _reconnectDelay = 1000;
            document.querySelector('.logo-led').style.animation = 'blink 2s infinite';
        };

        _ws.onmessage = (event) => {
            try {
                const msg = JSON.parse(event.data);
                if (msg.type === 'metrics_update') {
                    Grid.update(msg.agent_id, msg.data);
                    updateClock();
                } else if (msg.type === 'server_stats') {
                    updateServerStats(msg.data);
                } else if (msg.type === 'status_update') {
                    Grid.updateStatus(msg.agent_id, msg.data.status);
                }
            } catch {}
        };

        _ws.onclose = () => {
            clearTimeout(_reconnectTimer);
            _reconnectTimer = setTimeout(connectWS, _reconnectDelay);
            _reconnectDelay = Math.min(_reconnectDelay * 2, 30000);
        };
    }

    async function init() {
        try {
            _serverConfig = await API.getServerConfig();
            if (_serverConfig.tile_min_width) {
                document.documentElement.style.setProperty('--tile-min', _serverConfig.tile_min_width + 'px');
            }
            if (_serverConfig.font_size) {
                document.body.style.fontSize = _serverConfig.font_size + 'px';
            }
            if (_serverConfig.popup_detail_w && _serverConfig.popup_detail_h) {
                const pd = document.getElementById('popup-detail');
                pd.style.width = _serverConfig.popup_detail_w + 'px';
                pd.style.height = _serverConfig.popup_detail_h + 'px';
            }
        } catch {}

        try {
            const agents = await API.getAgents();
            Grid.refresh(agents);
        } catch {}

        connectWS();
        updateClock();
        setInterval(updateClock, 1000);
    }

    document.addEventListener('DOMContentLoaded', init);

    return {
        toggleTheme,
        get serverConfig() { return _serverConfig; },
        set serverConfig(v) { _serverConfig = v; },
    };
})();
