(function() {
    // Read required data attributes from the DOM
    var root = document.querySelector('[data-signal-product-id]');
    if (!root) return;

    var productId = root.getAttribute('data-signal-product-id');
    var shopId = root.getAttribute('data-signal-shop-id');
    if (!productId || !shopId) return;
    var isOwner = root.hasAttribute('data-signal-is-owner');

    // Per-session random token (never persisted)
    var sessionToken = Math.random().toString(36).slice(2) + Math.random().toString(36).slice(2);

    var beaconSent = false;

    // --- Presence tracking ---
    var bootTime = Date.now();
    var visibleMs = 0;
    var activeMs = 0;
    var lastVisibleStart = document.hidden ? null : Date.now();
    var lastActiveStart = Date.now();
    var idleTimeout = null;
    var IDLE_THRESHOLD = 2000;

    function onVisibilityChange() {
        if (document.hidden) {
            // Went hidden — accumulate visible time
            if (lastVisibleStart !== null) {
                visibleMs += Date.now() - lastVisibleStart;
                lastVisibleStart = null;
            }
            sendBeacon();
        } else {
            // Became visible — start counting again
            lastVisibleStart = Date.now();
        }
    }

    function onActivity() {
        if (lastActiveStart === null) {
            lastActiveStart = Date.now();
        }
        clearTimeout(idleTimeout);
        idleTimeout = setTimeout(function() {
            // User went idle
            if (lastActiveStart !== null) {
                activeMs += Date.now() - lastActiveStart;
                lastActiveStart = null;
            }
        }, IDLE_THRESHOLD);
    }

    document.addEventListener('visibilitychange', onVisibilityChange);
    document.addEventListener('mousemove', onActivity);
    document.addEventListener('touchstart', onActivity);
    document.addEventListener('keydown', onActivity);

    // --- Scroll tracking ---
    var scrollDepthMax = 0;
    var scrollDirectionChanges = 0;
    var lastScrollY = window.scrollY || 0;
    var lastScrollDirection = 0; // 0=unknown, 1=down, -1=up

    function onScroll() {
        var y = window.scrollY || 0;
        var pageHeight = Math.max(
            document.body.scrollHeight || 0,
            document.documentElement.scrollHeight || 0
        );
        var viewportHeight = window.innerHeight || 0;
        var scrollable = pageHeight - viewportHeight;
        if (scrollable > 0) {
            var depth = y / scrollable;
            if (depth > scrollDepthMax) scrollDepthMax = depth;
        }

        var delta = y - lastScrollY;
        if (delta !== 0) {
            var dir = delta > 0 ? 1 : -1;
            if (lastScrollDirection !== 0 && dir !== lastScrollDirection) {
                scrollDirectionChanges++;
            }
            lastScrollDirection = dir;
        }
        lastScrollY = y;
    }

    window.addEventListener('scroll', onScroll, {passive: true});

    // --- Media tracking ---
    var mediaDurationMs = null;
    var mediaPlayMs = 0;
    var mediaPlayCount = 0;
    var mediaPauseCount = 0;
    var mediaSeekCount = 0;
    var mediaSeekBackCount = 0;
    var mediaSpeed = null;
    var mediaCompleted = false;
    var mediaPlayStart = null;
    var mediaLastTime = 0;

    function attachMediaListeners() {
        var elements = document.querySelectorAll('video, audio');
        for (var i = 0; i < elements.length; i++) {
            var el = elements[i];
            if (el._signalsBound) continue;
            el._signalsBound = true;

            el.addEventListener('loadedmetadata', function() {
                if (this.duration && isFinite(this.duration)) {
                    mediaDurationMs = Math.round(this.duration * 1000);
                }
            });

            el.addEventListener('play', function() {
                mediaPlayCount++;
                mediaPlayStart = Date.now();
                mediaSpeed = this.playbackRate;
            });

            el.addEventListener('pause', function() {
                mediaPauseCount++;
                if (mediaPlayStart !== null) {
                    mediaPlayMs += Date.now() - mediaPlayStart;
                    mediaPlayStart = null;
                }
            });

            el.addEventListener('ended', function() {
                mediaCompleted = true;
                if (mediaPlayStart !== null) {
                    mediaPlayMs += Date.now() - mediaPlayStart;
                    mediaPlayStart = null;
                }
            });

            el.addEventListener('seeked', function() {
                mediaSeekCount++;
                if (this.currentTime < mediaLastTime) {
                    mediaSeekBackCount++;
                }
                mediaLastTime = this.currentTime;
            });

            el.addEventListener('timeupdate', function() {
                mediaLastTime = this.currentTime;
            });

            el.addEventListener('ratechange', function() {
                mediaSpeed = this.playbackRate;
            });
        }
    }

    attachMediaListeners();

    // Re-attach when new media elements appear (watch mode hard-swap)
    var observer = null;
    if (typeof MutationObserver !== 'undefined') {
        observer = new MutationObserver(function() {
            attachMediaListeners();
        });
        observer.observe(document.body, {childList: true, subtree: true});
    }

    // --- Ring context ---
    var isRingEntry = false;
    var ringPosition = null;
    try {
        var watchLeft = document.querySelector('[data-watch-product-id]');
        if (watchLeft) {
            isRingEntry = true;
            var savedPos = localStorage.getItem('watchRingPosition');
            if (savedPos !== null) ringPosition = parseInt(savedPos, 10);
        }
    } catch (e) {}

    // --- Build payload ---
    function buildPayload() {
        // Finalize running timers
        var now = Date.now();
        var wallClockMs = now - bootTime;

        var finalVisibleMs = visibleMs;
        if (lastVisibleStart !== null) {
            finalVisibleMs += now - lastVisibleStart;
        }

        var finalActiveMs = activeMs;
        if (lastActiveStart !== null) {
            finalActiveMs += now - lastActiveStart;
        }

        var finalMediaPlayMs = mediaPlayMs;
        if (mediaPlayStart !== null) {
            finalMediaPlayMs += now - mediaPlayStart;
        }

        var mediaPercentPlayed = null;
        if (mediaDurationMs && mediaDurationMs > 0) {
            mediaPercentPlayed = Math.min(1, finalMediaPlayMs / mediaDurationMs);
        }

        var payload = {
            session_token: sessionToken,
            product_id: productId,
            shop_id: shopId,
            wall_clock_ms: wallClockMs,
            visible_ms: finalVisibleMs,
            active_ms: finalActiveMs,
            scroll_depth_max: Math.round(scrollDepthMax * 1000) / 1000,
            scroll_direction_changes: scrollDirectionChanges,
            viewport_width: window.innerWidth || 0,
            is_ring_entry: isRingEntry,
            ring_position: ringPosition,
            is_owner: isOwner
        };

        // Only include media fields if there was media
        if (mediaDurationMs !== null) {
            payload.media_duration_ms = mediaDurationMs;
            payload.media_play_ms = finalMediaPlayMs;
            payload.media_play_count = mediaPlayCount;
            payload.media_pause_count = mediaPauseCount;
            payload.media_seek_count = mediaSeekCount;
            payload.media_seek_back_count = mediaSeekBackCount;
            payload.media_speed = mediaSpeed;
            payload.media_completed = mediaCompleted;
            payload.media_percent_played = mediaPercentPlayed;
        }

        return payload;
    }

    // --- Send beacon ---
    function sendBeacon() {
        if (beaconSent) return;
        beaconSent = true;

        var payload = buildPayload();
        var json = JSON.stringify(payload);

        var sent = false;
        if (navigator.sendBeacon) {
            try {
                sent = navigator.sendBeacon('/signals/beacon', new Blob([json], {type: 'application/json'}));
            } catch (e) {}
        }

        if (!sent) {
            try {
                fetch('/signals/beacon', {
                    method: 'POST',
                    body: json,
                    headers: {'Content-Type': 'application/json'},
                    keepalive: true
                });
            } catch (e) {}
        }
    }

    window.addEventListener('beforeunload', sendBeacon);

    // --- SPA reset: listen for custom event from watch.js ---
    document.addEventListener('mps:signal:reset', function(e) {
        // Finalize and send current session
        sendBeacon();

        // Reset state for new product
        var detail = e.detail || {};
        productId = detail.product_id || productId;
        shopId = detail.shop_id || shopId;
        sessionToken = Math.random().toString(36).slice(2) + Math.random().toString(36).slice(2);
        beaconSent = false;

        // Reset presence
        bootTime = Date.now();
        visibleMs = 0;
        activeMs = 0;
        lastVisibleStart = document.hidden ? null : Date.now();
        lastActiveStart = Date.now();

        // Reset scroll
        scrollDepthMax = 0;
        scrollDirectionChanges = 0;
        lastScrollY = window.scrollY || 0;
        lastScrollDirection = 0;

        // Reset media
        mediaDurationMs = null;
        mediaPlayMs = 0;
        mediaPlayCount = 0;
        mediaPauseCount = 0;
        mediaSeekCount = 0;
        mediaSeekBackCount = 0;
        mediaSpeed = null;
        mediaCompleted = false;
        mediaPlayStart = null;
        mediaLastTime = 0;

        // Update ring context
        isRingEntry = true;
        try {
            var savedPos = localStorage.getItem('watchRingPosition');
            if (savedPos !== null) ringPosition = parseInt(savedPos, 10);
        } catch (ex) {}

        // Re-attach media listeners for new elements
        attachMediaListeners();
    });
})();
