if (!window.WpStatisticsUserTracker) {
    window.WpStatisticsUserTracker = {
        // Track URL changes for AJAX in Gutenberg SPA mode using History API
        lastUrl: window.location.href,

        // Save original history methods
        originalPushState: history.pushState,
        originalReplaceState: history.replaceState,

        // Check DoNotTrack Settings on User Browser
        isDndActive: parseInt(navigator.msDoNotTrack || window.doNotTrack || navigator.doNotTrack, 10),

        // Prevent init() from running more than once
        hasTrackerInitializedOnce: false,

        // Prevent trackUrlChange() from running more than once
        hasUrlChangeTrackerInitialized: false,

        // Flag to track hit request status
        hitRequestSuccessful: true,

        init: function () {
            if (this.hasTrackerInitializedOnce) {
                return;
            }
            this.hasTrackerInitializedOnce = true;

            if (WP_Statistics_Tracker_Object.option.isPreview) {
                return;
            }

            if (typeof WP_Statistics_Tracker_Object == "undefined") {
                console.error('WP Statistics: Variable WP_Statistics_Tracker_Object not found. Ensure /wp-content/plugins/wp-statistics/assets/js/tracker.js is either excluded from cache settings or not dequeued by any plugin. Clear your cache if necessary.');
            } else {
                this.checkHitRequestConditions();
            }

            this.trackUrlChange();
        },

        // Method to Base64 encode a string using modern approach
        base64Encode: function (str) {
            const encoder = new TextEncoder();
            const data = encoder.encode(str);
            return btoa(String.fromCharCode.apply(null, data));
        },

        // Extract Path and Query String from Current URL and Base64 encode it
        getPathAndQueryString: function () {
            const pathname = window.location.pathname;
            const queryString = window.location.search;
            const fullPath = pathname + queryString;
            return this.base64Encode(fullPath);
        },

        // Get Referred URL and Base64 encode it
        getReferred: function () {
            return this.base64Encode(document.referrer);
        },

        // Check Conditions for Sending Hit Request
        checkHitRequestConditions: function () {
            if (WP_Statistics_Tracker_Object.option.dntEnabled) {
                if (this.isDndActive !== 1) {
                    this.sendHitRequest();
                } else {
                    console.log('WP Statistics: Do Not Track (DNT) is enabled. Hit request not sent.');
                }
            } else {
                this.sendHitRequest();
            }
        },

        // Sending Hit Request
        sendHitRequest: async function () {
            try {
                let requestUrl = this.getRequestUrl();
                const params = new URLSearchParams({
                    ...WP_Statistics_Tracker_Object.hitParams,
                    referred: this.getReferred(), // Use the getReferred method
                    page_uri: this.getPathAndQueryString() // Use the correct key for the path and query string (Base64 encoded)
                }).toString();

                const xhr = new XMLHttpRequest();
                xhr.open('POST', requestUrl, true);
                xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
                xhr.send(params);
                xhr.onreadystatechange = function () {
                    if (xhr.readyState === 4) {
                        if (xhr.status === 200) {
                            const responseData = JSON.parse(xhr.responseText);
                            this.hitRequestSuccessful = responseData.status !== false;
                        } else {
                            this.hitRequestSuccessful = false;
                            console.warn('WP Statistics: Hit request failed with status ' + xhr.status);
                        }
                    }
                }.bind(this);
            } catch (error) {
                this.hitRequestSuccessful = false;
                console.error('WP Statistics: Error sending hit request:', error);
            }
        },

        getRequestUrl: function () {
            let requestUrl = `${WP_Statistics_Tracker_Object.requestUrl}/`;

            if (WP_Statistics_Tracker_Object.option.bypassAdBlockers) {
                requestUrl = WP_Statistics_Tracker_Object.ajaxUrl;
            } else {
                requestUrl += WP_Statistics_Tracker_Object.hitParams.endpoint;
            }

            return requestUrl;
        },

        // Function to update the WP_Statistics_Tracker_Object when URL changes
        // Uses polling to handle delayed DOM updates in SPAs
        updateTrackerObject: function (callback) {
            let callbackCalled = false;
            let attempts = 0;
            const maxAttempts = 20; // Maximum 2 seconds (20 * 100ms)

            const tryUpdate = function () {
                // Re-query the script tag each time (it may be replaced by Interactivity API)
                const scriptTag = document.getElementById("wp-statistics-tracker-js-extra");

                if (!scriptTag) {
                    attempts++;
                    if (attempts < maxAttempts) {
                        setTimeout(tryUpdate, 100);
                    } else if (!callbackCalled && callback) {
                        callbackCalled = true;
                        callback();
                    }
                    return;
                }

                try {
                    const match = scriptTag.innerHTML.match(/var\s+WP_Statistics_Tracker_Object\s*=\s*(\{[\s\S]*?\});/);
                    if (match && match[1]) {
                        const newData = JSON.parse(match[1]);

                        // Check if data has actually changed
                        const dataChanged = !WP_Statistics_Tracker_Object.hitParams ||
                            JSON.stringify(WP_Statistics_Tracker_Object.hitParams) !== JSON.stringify(newData.hitParams);

                        if (dataChanged) {
                            WP_Statistics_Tracker_Object = newData;
                            if (!callbackCalled && callback) {
                                callbackCalled = true;
                                callback();
                            }
                        } else {
                            // Data hasn't changed yet, try again
                            attempts++;
                            if (attempts < maxAttempts) {
                                setTimeout(tryUpdate, 100);
                            } else if (!callbackCalled && callback) {
                                callbackCalled = true;
                                callback();
                            }
                        }
                    } else {
                        attempts++;
                        if (attempts < maxAttempts) {
                            setTimeout(tryUpdate, 100);
                        } else if (!callbackCalled && callback) {
                            callbackCalled = true;
                            callback();
                        }
                    }
                } catch (error) {
                    console.error("WP Statistics: Error parsing WP_Statistics_Tracker_Object", error);
                    if (!callbackCalled && callback) {
                        callbackCalled = true;
                        callback();
                    }
                }
            };

            // Start trying to update with a small initial delay to let DOM settle
            setTimeout(tryUpdate, 50);
        },

        // Detect URL changes caused by History API (pushState, replaceState) or browser navigation
        trackUrlChange: function () {
            // Only set up History API wrappers once
            if (this.hasUrlChangeTrackerInitialized) {
                return;
            }
            this.hasUrlChangeTrackerInitialized = true;

            const self = this;

            window.removeEventListener('popstate', self.handleUrlChange);

            history.pushState = function () {
                self.originalPushState.apply(history, arguments);
                self.handleUrlChange();
            };

            history.replaceState = function () {
                self.originalReplaceState.apply(history, arguments);
                self.handleUrlChange();
            };

            window.addEventListener('popstate', function () {
                self.handleUrlChange();
            });
        },

        // Handles URL changes in an SPA environment (WordPress Interactivity API, etc.)
        handleUrlChange: function () {
            const self = this;

            if (window.location.href !== this.lastUrl) {
                this.lastUrl = window.location.href;
                this.updateTrackerObject(function () {
                    self.checkHitRequestConditions();
                });
            }
        }
    };
}