const WebSocket = require('ws');

// Helper function to send notifications via WebSocket
function setupWebSocket(server) {
    console.log('[WS] Initializing WebSocket server...');
    const wss = new WebSocket.Server({ 
        server,
        verifyClient: (info) => {
            // Extract path without query parameters for matching
            const urlPath = info.req.url.split('?')[0];
            // Log connection attempts for debugging
            console.log(`[WS] Connection attempt from ${info.origin || 'unknown'} to path: ${info.req.url}`);
            // Allow connections to /EMS-backend path (with or without query parameters)
            const isAllowed = urlPath === '/EMS-backend';
            if (!isAllowed) {
                console.log(`[WS] Connection rejected - path mismatch: ${urlPath}`);
            } else {
                console.log(`[WS] Connection allowed for path: ${urlPath}`);
            }
            return isAllowed;
        }
    });
    
    console.log('[WS] WebSocket server initialized and listening for connections on /EMS-backend');

    wss.on('connection', (ws, req) => {
        console.log(`[WS] User connected from ${req.socket.remoteAddress}`);
        ws.subscriptions = new Set();
        
        ws.on('error', (error) => {
            console.error('[WS] WebSocket error:', error);
        });
        
        ws.on('message', (message) => {
            try {
                const data = JSON.parse(message);
                
                if (data.type === 'join-user-room' && data.userId) {
                    // Store user ID in the WebSocket connection
                    ws.userId = data.userId;
                    console.log(`[WS] User ${data.userId} registered and joined their room`);
                }

                if (data.type === 'subscribe-dispatch-updates') {
                    ws.subscriptions.add('dispatch-updates');
                    console.log('[WS] Client subscribed to dispatch updates');
                }

                if (data.type === 'unsubscribe-dispatch-updates') {
                    ws.subscriptions.delete('dispatch-updates');
                    console.log('[WS] Client unsubscribed from dispatch updates');
                }

                // Subscribe to new ambulance requests (for drivers)
                if (data.type === 'subscribe-ambulance-requests') {
                    ws.role = data.role || null;
                    ws.subscriptions.add('ambulance-requests');
                    console.log(`[WS] Client subscribed to ambulance request updates (role: ${data.role || 'unknown'})`);
                }

                if (data.type === 'unsubscribe-ambulance-requests') {
                    ws.subscriptions.delete('ambulance-requests');
                    console.log('[WS] Client unsubscribed from ambulance request updates');
                }
            } catch (error) {
                console.error('Error parsing WebSocket message:', error);
            }
        });
        
        ws.on('close', () => {
            console.log('User disconnected');
        });
    });

    // Helper function to send notifications via WebSocket
    function sendNotification(userId, notification) {
        wss.clients.forEach((client) => {
            if (client.readyState === WebSocket.OPEN && client.userId === userId) {
                console.log(`[WS] Sending notification to user ${userId}: ${notification.type || 'notification'}`);
                client.send(JSON.stringify({
                    type: 'notification',
                    data: notification
                }));
            }
        });
    }

    // Broadcast dispatch updates to subscribed clients
    function broadcastDispatch(dispatchEvent) {
        const payload = {
            type: 'ambulance-dispatched',
            data: dispatchEvent
        };

        wss.clients.forEach((client) => {
            if (client.readyState === WebSocket.OPEN && client.subscriptions?.has('dispatch-updates')) {
                console.log('[WS] Broadcasting ambulance dispatch event');
                client.send(JSON.stringify(payload));
            }
        });
    }

    // Broadcast new ambulance request to all drivers
    function broadcastNewAmbulanceRequest(requestData) {
        const payload = {
            type: 'new-ambulance-request',
            data: requestData
        };

        let sentCount = 0;
        wss.clients.forEach((client) => {
            if (client.readyState === WebSocket.OPEN && 
                client.subscriptions?.has('ambulance-requests') &&
                client.role === 'driver') {
                console.log(`[WS] Broadcasting new ambulance request to driver (userId: ${client.userId})`);
                client.send(JSON.stringify(payload));
                sentCount++;
            }
        });
        console.log(`[WS] Broadcast new ambulance request to ${sentCount} driver(s)`);
    }

    // Broadcast when a request is assigned (removed from pending) to all drivers
    function broadcastRequestAssigned(requestId, dispatchData) {
        const payload = {
            type: 'request-assigned',
            data: {
                request_id: requestId,
                dispatch_id: dispatchData?.dispatch_id || null,
                ambulance_id: dispatchData?.ambulance_id || null,
                driver_id: dispatchData?.driver_id || null,
                status: 'dispatched'
            }
        };

        let sentCount = 0;
        wss.clients.forEach((client) => {
            if (client.readyState === WebSocket.OPEN && 
                client.subscriptions?.has('ambulance-requests') &&
                client.role === 'driver') {
                console.log(`[WS] Broadcasting request assigned to driver (userId: ${client.userId})`);
                client.send(JSON.stringify(payload));
                sentCount++;
            }
        });
        console.log(`[WS] Broadcast request assigned to ${sentCount} driver(s)`);
    }

    return { wss, sendNotification, broadcastDispatch, broadcastNewAmbulanceRequest, broadcastRequestAssigned };
}

module.exports = setupWebSocket;



