/**
 * Global events WebSocket — stays connected while logged in,
 * dispatches DOM custom events that feature modules can listen to.
 *
 * Events dispatched:
 *   server:state_change          — target processing start/stop/crash
 *   server:automation_state_changed — automation activated/deactivated
 *   server:entity_changed        — entity CRUD (create/update/delete)
 *   server:device_health_changed — device online/offline status change
 */

import { apiKey, authRequired } from './state.ts';
import { showRestartingOverlay } from './api.ts';

/** True when the server has signalled it is restarting (not crashed). */
export let serverRestarting = false;

export function clearRestartingFlag() {
    serverRestarting = false;
}

let _ws: WebSocket | null = null;
let _reconnectTimer: ReturnType<typeof setTimeout> | null = null;
let _reconnectDelay = 1000;  // start at 1s, exponential backoff to 30s
const _RECONNECT_MIN = 1000;
const _RECONNECT_MAX = 30000;

export function startEventsWS() {
    stopEventsWS();
    if (authRequired && !apiKey) return;

    const wsProto = location.protocol === 'https:' ? 'wss:' : 'ws:';
    const url = `${wsProto}//${location.host}/api/v1/events/ws?token=${encodeURIComponent(apiKey || '')}`;

    try {
        _ws = new WebSocket(url);
        _ws.onopen = () => {
            _reconnectDelay = _RECONNECT_MIN;  // reset backoff on successful connection
        };
        _ws.onmessage = (event) => {
            try {
                const data = JSON.parse(event.data);
                if (data.type === 'server_restarting') {
                    serverRestarting = true;
                    showRestartingOverlay();
                }
                document.dispatchEvent(new CustomEvent(`server:${data.type}`, { detail: data }));
            } catch {}
        };
        _ws.onclose = () => {
            _ws = null;
            _reconnectTimer = setTimeout(startEventsWS, _reconnectDelay);
            _reconnectDelay = Math.min(_reconnectDelay * 2, _RECONNECT_MAX);
        };
        _ws.onerror = () => {};
    } catch {
        _ws = null;
    }
}

export function stopEventsWS() {
    if (_reconnectTimer) {
        clearTimeout(_reconnectTimer);
        _reconnectTimer = null;
    }
    if (_ws) {
        _ws.onclose = null;
        _ws.close();
        _ws = null;
    }
    _reconnectDelay = _RECONNECT_MIN;
}
