---
/**
 * Google Tag Manager behind Consent Mode v2, with the Silktide consent manager. Production only. Deferred to the first
 * interaction, or to idle after load (8 s timeout keeps GTM outside the Lighthouse TBT window). Inline on purpose:
 * the consent default must be pushed before the gtm.js event in one synchronous step, which a deferred module cannot
 * guarantee. Defines `window.openCookiePreferences`, which the footer's cookie-preferences button calls.
 * The `<noscript>` iframe goes at the start of `<body>`: render with `part="noscript"` there and `part="script"` at
 * the end of `<body>`.
 */
import { GTM_ORIGIN, SILKTIDE_BASE } from './resources.ts';

export interface ConsentType {
  id: string;
  label: string;
  description: string;
  required?: boolean;
  defaultValue?: boolean;
  /** The Consent Mode v2 storage key(s) this category grants. */
  gtag?: string | string[];
}

interface Props {
  gtmId: string;
  part: 'noscript' | 'script';
  /** The banner's prompt text. */
  prompt?: string;
  consentTypes?: ConsentType[];
}

const { gtmId, part, prompt = '', consentTypes = [] } = Astro.props;
const isProd = import.meta.env.PROD;
// Absolute and built here: Googlebot crawls a relative '/gtm.js?id=' literal in the inline script as a page (SLA-3001).
const gtmSrc = `${GTM_ORIGIN}/gtm.js?id=${gtmId}`;
const silktideScript = `${SILKTIDE_BASE}/silktide-consent-manager.js`;
const silktideConfig = { text: { prompt: { description: prompt } }, consentTypes };
---

{isProd && part === 'noscript' && (
  <noscript set:html={`<iframe src="${GTM_ORIGIN}/ns.html?id=${gtmId}" height="0" width="0" style="display:none;visibility:hidden"></iframe>`} />
)}
{isProd && part === 'script' && (
  <script is:inline define:vars={{ gtmSrc, silktideScript, silktideConfig }}>
    (function () {
      let thirdPartyLoaded = false;

      function loadThirdPartyScripts() {
        if (thirdPartyLoaded) return;
        thirdPartyLoaded = true;

        window.dataLayer = window.dataLayer || [];

        // GTM treats a dataLayer entry as a consent command only when it is an `arguments` object; a plain array is
        // ignored, which leaves analytics_storage unset and blocks tags with an additional consent check.
        function gtag() { window.dataLayer.push(arguments); }
        gtag('consent', 'default', {
          ad_storage: 'denied',
          ad_user_data: 'denied',
          ad_personalization: 'denied',
          analytics_storage: 'granted',
        });

        window.dataLayer.push({
          'gtm.start': new Date().getTime(),
          event: 'gtm.js',
        });

        // On the main thread: Partytown race-dropped the initial page_view (SLA-2661).
        var gtmScript = document.createElement('script');
        gtmScript.async = true;
        gtmScript.src = gtmSrc;
        document.head.appendChild(gtmScript);

        var consentScript = document.createElement('script');
        consentScript.src = silktideScript;
        consentScript.async = true;
        consentScript.onload = function () {
          if (!window.silktideConsentManager) return;
          window.silktideConsentManager.init(silktideConfig);
        };
        document.head.appendChild(consentScript);
      }

      var evtOpts = { once: true, passive: true, capture: true };
      ['pointerdown', 'keydown', 'touchstart', 'scroll'].forEach(function (evt) {
        window.addEventListener(evt, loadThirdPartyScripts, evtOpts);
      });

      function scheduleThirdPartyScripts() {
        if ('requestIdleCallback' in window) {
          window.requestIdleCallback(loadThirdPartyScripts, { timeout: 8000 });
        } else {
          setTimeout(loadThirdPartyScripts, 6000);
        }
      }

      if (document.readyState === 'complete') {
        scheduleThirdPartyScripts();
      } else {
        window.addEventListener('load', scheduleThirdPartyScripts, { once: true });
      }

      // Silktide is lazy-loaded: if this click is the first interaction, load it and poll briefly (about 4 s).
      window.openCookiePreferences = function () {
        if (window.silktideConsentManager) {
          window.silktideConsentManager.getInstance().toggleModal(true);
          return;
        }
        loadThirdPartyScripts();
        var attempts = 0;
        var poll = setInterval(function () {
          attempts++;
          if (window.silktideConsentManager) {
            clearInterval(poll);
            window.silktideConsentManager.getInstance().toggleModal(true);
          } else if (attempts > 40) {
            clearInterval(poll);
          }
        }, 100);
      };
    })();
  </script>
)}
