import { useState, useEffect, useCallback } from 'react' import { notificationService } from '@/lib/notificationService' import type { Notification } from '@/lib/notificationService' const MAX_NOTIFICATIONS = 100 const POLL_INTERVAL_MS = 30_000 export function useNotifications(userPubkey: string | null): { notifications: Notification[] unreadCount: number loading: boolean markAsRead: (notificationId: string) => void markAllAsRead: () => void deleteNotification: (notificationId: string) => void } { const [notifications, setNotifications] = useState([]) const [loading, setLoading] = useState(true) useNotificationsPoller({ userPubkey, setNotifications, setLoading }) const effectiveNotifications = userPubkey ? notifications : [] const effectiveLoading = userPubkey ? loading : false const unreadCount = effectiveNotifications.filter((n) => !n.read).length const actions = useNotificationActions({ userPubkey, setNotifications }) return { notifications: effectiveNotifications, unreadCount, loading: effectiveLoading, markAsRead: actions.markAsRead, markAllAsRead: actions.markAllAsRead, deleteNotification: actions.deleteNotification, } } function useNotificationsPoller(params: { userPubkey: string | null setNotifications: (value: Notification[]) => void setLoading: (value: boolean) => void }): void { useEffect(() => { if (!params.userPubkey) { return } void loadAndSetNotifications({ setNotifications: params.setNotifications, setLoading: params.setLoading }) const interval = setInterval(() => { void loadAndSetNotifications({ setNotifications: params.setNotifications, setLoading: params.setLoading }) }, POLL_INTERVAL_MS) return () => clearInterval(interval) }, [params.userPubkey, params.setNotifications, params.setLoading]) } function useNotificationActions(params: { userPubkey: string | null setNotifications: (value: Notification[]) => void }): { markAsRead: (notificationId: string) => void markAllAsRead: () => void deleteNotification: (notificationId: string) => void } { const markAsRead = useCallback((notificationId: string): void => { if (!params.userPubkey) { return } void markAsReadAndRefresh({ notificationId, setNotifications: params.setNotifications }) }, [params.userPubkey, params.setNotifications]) const markAllAsRead = useCallback((): void => { if (!params.userPubkey) { return } void markAllAsReadAndRefresh({ setNotifications: params.setNotifications }) }, [params.userPubkey, params.setNotifications]) const deleteNotification = useCallback((notificationId: string): void => { if (!params.userPubkey) { return } void deleteNotificationAndRefresh({ notificationId, setNotifications: params.setNotifications }) }, [params.userPubkey, params.setNotifications]) return { markAsRead, markAllAsRead, deleteNotification } } async function loadAndSetNotifications(params: { setNotifications: (value: Notification[]) => void setLoading: (value: boolean) => void }): Promise { try { params.setLoading(true) params.setNotifications(await notificationService.getAllNotifications(MAX_NOTIFICATIONS)) } catch (error) { console.error('[useNotifications] Error loading notifications:', error) } finally { params.setLoading(false) } } async function refreshNotifications(params: { setNotifications: (value: Notification[]) => void }): Promise { params.setNotifications(await notificationService.getAllNotifications(MAX_NOTIFICATIONS)) } async function markAsReadAndRefresh(params: { notificationId: string setNotifications: (value: Notification[]) => void }): Promise { try { await notificationService.markAsRead(params.notificationId) await refreshNotifications({ setNotifications: params.setNotifications }) } catch (error) { console.error('[useNotifications] Error marking notification as read:', error) } } async function markAllAsReadAndRefresh(params: { setNotifications: (value: Notification[]) => void }): Promise { try { await notificationService.markAllAsRead() await refreshNotifications({ setNotifications: params.setNotifications }) } catch (error) { console.error('[useNotifications] Error marking all as read:', error) } } async function deleteNotificationAndRefresh(params: { notificationId: string setNotifications: (value: Notification[]) => void }): Promise { try { await notificationService.deleteNotification(params.notificationId) await refreshNotifications({ setNotifications: params.setNotifications }) } catch (error) { console.error('[useNotifications] Error deleting notification:', error) } }