import { useEffect, useRef } from "react"; import { useQueryClient } from "@tanstack/react-query"; import { API_ENDPOINTS } from "@/config/api"; interface DeviceEventData { Message: string; DeviceId: string; Room: string; Timestamp?: string; } export function useDeviceEvents(roomName?: string) { const queryClient = useQueryClient(); const reconnectTimeout = useRef | null>(null); useEffect(() => { let onlineES: EventSource | null = null; let offlineES: EventSource | null = null; const connect = () => { onlineES = new EventSource(API_ENDPOINTS.SSE_EVENTS.DEVICE_ONLINE); offlineES = new EventSource(API_ENDPOINTS.SSE_EVENTS.DEVICE_OFFLINE); onlineES.addEventListener("online", (event) => { try { const data: DeviceEventData = JSON.parse(event.data); if (roomName && data.Room === roomName) { queryClient.setQueryData( ["devices", roomName], (oldDevices: any[] = []) => oldDevices.map((d) => d.macAddress === data.DeviceId ? { ...d, isOffline: false } : d ) ); } queryClient.setQueryData(["rooms"], (oldRooms: any[] = []) => oldRooms.map((room) => room.name === data.Room ? { ...room, numberOfOfflineDevices: Math.max(0, room.numberOfOfflineDevices - 1), } : room ) ); } catch (err) { console.error("Error parsing online event:", err); } }); offlineES.addEventListener("offline", (event) => { try { const data: DeviceEventData = JSON.parse(event.data); if (roomName && data.Room === roomName) { queryClient.setQueryData( ["devices", roomName], (oldDevices: any[] = []) => oldDevices.map((d) => d.macAddress === data.DeviceId ? { ...d, isOffline: true } : d ) ); } queryClient.setQueryData(["rooms"], (oldRooms: any[] = []) => oldRooms.map((room) => room.name === data.Room ? { ...room, numberOfOfflineDevices: room.numberOfOfflineDevices + 1, } : room ) ); } catch (err) { console.error("Error parsing offline event:", err); } }); const onError = (err: any) => { console.error("SSE connection error:", err); cleanup(); reconnectTimeout.current = setTimeout(connect, 5000); }; onlineES.onerror = onError; offlineES.onerror = onError; }; const cleanup = () => { if (onlineES) onlineES.close(); if (offlineES) offlineES.close(); if (reconnectTimeout.current) { clearTimeout(reconnectTimeout.current); reconnectTimeout.current = null; } }; connect(); return cleanup; }, [roomName, queryClient]); }