"use client" import { createContext, useContext, useState, useCallback, useMemo, useEffect, ReactNode } from "react" import { Notification, NotificationType } from "@/types" interface NotificationContextValue { notifications: Notification[] unreadCount: number unreadChatCount: number addNotification: (type: NotificationType, title: string, description: string, link?: string) => void markAsRead: (id: string) => void markAllAsRead: () => void dismiss: (id: string) => void } const NotificationContext = createContext(null) export function NotificationProvider({ children }: { children: ReactNode }) { const [notifications, setNotifications] = useState([]) const [loading, setLoading] = useState(true) const [unreadChatCount, setUnreadChatCount] = useState(0) useEffect(() => { async function fetchNotifications() { try { const res = await fetch("/api/notifications") if (!res.ok) return const data = await res.json() if (data.notifications) { setNotifications(data.notifications) } } catch { // ignore } finally { setLoading(false) } } fetchNotifications() }, []) useEffect(() => { let cancelled = false async function fetchUnread() { try { const res = await fetch("/api/conversations") if (!res.ok) return const data = await res.json() if (!cancelled) { const list = data.conversations || [] const total = list.reduce((sum: number, c: any) => sum + (c.unread || 0), 0) setUnreadChatCount(total) } } catch { // ignore } } fetchUnread() const id = setInterval(fetchUnread, 5000) return () => { cancelled = true; clearInterval(id) } }, []) const unreadCount = useMemo( () => notifications.filter((n) => !n.read).length, [notifications] ) const addNotification = useCallback( async (type: NotificationType, title: string, description: string, link?: string) => { const notif: Notification = { id: `temp-${Date.now()}`, type, title, description, timestamp: new Date().toISOString(), read: false, link, } setNotifications((prev) => [notif, ...prev]) try { await fetch("/api/notifications", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ type, title, description, link }), }) } catch { // ignore } }, [] ) const markAsRead = useCallback(async (id: string) => { if (id.startsWith("temp-")) return setNotifications((prev) => prev.map((n) => (n.id === id ? { ...n, read: true } : n)) ) try { await fetch(`/api/notifications/${id}`, { method: "PATCH" }) } catch { // ignore } }, []) const markAllAsRead = useCallback(async () => { setNotifications((prev) => prev.map((n) => ({ ...n, read: true }))) try { await fetch("/api/notifications", { method: "PATCH" }) } catch { // ignore } }, []) const dismiss = useCallback(async (id: string) => { setNotifications((prev) => prev.filter((n) => n.id !== id)) if (id.startsWith("temp-")) return try { await fetch(`/api/notifications/${id}`, { method: "DELETE" }) } catch { // ignore } }, []) return ( {children} ) } export function useNotifications(): NotificationContextValue { const ctx = useContext(NotificationContext) if (!ctx) { throw new Error("useNotifications must be used within a NotificationProvider") } return ctx }