import { useEffect, useRef, useState } from 'react'; import { io, Socket } from 'socket.io-client'; import { AdminNotification } from '@/types/admin.types'; import { SOCKET_URL } from '@/config/backend'; import { getAccessToken } from '@/components/apis/authApiClients'; interface NotificationCounts { total: number; unread: number; read: number; } interface UseNotificationSocketReturn { socket: Socket | null; isConnected: boolean; notificationCounts: NotificationCounts; onNewNotification: (callback: (notification: AdminNotification) => void) => void; onNotificationRead: (callback: (data: { id: string }) => void) => void; onAllNotificationsRead: (callback: () => void) => void; } export function useNotificationSocket(): UseNotificationSocketReturn { const [socket, setSocket] = useState(null); const [isConnected, setIsConnected] = useState(false); const [notificationCounts, setNotificationCounts] = useState({ total: 0, unread: 0, read: 0 }); const newNotificationCallbackRef = useRef<((notification: AdminNotification) => void) | null>(null); const notificationReadCallbackRef = useRef<((data: { id: string }) => void) | null>(null); const allNotificationsReadCallbackRef = useRef<(() => void) | null>(null); useEffect(() => { // Initialize socket connection const templateManagerUrl = SOCKET_URL; // connect directly to template-manager socket server const token = getAccessToken(); console.log('[useNotificationSocket] Initializing socket', { url: templateManagerUrl, hasToken: !!token, tokenPreview: token ? token.substring(0, 12) + '...' : null }); const newSocket = io(templateManagerUrl, { transports: ['websocket', 'polling'], timeout: 20000, path: '/socket.io/', auth: token ? { token } : undefined, }); newSocket.on('connect', () => { console.log('🔌 Connected to notification socket'); setIsConnected(true); }); newSocket.on('disconnect', () => { console.log('🔌 Disconnected from notification socket'); setIsConnected(false); }); newSocket.on('notification-count', (counts: NotificationCounts) => { console.log('📊 Notification counts updated:', counts); setNotificationCounts(counts); }); newSocket.on('new-notification', (notification: AdminNotification) => { console.log('🔔 New notification received:', notification); if (newNotificationCallbackRef.current) { newNotificationCallbackRef.current(notification); } }); newSocket.on('notification-read', (data: { id: string }) => { console.log('✅ Notification marked as read:', data.id); if (notificationReadCallbackRef.current) { notificationReadCallbackRef.current(data); } }); newSocket.on('all-notifications-read', () => { console.log('✅ All notifications marked as read'); if (allNotificationsReadCallbackRef.current) { allNotificationsReadCallbackRef.current(); } }); newSocket.on('connect_error', (error: any) => { console.error('🔌 Socket connection error:', { message: error?.message, name: error?.name, data: error?.data }); setIsConnected(false); }); setSocket(newSocket); return () => { newSocket.close(); }; }, []); const onNewNotification = (callback: (notification: AdminNotification) => void) => { newNotificationCallbackRef.current = callback; }; const onNotificationRead = (callback: (data: { id: string }) => void) => { notificationReadCallbackRef.current = callback; }; const onAllNotificationsRead = (callback: () => void) => { allNotificationsReadCallbackRef.current = callback; }; return { socket, isConnected, notificationCounts, onNewNotification, onNotificationRead, onAllNotificationsRead, }; }