/**
 * Shared SSE service for dashboard components.
 * Manages a single EventSource connection and distributes events to subscribers.
 */
(function(globalThis) {
    'use strict';
    
    class SSEService {
        constructor() {
            this.eventSource = null;
            this.subscribers = new Map();
            this.isConnecting = false;
            this.reconnectDelay = 1000;
            this.maxReconnectDelay = 30000;
        }
        
        /**
         * Subscribe to specific event types
         * @param {string} id - Unique subscriber ID
         * @param {Set<string>} eventTypes - Event types to listen for
         * @param {Function} callback - Callback function for events
         */
        subscribe(id, eventTypes, callback) {
            this.subscribers.set(id, { eventTypes, callback });
            
            if (!this.eventSource && !this.isConnecting) {
                this.connect();
            }
            
            // Return unsubscribe function
            return () => {
                this.subscribers.delete(id);
                if (this.subscribers.size === 0 && this.eventSource) {
                    this.disconnect();
                }
            };
        }
        
        connect() {
            if (this.isConnecting || this.eventSource) {
                return;
            }
            
            this.isConnecting = true;
            
            // Wait for APP_CONFIG to be loaded from /config before connecting
            const configReady = globalThis.__APP_CONFIG_READY__ || Promise.resolve(globalThis.APP_CONFIG);
            configReady.then(() => this._doConnect()).catch(() => this._doConnect());
        }
        
        _doConnect() {
            if (this.eventSource) {
                this.isConnecting = false;
                return;
            }
            
            const apiUrl = globalThis.APP_CONFIG?.api_url || globalThis.location.origin;
            const apiKey = globalThis.APP_CONFIG?.api_key || "sk-proxy-local-dev";
            const sseUrl = new URL("/dashboard/events/stream", apiUrl);
            sseUrl.searchParams.set("token", apiKey);
            
            try {
                this.eventSource = new EventSource(sseUrl.toString());
                
                this.eventSource.onopen = () => {
                    console.log("SSE connected");
                    this.isConnecting = false;
                    this.reconnectDelay = 1000;
                };
                
                this.eventSource.onmessage = (evt) => {
                    try {
                        const event = JSON.parse(evt.data);
                        this.distributeEvent(event);
                    } catch (e) {
                        console.warn("Malformed SSE event:", e);
                    }
                };
                
                this.eventSource.onerror = () => {
                    console.warn("SSE connection error");
                    this.isConnecting = false;
                    this.disconnect();
                    
                    // Exponential backoff reconnection
                    setTimeout(() => {
                        if (this.subscribers.size > 0) {
                            this.connect();
                        }
                    }, this.reconnectDelay);
                    
                    this.reconnectDelay = Math.min(
                        this.reconnectDelay * 2,
                        this.maxReconnectDelay
                    );
                };
                
            } catch (e) {
                console.error("Failed to create SSE connection:", e);
                this.isConnecting = false;
            }
        }
        
        disconnect() {
            if (this.eventSource) {
                this.eventSource.close();
                this.eventSource = null;
            }
        }
        
        distributeEvent(event) {
            if (!event?.event_type) return;
            
            for (const [id, { eventTypes, callback }] of this.subscribers) {
                if (eventTypes.has(event.event_type)) {
                    try {
                        callback(event);
                    } catch (e) {
                        console.error(`Error in SSE subscriber ${id}:`, e);
                    }
                }
            }
        }
    }
    
    // Create singleton instance
    globalThis.SSEService = new SSEService();
    
})(globalThis);
