(function () {
    const GTM_ID = 'GTM-M3JC64F';
    const GTM_SERVER_URL = 'https://happytagging.taggrs.io';
    const PROXY_BASE_URL = new URL(document.currentScript.src).origin;
    const PROXY_PATH_PREFIX = '/load';
    const KEY_API_ENDPOINT = `${PROXY_BASE_URL}/api/get-key`;
    let encryptionKey = null;

    // Get parameters from page URL
    const pageQuery = (window.location && typeof window.location.search === 'string')
        ? window.location.search.slice(1)
        : '';
    const pageParams = new URLSearchParams(pageQuery);

    // Disable adblocker shield when Oxygen builder is active
    const isOxygenBuilder = pageParams.get('ct_builder') === 'true' && pageParams.get('ct_inner') === 'true';
    if (isOxygenBuilder) {
        console.log('[GTM Proxy] Oxygen builder detected - adblocker shield disabled');
        return; // Exit early, no monkey patching
    }

    const DEBUG = pageParams.get('measurelake_debug') === 'true';
    let mlAbComputed = null; // null until detected; boolean afterwards
    let mlSstbComputed = null; // null until detected; boolean afterwards for SST bait
    let mlAbLogged = false; // ensure we log detected ml_ab only once

    // Debug logger
    const debugLog = {
        log: (...args) => DEBUG && console.log('[GTM Proxy]', ...args),
        error: (...args) => DEBUG && console.error('[GTM Proxy Error]', ...args),
        warn: (...args) => DEBUG && console.warn('[GTM Proxy Warning]', ...args),
        info: (...args) => DEBUG && console.info('[GTM Proxy Info]', ...args)
    };

    if (DEBUG) {
        debugLog.info('Debug mode enabled (measurelake_debug=true)');
    }

    async function fetchEncryptionKey() {
        try {
            const response = await fetch(KEY_API_ENDPOINT);
            if (!response.ok) throw new Error(`Failed to fetch key: ${response.status}`);
            const data = await response.json();
            sessionStorage.setItem('gtmfpm_encryptionKey', data.key);
            sessionStorage.setItem('gtmfpm_keyExpiry', data.expiry);
            debugLog.info('Encryption key loaded');
            return data.key;
        } catch (error) {
            debugLog.error('Error fetching key:', error);
            return null;
        }
    }

    async function getEncryptionKey() {
        try {
            const cachedKey = sessionStorage.getItem('gtmfpm_encryptionKey');
            const expiry = sessionStorage.getItem('gtmfpm_keyExpiry');
            if (cachedKey && expiry && new Date(expiry) > new Date()) return cachedKey;
            return await fetchEncryptionKey();
        } catch (error) {
            debugLog.error('Error getting encryption key:', error);
            return null;
        }
    }

    async function encryptUrl(dataString) {
        if (!encryptionKey) {
            encryptionKey = await getEncryptionKey();
            if (!encryptionKey) throw new Error("Encryption key not available.");
        }
        
        const encoder = new TextEncoder();
        const data = encoder.encode(dataString);
        const keyBytes = encoder.encode(encryptionKey);
        
        const cryptoKey = await crypto.subtle.importKey('raw', keyBytes, { name: 'AES-GCM' }, false, ['encrypt']);
        const iv = crypto.getRandomValues(new Uint8Array(12));
        const encrypted = await crypto.subtle.encrypt({ name: 'AES-GCM', iv: iv }, cryptoKey, data);
        const ivHex = Array.from(iv).map(b => b.toString(16).padStart(2, '0')).join('');
        const encryptedHex = Array.from(new Uint8Array(encrypted)).map(b => b.toString(16).padStart(2, '0')).join('');
        return `${ivHex}:${encryptedHex}`;
    }

    async function encryptPayload(payloadString) {
        if (!encryptionKey) {
            encryptionKey = await getEncryptionKey();
            if (!encryptionKey) throw new Error("Encryption key not available.");
        }
        
        const encoder = new TextEncoder();
        const data = encoder.encode(payloadString);
        const keyBytes = encoder.encode(encryptionKey);
        const cryptoKey = await crypto.subtle.importKey('raw', keyBytes, { name: 'AES-GCM' }, false, ['encrypt']);
        const iv = crypto.getRandomValues(new Uint8Array(12));
        const encrypted = await crypto.subtle.encrypt({ name: 'AES-GCM', iv: iv }, cryptoKey, data);
        const ivHex = Array.from(iv).map(b => b.toString(16).padStart(2, '0')).join('');
        const encryptedHex = Array.from(new Uint8Array(encrypted)).map(b => b.toString(16).padStart(2, '0')).join('');
        return `${ivHex}:${encryptedHex}`;
    }

    async function detectAdblockOnce() {
        if (mlAbComputed !== null && mlSstbComputed !== null) {
            return { ml_ab: mlAbComputed, ml_sstb: mlSstbComputed };
        }
        
        try {
            // Multi-method adblock detection optimized for uBlock Origin
            let adblockDetected = false;
            let sstBlocked = false;
            
            // Method 1: DOM bait element (most reliable)
            try {
                const baitElement = document.createElement('div');
                baitElement.innerHTML = '&nbsp;';
                baitElement.className = 'adsbox ads ad-banner doubleclick ad-placeholder adbadge BannerAd';
                baitElement.style.cssText = 'position:absolute!important;left:-10000px!important;width:1px!important;height:1px!important;';
                document.body.appendChild(baitElement);
                
                // Wait a bit for adblocker to process
                await new Promise(resolve => setTimeout(resolve, 100));
                
                const isBlocked = baitElement.offsetParent === null || 
                                baitElement.offsetHeight === 0 || 
                                baitElement.offsetWidth === 0 || 
                                window.getComputedStyle(baitElement, null).getPropertyValue('display') === 'none' ||
                                window.getComputedStyle(baitElement, null).getPropertyValue('visibility') === 'hidden';
                
                if (isBlocked) {
                    debugLog.info('Adblock detection - DOM bait element was blocked');
                    adblockDetected = true;
                }
                
                document.body.removeChild(baitElement);
            } catch (e) {
                debugLog.warn('Adblock detection - DOM test failed:', e);
            }
            
            // Method 2: Network bait with timeout detection (Google Ads)
            if (!adblockDetected) {
                try {
                    const controller = new AbortController();
                    const timeoutId = setTimeout(() => controller.abort(), 800);
                    
                    const startTime = performance.now();
                    await fetch('https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js', { 
                        mode: 'no-cors', 
                        cache: 'no-store',
                        signal: controller.signal
                    });
                    const endTime = performance.now();
                    
                    clearTimeout(timeoutId);
                    
                    // If request completed too quickly, it might be blocked/redirected
                    if (endTime - startTime < 50) {
                        debugLog.info('Adblock detection - Network request completed suspiciously fast (likely blocked/redirected)');
                        adblockDetected = true;
                    }
                } catch (e) {
                    debugLog.info('Adblock detection - Network request failed:', e.name);
                    adblockDetected = true;
                }
            }
            
            // Method 2b: SST bait detection - test if server-side tracking would be blocked
            try {
                const sstController = new AbortController();
                const sstTimeoutId = setTimeout(() => sstController.abort(), 800);
                
                const sstStartTime = performance.now();
                await fetch('https://happytagging.taggrs.io/g/collect?v=2&tid=G-0000000000&gtm=45je59n2v897599456z8897586164za200zb897586164zd897586164&_p=1758882187026&gcs=G111&gcd=13r3rPr2r5l1&npa=0&dma_cps=syphamo&dma=1&gdid=dMWZhNz&cid=1686981748.1756456372&ecid=1299729156&ul=en-us&sr=1920x1080&ur=DE-BW&uaa=arm&uab=64&uafvl=Chromium%3B140.0.7339.186%7CNot%253DA%253FBrand%3B24.0.0.0%7CGoogle%2520Chrome%3B140.0.7339.186&uamb=0&uam=&uap=macOS&uapv=14.8.0&uaw=0&are=1&frm=0&pscdl=&ec_mode=c&_eu=AAAAAAQ&sst.rnd=855067871.1758882188&sst.etld=google.de&sst.gcsub=region1&sst.us_privacy=1---&sst.tft=1758882187026&sst.lpc=99583387&sst.navt=r&sst.ude=0&sst.sw_exp=1&_s=1&tag_exp=101509157~103116026~103200004~103233427~104527907~104528501~104684208~104684211~104948813~115480710~115616985~115691064&sid=1758869199&sct=10&seg=1&dl=https%3A%2F%2Ftaggrs.io%2Fprices%2F&dr=https%3A%2F%2Ftaggrs.io%2F&dt=Server%20Side%20Tracking%20Pricing%20%26%20Subscriptions%20-%20TAGGRS&_tu=DA&en=page_view&ep.event_id=1758882652419_17588830665472&ep.cookie_consent_ad_storage=granted&ep.analytics_storage=granted&ep.functionality_storage=granted&ep.personalization_storage=granted&ep.security_storage=granted&ep.ad_user_data=granted&ep.ad_personalization=granted&ep.x-fb-ck-fbp=fb.1.1756456372500.1154958244&ep.user_data.address.0.country=NL&ep.user_data._tag_mode=MANUAL&tfd=978&richsstsse&ml_bait=true', { 
                    mode: 'no-cors', 
                    cache: 'no-store',
                    signal: sstController.signal
                });
                const sstEndTime = performance.now();
                
                clearTimeout(sstTimeoutId);
                
                // If request completed too quickly, it might be blocked/redirected
                if (sstEndTime - sstStartTime < 50) {
                    debugLog.info('SST Adblock detection - SST network request completed suspiciously fast (likely blocked/redirected)');
                    sstBlocked = true;
                }
            } catch (e) {
                debugLog.info('SST Adblock detection - SST network request failed:', e.name);
                sstBlocked = true;
            }
            
            // Method 3: Script injection test
            if (!adblockDetected) {
                try {
                    const script = document.createElement('script');
                    script.type = 'text/javascript';
                    script.style.display = 'none';
                    script.src = 'data:text/javascript;base64,dmFyIGFkc2J5Z29vZ2xlID0gW107'; // "var adsbygoogle = [];"
                    document.head.appendChild(script);
                    
                    await new Promise(resolve => setTimeout(resolve, 100));
                    
                    if (typeof window.adsbygoogle === 'undefined') {
                        debugLog.info('Adblock detection - Script injection was blocked');
                        adblockDetected = true;
                    }
                    
                    document.head.removeChild(script);
                } catch (e) {
                    debugLog.warn('Adblock detection - Script test failed:', e);
                }
            }
            
            debugLog.info('Adblock detection - Final result:', adblockDetected);
            debugLog.info('SST Adblock detection - Final result:', sstBlocked);
            mlAbComputed = adblockDetected;
            mlSstbComputed = sstBlocked;
            debugLog.info('Adblock detection - decision:', mlAbComputed ? 'blocked (ml_ab=1)' : 'not blocked (ml_ab=0)');
            debugLog.info('SST Adblock detection - decision:', mlSstbComputed ? 'blocked (ml_sstb=1)' : 'not blocked (ml_sstb=0)');
            return { ml_ab: mlAbComputed, ml_sstb: mlSstbComputed };
        } catch (e) {
            debugLog.warn('Adblock detection failed, defaulting to blocked for safety:', e);
            mlAbComputed = true; // Default to blocked for safety
            mlSstbComputed = true; // Default to blocked for safety
            return { ml_ab: true, ml_sstb: true };
        }
    }

    async function modifyUrl(url) {
        if (typeof url !== 'string' || !url.includes(GTM_SERVER_URL)) {
            return url;
        }

        const relativePath = url.substring(GTM_SERVER_URL.length);
        // Auto-detect adblock status
        const adblockResult = await detectAdblockOnce();
        const mlAbParam = adblockResult.ml_ab ? '1' : '0';
        const mlSstbParam = adblockResult.ml_sstb ? '1' : '0';

        if (!mlAbLogged) {
            debugLog.info(`Auto-detected ml_ab: ${mlAbParam}, ml_sstb: ${mlSstbParam}`);
            mlAbLogged = true;
        }

        let relativeWithParams = relativePath;
        relativeWithParams += (relativeWithParams.includes('?') ? '&' : '?') + 
            `ml_ab=${encodeURIComponent(mlAbParam)}&ml_sstb=${encodeURIComponent(mlSstbParam)}`;

        const encryptedFragment = await encryptUrl(relativeWithParams);
        return `${PROXY_BASE_URL}${PROXY_PATH_PREFIX}/${encodeURIComponent(encryptedFragment)}`;
    }

    // NOW set up all interception AFTER functions are defined
    debugLog.log('GTM Proxy: Setting up immediate interception for:', GTM_SERVER_URL);

    // Override document.createElement FIRST
    const originalCreateElement = document.createElement;
    document.createElement = function (tagName, options) {
        const element = originalCreateElement.call(this, tagName, options);

        if (tagName.toLowerCase() === 'script') {
            const originalSetAttribute = element.setAttribute.bind(element);
            element.setAttribute = function (name, value) {
                if (name.toLowerCase() === 'src' && typeof value === 'string' && value.includes(GTM_SERVER_URL)) {
                    debugLog.log('GTM Proxy: Intercepting createElement setAttribute src:', value);
                    // Use a promise-based approach but don't block
                    modifyUrl(value).then(modifiedUrl => {
                        originalSetAttribute(name, modifiedUrl);
                    }).catch(error => {
                        debugLog.error('GTM Proxy: createElement setAttribute error:', error);
                        originalSetAttribute(name, value);
                    });
                    return; // Don't call original
                } else {
                    originalSetAttribute(name, value);
                }
            };
        }

        if (tagName.toLowerCase() === 'iframe') {
            const originalSetAttribute = element.setAttribute.bind(element);
            element.setAttribute = function (name, value) {
                if (name.toLowerCase() === 'src' && typeof value === 'string' && value.includes(GTM_SERVER_URL)) {
                    debugLog.log('GTM Proxy: Intercepting iframe src:', value);
                    modifyUrl(value).then(modifiedUrl => {
                        originalSetAttribute(name, modifiedUrl);
                    }).catch(error => {
                        debugLog.error('GTM Proxy: Error modifying iframe URL:', error);
                        originalSetAttribute(name, value);
                    });
                    return;
                } else {
                    originalSetAttribute(name, value);
                }
            };
        }

        return element;
    };

    // Override appendChild IMMEDIATELY
    const originalAppendChild = Node.prototype.appendChild;
    Node.prototype.appendChild = function(child) {
        if (child.tagName === 'SCRIPT' && child.src && child.src.includes(GTM_SERVER_URL)) {
            debugLog.log('GTM Proxy: Intercepting appendChild script:', child.src);
            const originalSrc = child.src;
            child.src = ''; // Clear to prevent load
            modifyUrl(originalSrc).then(modifiedUrl => {
                child.src = modifiedUrl;
                originalAppendChild.call(this, child);
            }).catch(error => {
                debugLog.error('GTM Proxy: appendChild error:', error);
                child.src = originalSrc;
                originalAppendChild.call(this, child);
            });
            return child;
        }
        return originalAppendChild.call(this, child);
    };

    // Override insertBefore IMMEDIATELY  
    const originalInsertBefore = Node.prototype.insertBefore;
    Node.prototype.insertBefore = function(newNode, referenceNode) {
        if (newNode.tagName === 'SCRIPT' && newNode.src && newNode.src.includes(GTM_SERVER_URL)) {
            debugLog.log('GTM Proxy: Intercepting insertBefore script:', newNode.src);
            const originalSrc = newNode.src;
            newNode.src = '';
            modifyUrl(originalSrc).then(modifiedUrl => {
                newNode.src = modifiedUrl;
                originalInsertBefore.call(this, newNode, referenceNode);
            }).catch(error => {
                debugLog.error('GTM Proxy: insertBefore error:', error);
                newNode.src = originalSrc;
                originalInsertBefore.call(this, newNode, referenceNode);
            });
            return newNode;
        }
        return originalInsertBefore.call(this, newNode, referenceNode);
    };

    // Override fetch IMMEDIATELY
    const originalFetch = window.fetch;
    window.fetch = async function (resource, init = {}) {
        let finalResource = resource;
        let finalInit = { ...init };

        // Skip interception for bait URLs to prevent infinite loops
        if (typeof resource === 'string' && 
            (resource.includes('pagead2.googlesyndication.com') || 
             resource.includes('ml_bait=true'))) {
            debugLog.log('GTM Proxy: Skipping bait URL:', resource);
            return originalFetch.call(this, resource, init);
        }

        if (typeof resource === 'string' && resource.includes(GTM_SERVER_URL)) {
            debugLog.log('GTM Proxy: Intercepting fetch:', resource);
            finalResource = await modifyUrl(resource);
            debugLog.log('GTM Proxy: Fetch URL modified to:', finalResource);

            // Ensure cookies / auth headers are always included
            if (finalInit.credentials === undefined) {
                finalInit.credentials = 'include';
            }

            // Encrypt body for write-methods to preserve parity with server logic
            const method = (finalInit.method || 'GET').toUpperCase();
            if (finalInit.body && ['POST', 'PUT', 'PATCH'].includes(method)) {
                 if (typeof finalInit.body === 'string') {
                    debugLog.log('GTM Proxy: Encrypting fetch payload.');
                    finalInit.body = await encryptPayload(finalInit.body);
                 } else {
                    debugLog.warn('GTM Proxy: Fetch body is not a string, cannot encrypt.');
                 }
            }
        }
        return originalFetch.call(this, finalResource, finalInit);
    };

    // Override XMLHttpRequest IMMEDIATELY
    const originalXHROpen = XMLHttpRequest.prototype.open;
    XMLHttpRequest.prototype.open = function(method, url, ...args) {
        // Remember method so we know later if body should be encrypted
        this._ml_method = method ? String(method).toUpperCase() : 'GET';
        // Track whether this XHR should be intercepted/encrypted (only for GTM server URL)
        this._ml_intercept = false;

        // Skip interception for bait URLs to prevent infinite loops
        if (typeof url === 'string' && 
            (url.includes('pagead2.googlesyndication.com') || 
             url.includes('ml_bait=true'))) {
            debugLog.log('GTM Proxy: Skipping XHR bait URL:', url);
            return originalXHROpen.call(this, method, url, ...args);
        }

        if (typeof url === 'string' && url.includes(GTM_SERVER_URL)) {
            debugLog.log('GTM Proxy: Intercepting XHR:', url);
            const xhr = this;
            xhr._ml_intercept = true;
            modifyUrl(url).then(modifiedUrl => {
                debugLog.log('GTM Proxy: XHR URL modified to:', modifiedUrl);
                xhr.withCredentials = true; // always send cookies
                originalXHROpen.call(xhr, method, modifiedUrl, ...args);
            }).catch(error => {
                debugLog.error('GTM Proxy: Error modifying XHR URL:', error);
                xhr.withCredentials = true;
                originalXHROpen.call(xhr, method, url, ...args);
            });
            return;
        }
        // Not targeting GTM server URL; do not intercept/encrypt or change credentials
        return originalXHROpen.call(this, method, url, ...args);
    };

    // Encrypt XHR request body if necessary
    const originalXHRSend = XMLHttpRequest.prototype.send;
    XMLHttpRequest.prototype.send = function(body) {
        // Only attempt encryption for requests targeting GTM server URL
        // and when body is a plain string and method warrants it
        if (this._ml_intercept && this._ml_method && ['POST', 'PUT', 'PATCH'].includes(this._ml_method) && typeof body === 'string') {
            debugLog.log('GTM Proxy: Encrypting XHR payload.');
            encryptPayload(body).then(encrypted => {
                originalXHRSend.call(this, encrypted);
            }).catch(err => {
                debugLog.error('GTM Proxy: Failed to encrypt XHR payload – sending original. Reason:', err);
                originalXHRSend.call(this, body);
            });
            return;
        }
        return originalXHRSend.call(this, body);
    };

    debugLog.log('GTM Proxy: Immediate interception setup complete.');

    // Override Service Worker registration to intercept worker scripts
    if ('serviceWorker' in navigator) {
        const originalRegister = navigator.serviceWorker.register;
        navigator.serviceWorker.register = function(scriptURL, options) {
            if (typeof scriptURL === 'string' && scriptURL.includes(GTM_SERVER_URL)) {
                debugLog.log('GTM Proxy: Intercepting Service Worker registration:', scriptURL);
                return modifyUrl(scriptURL).then(modifiedUrl => {
                    debugLog.log('GTM Proxy: Service Worker URL modified to:', modifiedUrl);
                    return originalRegister.call(this, modifiedUrl, options);
                }).catch(error => {
                    debugLog.error('GTM Proxy: Error modifying Service Worker URL:', error);
                    return originalRegister.call(this, scriptURL, options);
                });
            }
            return originalRegister.call(this, scriptURL, options);
        };
        debugLog.log('GTM Proxy: Service Worker interception setup complete.');
    }

    // Initialize
    (async function initialize() {
        try {
            window.dataLayer = window.dataLayer || [];
            function gtag(){dataLayer.push(arguments);}
            gtag('js', new Date());
            gtag('config', GTM_ID);
            debugLog.info('DataLayer initialized');
            
            encryptionKey = await getEncryptionKey();
            if(encryptionKey) {
                debugLog.info('GTM initialization successful');
                const gtmScript = document.createElement('script');
                gtmScript.async = true;
                const gtmUrl = new URL(`gtm.js?id=${GTM_ID}`, GTM_SERVER_URL);
                gtmScript.src = gtmUrl.href;
                document.head.appendChild(gtmScript);
            } else {
                throw new Error('Failed to initialize: encryption key not available');
            }
        } catch (error) {
            debugLog.error('Initialization failed:', error);
        }
    })();

    // Add a global listener to catch any requests we might have missed
    debugLog.log('GTM Proxy: All interception methods initialized.');

    // Add MutationObserver to catch any script elements we might have missed
    const observer = new MutationObserver(function(mutations) {
        mutations.forEach(function(mutation) {
            if (mutation.type === 'childList') {
                mutation.addedNodes.forEach(function(node) {
                    if (node.nodeType === Node.ELEMENT_NODE && node.tagName === 'SCRIPT' && node.src && node.src.includes(GTM_SERVER_URL)) {
                        debugLog.log('GTM Proxy: MutationObserver caught unintercepted script:', node.src);
                        const originalSrc = node.src;
                        modifyUrl(originalSrc).then(modifiedUrl => {
                            debugLog.log('GTM Proxy: MutationObserver modifying script URL to:', modifiedUrl);
                            node.src = modifiedUrl;
                        }).catch(error => {
                            debugLog.error('GTM Proxy: MutationObserver error modifying URL:', error);
                        });
                    }
                });
            }
        });
    });

    // Start observing
    observer.observe(document, { childList: true, subtree: true });
    debugLog.log('GTM Proxy: MutationObserver started.');

    // Override Image constructor in case GTM uses it for tracking pixels
    const OriginalImage = window.Image;
    window.Image = function(...args) {
        const img = new OriginalImage(...args);
        const originalSrcDescriptor = Object.getOwnPropertyDescriptor(HTMLImageElement.prototype, 'src') || {};
        const originalSetter = originalSrcDescriptor.set;
        
        if (originalSetter) {
            try {
                const descriptor = Object.getOwnPropertyDescriptor(img, 'src');
                
                // If property doesn't exist or is configurable, we can define our own
                if (!descriptor || descriptor.configurable !== false) {
                    Object.defineProperty(img, 'src', {
                        set: function(value) {
                            if (typeof value === 'string' && value.includes(GTM_SERVER_URL)) {
                                debugLog.log('GTM Proxy: Intercepting Image src:', value);
                                modifyUrl(value).then(modifiedUrl => {
                                    originalSetter.call(this, modifiedUrl);
                                }).catch(error => {
                                    debugLog.error('GTM Proxy: Error modifying Image URL:', error);
                                    originalSetter.call(this, value);
                                });
                            } else {
                                originalSetter.call(this, value);
                            }
                        },
                        get: originalSrcDescriptor.get,
                        configurable: true
                    });
                } else if (descriptor && descriptor.set) {
                    // Property exists and is not configurable, but has a setter
                    // Wrap the existing setter
                    const existingSetter = descriptor.set;
                    Object.defineProperty(img, 'src', {
                        get: descriptor.get,
                        set: function(value) {
                            if (typeof value === 'string' && value.includes(GTM_SERVER_URL)) {
                                debugLog.log('GTM Proxy: Intercepting Image src (wrapped):', value);
                                modifyUrl(value).then(modifiedUrl => {
                                    existingSetter.call(this, modifiedUrl);
                                }).catch(error => {
                                    debugLog.error('GTM Proxy: Error modifying Image URL:', error);
                                    existingSetter.call(this, value);
                                });
                            } else {
                                existingSetter.call(this, value);
                            }
                        },
                        configurable: descriptor.configurable
                    });
                }
            } catch (e) {
                debugLog.warn('GTM Proxy: Could not define src property on Image element:', e.message);
                // Fall back to setAttribute interception which should still work
            }
        }
        return img;
    };

    // Override Navigator.sendBeacon for analytics requests
    const originalSendBeacon = navigator.sendBeacon;
    navigator.sendBeacon = function(url, data) {
        // Skip interception for bait URLs to prevent infinite loops
        if (typeof url === 'string' && 
            (url.includes('pagead2.googlesyndication.com') || 
             url.includes('ml_bait=true'))) {
            debugLog.log('GTM Proxy: Skipping sendBeacon bait URL:', url);
            return originalSendBeacon.call(this, url, data);
        }

        if (typeof url === 'string' && url.includes(GTM_SERVER_URL)) {
            debugLog.log('GTM Proxy: Intercepting sendBeacon:', url);
            return modifyUrl(url).then(modifiedUrl => {
                debugLog.log('GTM Proxy: sendBeacon URL modified to:', modifiedUrl);
                return originalSendBeacon.call(this, modifiedUrl, data);
            }).catch(error => {
                debugLog.error('GTM Proxy: Error modifying sendBeacon URL:', error);
                return originalSendBeacon.call(this, url, data);
            });
        }
        return originalSendBeacon.call(this, url, data);
    };

    // Add comprehensive IMG element interception
    const originalSetAttribute = Element.prototype.setAttribute;
    Element.prototype.setAttribute = function(name, value) {
        if (this.tagName === 'IMG' && name.toLowerCase() === 'src' && typeof value === 'string' && value.includes(GTM_SERVER_URL)) {
            debugLog.log('GTM Proxy: Intercepting IMG setAttribute src:', value);
            modifyUrl(value).then(modifiedUrl => {
                originalSetAttribute.call(this, name, modifiedUrl);
            }).catch(error => {
                debugLog.error('GTM Proxy: Error modifying IMG setAttribute URL:', error);
                originalSetAttribute.call(this, name, value);
            });
            return;
        }
        return originalSetAttribute.call(this, name, value);
    };
})(); 