importScripts("<%= javascript_url("turbo-offline-umd.min") %>")

// Documents - top-level navigation requests only
// We need `cache: "no-cache"` here to work around
// an annoying Safari PWA bug that predates offline mode
TurboOffline.addRule({
  match: (request) => request.destination === "document",
  except: /\/(edit|pin|watch|new)$/,
  handler: TurboOffline.handlers.networkFirst({
    cacheName: "main",
    maxAge: 60 * 60 * 24 * 3,
    networkTimeout: 3,
    fetchOptions: { cache: "no-cache" },
    maxEntrySize: 1024 * 1024
  })
})

TurboOffline.addRule({
  match: /\/assets\/.+[-\.][0-9a-f]+\.(js|css|svg|png|jpg|webp|woff2?|ico)$/,
  handler: TurboOffline.handlers.cacheFirst({
    cacheName: "assets",
    maxAge: 60 * 60 * 24 * 7,
    maxEntrySize: 1024 * 1024
  })
})

TurboOffline.addRule({
  match: /\/(boards|cards|users)\//,
  except: /\/(edit|pin|watch|new)$/,
  handler: TurboOffline.handlers.networkFirst({
    cacheName: "main",
    maxAge: 60 * 60 * 24 * 3,
    networkTimeout: 2,
    maxEntrySize: 1024 * 1024
  })
})

TurboOffline.addRule({
  match: /\/rails\/active_storage\//,
  handler: TurboOffline.handlers.networkFirst({
    cacheName: "storage",
    maxAge: 60 * 60 * 24 * 7,
    networkTimeout: 2,
    maxEntrySize: 2 * 1024 * 1024, // 2MB covers about 95% of all Fizzy blobs
    maxEntries: 500,
    fetchOptions: { mode: "cors" }
  })
})

// Everything else
TurboOffline.addRule({
  except: /\/(service-worker\.js|edit|pin|watch|new)$/,
  handler: TurboOffline.handlers.networkFirst({
    cacheName: "main",
    maxAge: 60 * 60 * 24,
    networkTimeout: 3,
    maxEntrySize: 1024 * 1024
  })
})

self.addEventListener("activate", (event) => {
  event.waitUntil(self.clients.claim())
})

TurboOffline.start()


self.addEventListener("push", (event) => {
  const data = event.data.json()
  event.waitUntil(Promise.all([ showNotification(data), updateBadgeCount(data.options) ]))
})

async function showNotification({ title, options }) {
  return self.registration.showNotification(title, options)
}

async function updateBadgeCount({ data: { badge } }) {
  return self.navigator.setAppBadge?.(badge || 0)
}

self.addEventListener("notificationclick", (event) => {
  event.notification.close()

  const url = new URL(event.notification.data.url, self.location.origin).href
  event.waitUntil(openURL(url))
})

async function openURL(url) {
  const clients = await self.clients.matchAll({ type: "window" })
  const focused = clients.find((client) => client.focused)

  if (focused) {
    await focused.navigate(url)
  } else {
    await self.clients.openWindow(url)
  }
}
