import { subscribeToPushAction, unsubscribeFromPushAction } from '@/actions/push'

export function isPushSupported(): boolean {
  return typeof window !== 'undefined' &&
    'serviceWorker' in navigator &&
    'PushManager' in window
}

export function isIOSSafari(): boolean {
  if (typeof window === 'undefined') return false
  const ua = navigator.userAgent
  return /iPhone|iPad/.test(ua) && !/CriOS|FxiOS/.test(ua)
}

export function isStandalonePWA(): boolean {
  if (typeof window === 'undefined') return false
  return (
    window.matchMedia('(display-mode: standalone)').matches ||
    !!(navigator as Navigator & { standalone?: boolean }).standalone
  )
}

export function urlBase64ToUint8Array(base64: string): Uint8Array<ArrayBuffer> {
  const padding = '='.repeat((4 - (base64.length % 4)) % 4)
  const base64Std = (base64 + padding).replace(/-/g, '+').replace(/_/g, '/')
  const rawData = atob(base64Std)
  const buf = new Uint8Array(rawData.length)
  for (let i = 0; i < rawData.length; i++) buf[i] = rawData.charCodeAt(i)
  return buf
}

export async function subscribeToPush(publicKey: string): Promise<PushSubscription> {
  const reg = await navigator.serviceWorker.register('/sw.js', { updateViaCache: 'none' })
  await navigator.serviceWorker.ready
  const sub = await reg.pushManager.subscribe({
    userVisibleOnly: true,
    applicationServerKey: urlBase64ToUint8Array(publicKey),
  })
  await subscribeToPushAction(sub.toJSON() as Parameters<typeof subscribeToPushAction>[0])
  return sub
}

export async function unsubscribeFromPush(): Promise<void> {
  const reg = await navigator.serviceWorker.getRegistration()
  const sub = await reg?.pushManager.getSubscription()
  if (sub) {
    await sub.unsubscribe()
    await unsubscribeFromPushAction({ endpoint: sub.endpoint })
  }
}
