// ── Provider: Notification Context ──
// Global notification state: fetches notifications from the API on mount,
// polls for unread chat counts every 5 seconds, and provides methods
// to add, mark as read, mark all as read, and dismiss notifications.

"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<NotificationContextValue | null>(null)

/**
 * NotificationProvider — wraps the app to provide notification state and actions.
 * Fetches initial notifications on mount and polls for unread chat counts.
 */
export function NotificationProvider({ children }: { children: ReactNode }) {
  const [notifications, setNotifications] = useState<Notification[]>([])
  const [loading, setLoading] = useState(true)
  const [unreadChatCount, setUnreadChatCount] = useState(0)

  // ── Fetch notifications on mount ──
  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 {
        console.warn("Failed to fetch notifications in notification provider")
      } finally {
        setLoading(false)
      }
    }
    fetchNotifications()
  }, [])

  // ── Poll for unread chat counts every 5 seconds ──
  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 {
        console.warn("Failed to fetch unread conversations in notification provider")
      }
    }
    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 {
        console.warn("Failed to add notification in notification provider")
      }
    },
    []
  )

  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 {
      console.warn("Failed to mark notification as read in notification provider")
    }
  }, [])

  const markAllAsRead = useCallback(async () => {
    setNotifications((prev) => prev.map((n) => ({ ...n, read: true })))
    try {
      await fetch("/api/notifications", { method: "PATCH" })
    } catch {
      console.warn("Failed to mark all notifications as read in notification provider")
    }
  }, [])

  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 {
      console.warn("Failed to dismiss notification in notification provider")
    }
  }, [])

  return (
    <NotificationContext.Provider
      value={{
        notifications,
        unreadCount,
        unreadChatCount,
        addNotification,
        markAsRead,
        markAllAsRead,
        dismiss,
      }}
    >
      {children}
    </NotificationContext.Provider>
  )
}

/**
 * useNotifications — hook to access notification context.
 * Must be called within a NotificationProvider tree.
 */
export function useNotifications(): NotificationContextValue {
  const ctx = useContext(NotificationContext)
  if (!ctx) {
    throw new Error("useNotifications must be used within a NotificationProvider")
  }
  return ctx
}
