(function () {
  'use strict';

  const config = window.foodordPwaConfig || {};
  if (!('serviceWorker' in navigator) || !config.serviceWorkerUrl || !config.scope) {
    return;
  }

  const isStandalone = () =>
    window.matchMedia('(display-mode: standalone)').matches || window.navigator.standalone === true;

  const isIos = () =>
    /iphone|ipad|ipod/i.test(window.navigator.userAgent) ||
    (/macintosh/i.test(window.navigator.userAgent) && window.navigator.maxTouchPoints > 1);
  const isMacSafari = () =>
    !isIos() &&
    /macintosh/i.test(window.navigator.userAgent) &&
    /safari/i.test(window.navigator.userAgent) &&
    !/(?:chrome|chromium|crios|edg|opr)/i.test(window.navigator.userAgent);
  const storageKey = `foodord-pwa-dismissed-${config.appId || 'site'}`;
  const launchHeartbeatKey = `foodord-pwa-launch-heartbeat-${config.appId || 'site'}`;

  const storage = {
    get() {
      try {
        return Number(window.localStorage.getItem(storageKey) || 0);
      } catch {
        return 0;
      }
    },
    set(value) {
      try {
        window.localStorage.setItem(storageKey, String(value));
      } catch {
        return;
      }
    }
  };

  const clearFoodordCaches = () => {
    if (!('caches' in window)) {
      return Promise.resolve();
    }

    return window.caches.keys().then((keys) =>
      Promise.all(keys.filter((key) => key.startsWith('foodord-pwa-')).map((key) => window.caches.delete(key)))
    );
  };

  const unregister = async () => {
    const registrations = await navigator.serviceWorker.getRegistrations();
    await Promise.all(
      registrations
        .filter((registration) => {
          const worker = registration.active || registration.waiting || registration.installing;
          return worker?.scriptURL.includes('foodord_pwa_service_worker');
        })
        .map((registration) => {
          const worker = registration.active || registration.waiting || registration.installing;
          worker?.postMessage({ type: 'FOODORD_PWA_CLEAR' });
          return registration.unregister();
        })
    );
    await clearFoodordCaches();
  };

  if (!config.enabled) {
    unregister().catch(() => undefined);
    return;
  }

  if (!window.isSecureContext) {
    return;
  }

  const navigationProgress = {
    element: null,
    resetTimer: null,
    ensure() {
      if (this.element?.isConnected) {
        return this.element;
      }

      const element = document.createElement('div');
      element.className = 'foodord-pwa-navigation-progress';
      element.setAttribute('aria-hidden', 'true');
      document.body.appendChild(element);
      this.element = element;

      return element;
    },
    start() {
      if (!isStandalone()) {
        return;
      }

      const element = this.ensure();
      window.clearTimeout(this.resetTimer);
      element.classList.add('is-active');
      this.resetTimer = window.setTimeout(() => this.reset(), 12000);
    },
    reset() {
      window.clearTimeout(this.resetTimer);
      this.resetTimer = null;
      this.element?.classList.remove('is-active');
    }
  };

  const isInternalNavigationLink = (link) => {
    if (
      !link ||
      link.hasAttribute('download') ||
      link.hasAttribute('data-foodord-pwa-no-progress') ||
      (link.target && link.target.toLowerCase() !== '_self')
    ) {
      return false;
    }

    let destination;
    try {
      destination = new URL(link.href, window.location.href);
    } catch {
      return false;
    }

    if (!['http:', 'https:'].includes(destination.protocol) || destination.origin !== window.location.origin) {
      return false;
    }

    const current = new URL(window.location.href);
    return !(
      destination.pathname === current.pathname &&
      destination.search === current.search &&
      destination.hash
    );
  };

  const runLaunchHeartbeat = () => {
    if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) {
      return;
    }

    try {
      if (window.sessionStorage.getItem(launchHeartbeatKey)) {
        return;
      }
      window.sessionStorage.setItem(launchHeartbeatKey, '1');
    } catch {
      return;
    }

    const logo = document.querySelector(
      '.foodord-banner-logo .foodord-logo-image, .site-branding .custom-logo, .site-branding .site-logo-image, img.custom-logo'
    );
    if (!logo) {
      return;
    }

    logo.classList.add('foodord-pwa-launch-heartbeat');
    logo.addEventListener(
      'animationend',
      () => logo.classList.remove('foodord-pwa-launch-heartbeat'),
      { once: true }
    );
  };

  if (isStandalone()) {
    document.documentElement.classList.add('foodord-pwa-standalone');
    navigationProgress.ensure();
    window.requestAnimationFrame(runLaunchHeartbeat);

    document.addEventListener('click', (event) => {
      if (
        event.button !== 0 ||
        event.metaKey ||
        event.ctrlKey ||
        event.shiftKey ||
        event.altKey ||
        !(event.target instanceof Element)
      ) {
        return;
      }

      const link = event.target.closest('a[href]');
      if (!isInternalNavigationLink(link)) {
        return;
      }

      window.setTimeout(() => {
        if (!event.defaultPrevented) {
          navigationProgress.start();
        }
      }, 0);
    });

    document.addEventListener('submit', (event) => {
      window.setTimeout(() => {
        if (!event.defaultPrevented) {
          navigationProgress.start();
        }
      }, 0);
    });

    window.addEventListener('pageshow', () => navigationProgress.reset());
  }

  let deferredPrompt = null;
  let revealTimer = null;
  const prompt = document.querySelector('[data-foodord-pwa-install]');
  const installButton = prompt?.querySelector('[data-foodord-pwa-install-button]');
  const dismissButton = prompt?.querySelector('[data-foodord-pwa-dismiss]');
  const instructions = prompt?.querySelector('[data-foodord-pwa-instructions]');

  const hidePrompt = (remember) => {
    window.clearTimeout(revealTimer);
    if (prompt) {
      prompt.classList.remove('is-visible');
      window.setTimeout(() => {
        prompt.hidden = true;
      }, 240);
    }
    if (remember) {
      storage.set(Date.now());
    }
  };

  const wasRecentlyDismissed = () => {
    const dismissedAt = storage.get();
    const days = Number(config.dismissDays || 14);
    return dismissedAt > 0 && Date.now() - dismissedAt < days * 86400000;
  };

  const revealPrompt = () => {
    if (!prompt || !config.showPrompt || isStandalone() || wasRecentlyDismissed()) {
      return;
    }


    if ((isIos() || isMacSafari()) && instructions && installButton) {
      instructions.textContent = String(isIos() ? config.iosInstructions || '' : config.macInstructions || '');
      instructions.hidden = false;
      installButton.hidden = true;
    }

    prompt.hidden = false;
    revealTimer = window.setTimeout(() => prompt.classList.add('is-visible'), 50);
  };

  window.addEventListener('beforeinstallprompt', (event) => {
    event.preventDefault();
    deferredPrompt = event;
    revealPrompt();
  });

  window.addEventListener('appinstalled', () => {
    deferredPrompt = null;
    hidePrompt(false);
  });

  installButton?.addEventListener('click', async () => {
    if (deferredPrompt) {
      try {
        await deferredPrompt.prompt();
        const choice = await deferredPrompt.userChoice;
        deferredPrompt = null;
        hidePrompt(choice.outcome !== 'accepted');
      } catch {
        deferredPrompt = null;
        hidePrompt(false);
      }
      return;
    }
  });

  dismissButton?.addEventListener('click', () => hidePrompt(true));

  navigator.serviceWorker
    .register(config.serviceWorkerUrl, {
      scope: config.scope,
      updateViaCache: 'none'
    })
    .catch(() => undefined);

  if ((isIos() || isMacSafari()) && !isStandalone()) {
    revealPrompt();
  }
})();
