import { getVapidKey, registerDevice } from "@/services/notification-compose"

/**
 * Convert a base64 URL-safe string to a Uint8Array for VAPID key usage.
 */
function urlBase64ToUint8Array(base64String: string): Uint8Array {
  const padding = "=".repeat((4 - (base64String.length % 4)) % 4)
  const base64 = (base64String + padding).replace(/-/g, "+").replace(/_/g, "/")
  const rawData = window.atob(base64)
  const outputArray = new Uint8Array(rawData.length)
  for (let i = 0; i < rawData.length; ++i) {
    outputArray[i] = rawData.charCodeAt(i)
  }
  return outputArray
}

/**
 * Subscribe the current browser to Web Push notifications.
 * Returns the PushSubscription on success, null on failure/denial.
 */
export async function subscribeToPush(): Promise<PushSubscription | null> {
  if (!("serviceWorker" in navigator) || !("PushManager" in window)) {
    console.warn("Push notifications not supported in this browser")
    return null
  }

  try {
    // Get VAPID public key from backend
    const { publicKey, configured } = await getVapidKey()
    if (configured !== "true" || !publicKey) {
      console.warn("Web Push not configured on server")
      return null
    }

    // Wait for service worker to be ready
    const registration = await navigator.serviceWorker.ready

    // Request permission
    const permission = await Notification.requestPermission()
    if (permission !== "granted") {
      console.info("Push notification permission denied")
      return null
    }

    // Subscribe to push
    const subscription = await registration.pushManager.subscribe({
      userVisibleOnly: true,
      applicationServerKey: urlBase64ToUint8Array(publicKey) as BufferSource,
    })

    // Send subscription to backend
    await registerDevice({
      platform: "WEB",
      token: JSON.stringify(subscription),
      deviceName: navigator.userAgent.includes("Mobile")
        ? "Mobile Browser"
        : "Desktop Browser",
    })

    return subscription
  } catch (error) {
    console.error("Failed to subscribe to push notifications:", error)
    return null
  }
}

/**
 * Check if the user has already granted push permission.
 */
export function isPushPermissionGranted(): boolean {
  return "Notification" in window && Notification.permission === "granted"
}

/**
 * Check if push notifications are supported in this browser.
 */
export function isPushSupported(): boolean {
  return "serviceWorker" in navigator && "PushManager" in window
}

/**
 * Get the current push subscription (if any).
 */
export async function getCurrentSubscription(): Promise<PushSubscription | null> {
  if (!("serviceWorker" in navigator)) return null
  const registration = await navigator.serviceWorker.ready
  return registration.pushManager.getSubscription()
}

/**
 * Unsubscribe from push notifications.
 */
export async function unsubscribeFromPush(): Promise<boolean> {
  const subscription = await getCurrentSubscription()
  if (subscription) {
    return subscription.unsubscribe()
  }
  return false
}
