"use client"

import { useEffect, useRef, useCallback, useState } from "react"

import type { Notification } from "../types"

interface UseDesktopNotificationsOptions {
  /** 是否启用桌面推送（默认 false） */
  enabled?: boolean
  /** 通知点击时的跳转回调 */
  onClick?: (notification: Notification) => void
}

interface UseDesktopNotificationsResult {
  /** 当前权限状态 */
  permission: NotificationPermission | "unsupported"
  /** 是否已授权 */
  isGranted: boolean
  /** 请求权限 */
  requestPermission: () => Promise<void>
  /** 发送桌面通知 */
  showNotification: (notification: Notification) => void
}

/**
 * 桌面通知 Hook
 *
 * 使用浏览器 Notification API 发送桌面推送通知，
 * 当用户不在页面标签页时仍可收到通知提醒。
 *
 * 使用场景：
 * - SSE 收到新通知时触发桌面推送
 * - 用户切换到其他标签页时仍能收到提醒
 *
 * 权限流程：
 * 1. 默认权限为 "default"（未询问）
 * 2. 调用 requestPermission() 弹出浏览器权限询问框
 * 3. 用户授权后可调用 showNotification 发送桌面通知
 *
 * 浏览器兼容性：
 * - Chrome/Edge/Firefox 桌面版完整支持
 * - Safari 桌面版 13+ 支持
 * - 移动端浏览器不支持（自动降级为无桌面推送）
 */
export function useDesktopNotifications(
  options?: UseDesktopNotificationsOptions
): UseDesktopNotificationsResult {
  const enabled = options?.enabled ?? false
  const [permission, setPermission] = useState<NotificationPermission | "unsupported">(
    typeof window !== "undefined" && "Notification" in window
      ? Notification.permission
      : "unsupported"
  )

  const onClickRef = useRef(options?.onClick)
  useEffect(() => {
    onClickRef.current = options?.onClick
  }, [options?.onClick])

  const isGranted = permission === "granted"

  const requestPermission = useCallback(async (): Promise<void> => {
    if (typeof window === "undefined" || !("Notification" in window)) return

    try {
      const result = await Notification.requestPermission()
      setPermission(result)
    } catch {
      // 某些浏览器可能抛出异常，静默处理
    }
  }, [])

  const showNotification = useCallback(
    (notification: Notification): void => {
      if (!enabled || !isGranted) return
      if (typeof window === "undefined" || !("Notification" in window)) return

      try {
        const desktopNotif = new Notification(notification.title, {
          body: notification.content ?? "",
          tag: notification.id, // 避免重复通知
          ...(notification.link ? { data: notification.link } : {}),
        })

        desktopNotif.onclick = () => {
          window.focus()
          onClickRef.current?.(notification)
          desktopNotif.close()
        }
      } catch {
        // 通知创建失败静默处理
      }
    },
    [enabled, isGranted]
  )

  // 当 enabled 变为 true 且权限为 default 时，自动请求权限
  // 使用异步队列避免在 effect 中同步调用 setState
  useEffect(() => {
    if (!enabled || permission !== "default") return
    if (typeof window === "undefined" || !("Notification" in window)) return

    let cancelled = false
    Notification.requestPermission().then((result) => {
      if (!cancelled) setPermission(result)
    }).catch(() => {
      // 某些浏览器可能抛出异常，静默处理
    })

    return () => {
      cancelled = true
    }
  }, [enabled, permission])

  return {
    permission,
    isGranted,
    requestPermission,
    showNotification,
  }
}
