// Dabil Web Push client helpers.
window.DabilPush = {
  supported() {
    return 'serviceWorker' in navigator && 'PushManager' in window && 'Notification' in window;
  },
  urlB64ToUint8(base64) {
    const pad = '='.repeat((4 - base64.length % 4) % 4);
    const b64 = (base64 + pad).replace(/-/g, '+').replace(/_/g, '/');
    const raw = atob(b64), arr = new Uint8Array(raw.length);
    for (let i = 0; i < raw.length; i++) arr[i] = raw.charCodeAt(i);
    return arr;
  },
  async registerSW() {
    return navigator.serviceWorker.register('sw.js');
  },
  async isSubscribed() {
    if (!this.supported()) return false;
    const reg = await navigator.serviceWorker.getRegistration();
    if (!reg) return false;
    const sub = await reg.pushManager.getSubscription();
    return !!sub;
  },
  async subscribe(vapidPublic) {
    if (!this.supported()) throw new Error('Push notifications aren\'t supported in this browser.');
    const perm = await Notification.requestPermission();
    if (perm !== 'granted') throw new Error('Notifications permission was declined.');
    const reg = await this.registerSW();
    await navigator.serviceWorker.ready;
    let sub = await reg.pushManager.getSubscription();
    if (!sub) {
      sub = await reg.pushManager.subscribe({
        userVisibleOnly: true,
        applicationServerKey: this.urlB64ToUint8(vapidPublic)
      });
    }
    const resp = await fetch('push_subscribe.php', {
      method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(sub)
    });
    const text = await resp.text();
    let res;
    try { res = JSON.parse(text); }
    catch (e) {
      if (resp.status === 401) throw new Error('Please sign in again to enable push.');
      throw new Error('Server didn\'t return the expected response (HTTP ' + resp.status + '). Make sure the push files are uploaded.');
    }
    if (!res.ok) {
      if (res.error === 'auth') throw new Error('Please sign in again to enable push.');
      throw new Error('Could not register this device for push.');
    }
    return true;
  },
  async unsubscribe() {
    const reg = await navigator.serviceWorker.getRegistration();
    if (reg) {
      const sub = await reg.pushManager.getSubscription();
      if (sub) {
        await fetch('push_unsubscribe.php', {
          method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ endpoint: sub.endpoint })
        });
        await sub.unsubscribe();
      }
    }
    return true;
  }
};
