"use client" import { createContext, useContext, useState, useCallback, useMemo, useEffect, ReactNode } from "react" import { Notification, NotificationType } from "@/types" import { leads } from "@/data/leads" 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) function generateId(): string { return `notif-${Date.now()}-${Math.random().toString(36).slice(2, 7)}` } function seedInitialNotifications(): Notification[] { const result: Notification[] = [] const recentLeads = leads.slice(0, 5) recentLeads.forEach((lead) => { result.push({ id: generateId(), type: "lead_created", title: "New Lead Created", description: `${lead.companyName} — ${lead.contactName}`, timestamp: lead.createdAt, read: false, link: `/leads/${lead.id}`, }) }) const statusChanged = leads.filter((l) => l.status !== "open").slice(0, 3) statusChanged.forEach((lead) => { result.push({ id: generateId(), type: "lead_status_changed", title: "Lead Status Updated", description: `${lead.companyName} moved to ${lead.status}`, timestamp: lead.updatedAt, read: false, link: `/leads/${lead.id}`, }) }) const assignedLeads = leads.filter((l) => l.assignedUser).slice(0, 3) assignedLeads.forEach((lead) => { result.push({ id: generateId(), type: "lead_assigned", title: "Lead Assigned", description: `${lead.companyName} assigned to ${lead.assignedUser!.name}`, timestamp: lead.updatedAt, read: false, link: `/leads/${lead.id}`, }) }) result.sort((a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime()) return result } export function NotificationProvider({ children }: { children: ReactNode }) { const [notifications, setNotifications] = useState(seedInitialNotifications) const [unreadChatCount, setUnreadChatCount] = useState(0) 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( (type: NotificationType, title: string, description: string, link?: string) => { const notif: Notification = { id: generateId(), type, title, description, timestamp: new Date().toISOString(), read: false, link, } setNotifications((prev) => [notif, ...prev]) }, [] ) const markAsRead = useCallback((id: string) => { setNotifications((prev) => prev.map((n) => (n.id === id ? { ...n, read: true } : n)) ) }, []) const markAllAsRead = useCallback(() => { setNotifications((prev) => prev.map((n) => ({ ...n, read: true }))) }, []) const dismiss = useCallback((id: string) => { setNotifications((prev) => prev.filter((n) => n.id !== id)) }, []) return ( {children} ) } export function useNotifications(): NotificationContextValue { const ctx = useContext(NotificationContext) if (!ctx) { throw new Error("useNotifications must be used within a NotificationProvider") } return ctx }