const base64UrlToUint8Array = (value) => {
  const padding = "=".repeat((4 - value.length % 4) % 4)
  const base64 = `${value}${padding}`.replace(/-/g, "+").replace(/_/g, "/")
  const rawData = window.atob(base64)
  const output = new Uint8Array(rawData.length)

  for (let i = 0; i < rawData.length; i += 1) {
    output[i] = rawData.charCodeAt(i)
  }

  return output
}

export const useDesktopPush = () => {
  const { $api } = useNuxtApp()

  const supported = computed(() =>
    process.client &&
    "serviceWorker" in navigator &&
    "PushManager" in window &&
    "Notification" in window
  )
  const permission = ref(process.client && "Notification" in window ? Notification.permission : "default")
  const configured = ref(false)
  const loading = ref(false)
  const error = ref("")

  const loadConfig = async () => {
    if (!supported.value) return { configured: false, publicKey: "" }

    const config = await $api("/api/notifications/push/config")
    configured.value = Boolean(config.configured && config.publicKey)
    return config
  }

  const subscribe = async () => {
    error.value = ""
    loading.value = true

    try {
      const config = await loadConfig()
      if (!configured.value) {
        throw new Error("Desktop Push ist im Backend noch nicht konfiguriert.")
      }

      const nextPermission = await Notification.requestPermission()
      permission.value = nextPermission
      if (nextPermission !== "granted") {
        throw new Error("Benachrichtigungen wurden im Browser nicht erlaubt.")
      }

      const registration = await navigator.serviceWorker.register("/fedeo-push-sw.js")
      const existingSubscription = await registration.pushManager.getSubscription()
      const subscription = existingSubscription || await registration.pushManager.subscribe({
        userVisibleOnly: true,
        applicationServerKey: base64UrlToUint8Array(config.publicKey),
      })

      await $api("/api/notifications/push/subscribe", {
        method: "POST",
        body: subscription.toJSON(),
      })

      return true
    } catch (err) {
      error.value = err?.data?.error || err?.message || "Desktop Push konnte nicht aktiviert werden."
      return false
    } finally {
      loading.value = false
    }
  }

  const sendTestPush = async () => {
    return await $api("/api/notifications/test-push", {
      method: "POST",
    })
  }

  return {
    supported,
    permission,
    configured,
    loading,
    error,
    loadConfig,
    subscribe,
    sendTestPush,
  }
}
