(function () {
  function disableLightningStylesheets() {
    [
      'link.auraCss' /* The main lightning stylesheet (app.css) as it interferes with the custom styles from global.css */,
      '#siteforce_fontStyleSheet' /* The embedded fonts (fonts.css) stylesheet that carries additional page weight */,
    ].forEach(function (selector) {
      var stylesheet = document.querySelector(selector);
      if (stylesheet) {
        // CASE-643: Disable the stylesheet rather than removing it
        // as SF/the Aura framework may have be listening for the onload event:
        stylesheet.type = 'disabled';
        stylesheet.rel = 'disabled';
      }
    });
  }

  function loadCustomStylesheets() {
    var stylesheetUrls = [
      '/s/sfsites/c/resource/1674036518000/ZooStaticAssets/css/global.css',
      '/s/sfsites/c/resource/1674036518000/ZooStaticAssets/css/swiper.css',
      '/s/sfsites/c/resource/1674036518000/ZooStaticAssets/css/bootstrap-datepicker3.css',
      '/s/sfsites/c/resource/1674036518000/ZooStaticAssets/css/bootstrap-grid.css',
      '/s/sfsites/c/resource/1605543294000/communitySetupStyles',
    ];

    for (var i = 0; i < stylesheetUrls.length; i++) {
      var link = document.createElement('link');

      link.type = 'text/css';
      link.rel = 'stylesheet';
      link.href = stylesheetUrls[i];

      document.head.appendChild(link);
    }
  }

  function pushDataLayerEvent(event) {
    console.info('Received dataLayer event', event);
    if (!window.dataLayer) return;

    window.dataLayer.push(event);
  }

  function loadGoogleTagManager() {
    var gtmId = 'GTM-W4W5DQ2';
    console.log('GTM ID: ', gtmId);
    if (!gtmId) {
      // No GTM container is available on this environment
      return;
    }

    // Preserve initial location for SPA-like navigation
    window.dataLayer = window.dataLayer || [];
    var location = document.location;
    window.dataLayer.push({
      originalLocation:
        location.protocol + '//' + location.hostname + location.pathname + location.search,
    });

    // Load GTM script
    (function (w, d, s, l, i) {
      w[l] = w[l] || [];
      w[l].push({ 'gtm.start': new Date().getTime(), event: 'gtm.js' });
      var f = d.getElementsByTagName(s)[0],
        j = d.createElement(s),
        dl = l != 'dataLayer' ? '&l=' + l : '';
      j.async = true;
      j.src = 'https://www.googletagmanager.com/gtm.js?id=' + i + dl;
      f.parentNode.insertBefore(j, f);
    })(window, document, 'script', 'dataLayer', gtmId);
  }

  /**
   * Extract tracking info object from a DOM element with the `data-tracking-info` attribute
   */
  function getTrackingInfo(element) {
    const trackingInfoJson = element.dataset.trackingInfo;
    if (!trackingInfoJson) {
      return {};
    }

    const trackingInfo = JSON.parse(trackingInfoJson);
    return trackingInfo;
  }

  const TrackingConfig = {
    CurrencyCode: 'DKK',
    EventTypes: {
      ProductImpression: 'productImpression',
      ProductClick: 'productClick',
      AddToCart: 'addToCart',
      RemoveFromCart: 'removeFromCart',
    },
  };

  function trackProductImpressions(products) {
    const dataLayerEvent = {
      event: TrackingConfig.EventTypes.ProductImpression,
      ecommerce: {
        currencyCode: TrackingConfig.CurrencyCode,
        impressions: products,
      },
    };

    pushDataLayerEvent(dataLayerEvent);
  }

  function trackProductInfoEvent(event) {
    const trackingInfo = getTrackingInfo(event.currentTarget);
    if (!trackingInfo.product) return;

    const dataLayerEvent = {
      event: TrackingConfig.EventTypes.ProductClick,
      ecommerce: {
        currencyCode: TrackingConfig.CurrencyCode,
        click: {
          products: [trackingInfo.product],
        },
      },
    };

    pushDataLayerEvent(dataLayerEvent);
  }

  function trackProductAddClickEvent(event) {
    const trackingInfo = getTrackingInfo(event.currentTarget);
    if (!trackingInfo.product) return;

    const dataLayerEvent = {
      event: TrackingConfig.EventTypes.AddToCart,
      ecommerce: {
        currencyCode: TrackingConfig.CurrencyCode,
        add: {
          products: [trackingInfo.product],
        },
      },
    };

    pushDataLayerEvent(dataLayerEvent);
  }

  function trackRemoveFromCart(products) {
    const dataLayerEvent = {
      event: TrackingConfig.EventTypes.RemoveFromCart,
      ecommerce: {
        currencyCode: TrackingConfig.CurrencyCode,
        remove: {
          products: products,
        },
      },
    };

    pushDataLayerEvent(dataLayerEvent);
  }

  function trackProductRemoveClickEvent(event) {
    const trackingInfo = getTrackingInfo(event.currentTarget);
    if (trackingInfo.product) {
      trackRemoveFromCart([trackingInfo.product]);
    }
  }

  function trackProductsRemoveClickEvent(event) {
    const trackingInfo = getTrackingInfo(event.currentTarget);
    if (Array.isArray(trackingInfo.products) && trackingInfo.products.length > 0) {
      trackRemoveFromCart(trackingInfo.products);
    }
  }

  function loadEventTracking() {
    // User must see the element for at least this long before tracking the impression event:
    // (Where "see" = the element is fully inside the viewport)
    const impressionDelayMs = 2000;
    const impressionTimeouts = [];
    setInterval(function trackImpressions() {
      const now = new Date();
      const products = [];
      for (let i = impressionTimeouts.length - 1; i >= 0; i--) {
        const impressionTimeout = impressionTimeouts[i];
        if (impressionTimeout.time > now) continue;

        clearTimeout(impressionTimeout.timeout);
        impressionTimeouts.splice(i, 1);

        const trackingInfo = getTrackingInfo(impressionTimeout.target);
        if (trackingInfo.product) {
          products.push(trackingInfo.product);
        }
      }
      if (products.length > 0) {
        trackProductImpressions(products);
      }
    }, impressionDelayMs);

    // Set up this observer to detect when an element enters and leaves the viewport:
    const intersectionObserver = new IntersectionObserver(
      function (intersectionEntries) {
        intersectionEntries.forEach(function (intersectionEntry) {
          if (intersectionEntry.isIntersecting) {
            // Element is fully visible. Start the timeout for impression tracking:
            const time = new Date();
            time.setMilliseconds(time.getMilliseconds() + impressionDelayMs);
            impressionTimeouts.push({
              target: intersectionEntry.target,
              time: time,
            });
          } else {
            // Element is no longer visible. Remove any impression tracking timeouts:
            for (let i = impressionTimeouts.length - 1; i >= 0; i--) {
              const impressionTimeout = impressionTimeouts[i];
              if (impressionTimeout.target === intersectionEntry.target) {
                impressionTimeouts.splice(i, 1);
              }
            }
          }
        });
      },
      {
        root: null,
        rootMargin: '0px',
        threshold: 1.0,
      }
    );

    // Delay the impression tracking timeout as the user cannot see the element clearly until he stops scrolling:
    document.addEventListener('scroll', function () {
      const time = new Date();
      time.setMilliseconds(time.getMilliseconds() + impressionDelayMs);
      impressionTimeouts.forEach(function (impressionTimeout) {
        impressionTimeout.time = time;
      });
    });

    // Expose callbacks on window object for LWC components like productCard or orderConfirmation:
    window.ZooLWCInterop = window.ZooLWCInterop || {};
    window.ZooLWCInterop.pushDataLayerEvent = pushDataLayerEvent;
    window.ZooLWCInterop.trackElement = function (element) {
      if (!element) return;

      const trackingInfo = getTrackingInfo(element);
      switch (trackingInfo.type) {
        case 'productImpression':
          intersectionObserver.observe(element);
          break;
        case 'productInfo':
          element.addEventListener('click', trackProductInfoEvent, { once: true });
          break;
        case 'productAdd':
          element.addEventListener('click', trackProductAddClickEvent, { once: false });
          break;
        case 'productRemove':
          element.addEventListener('click', trackProductRemoveClickEvent, { once: true });
          break;
        case 'productsRemove':
          element.addEventListener('click', trackProductsRemoveClickEvent, { once: true });
          break;
      }
    };
  }

  function init() {

    // This Cookiebot event is raised on accept and if accept was given in a previous session:
    // window.addEventListener('CookiebotOnAccept', loadGoogleTagManager, { once: true });
    loadGoogleTagManager();

    // Defer to account for loading order variations:
    //disableLightningStylesheets();    
    loadCustomStylesheets();   
    
    
    // Defer to account for script-based rendering:
    loadEventTracking();
  }

  if ('false' === 'true') {
    setTimeout(function debugTracking() {
      const evt = new Event('CookiebotOnAccept');
      window.dispatchEvent(evt);
    }, 250);
  }

  init();
})();
