/**
 * SwapAds Backlinks Statistics Bundle (F238).
 *
 * Loaded on the operator's public-facing pages. Attaches a single
 * document.click listener that fires when the visitor clicks (or
 * contains) a `.swapads-backlink` anchor. The event is enqueued
 * into the operator's local StatisticsQueue (via fetch to admin-ajax).
 *
 * Naming-convention-locked: no "tracker/tracking/ad/track" in code,
 * class names, file names, or strings (avoid EasyList triggers).
 *
 * @since 1.5.3
 */
(function () {
    'use strict';

    // Guard: only attach once per page load.
    if (window.SwapAdsBacklinksStatistics) {
        return;
    }
    window.SwapAdsBacklinksStatistics = { ready: true };

    /**
     * Mint a stable, anonymous visitor cookie.
     * 30-day expiration. SameSite=Lax so cross-site requests still send it.
     */
    function mintVisitorCookie() {
        var bytes = new Uint8Array(16);
        if (window.crypto && window.crypto.getRandomValues) {
            window.crypto.getRandomValues(bytes);
        } else {
            for (var i = 0; i < 16; i++) {
                bytes[i] = Math.floor(Math.random() * 256);
            }
        }
        var hex = '';
        for (var j = 0; j < bytes.length; j++) {
            hex += (bytes[j] < 16 ? '0' : '') + bytes[j].toString(16);
        }
        return hex;
    }

    /**
     * Read the swapads_sid cookie. Set one if missing.
     */
    function getOrMintVisitorId() {
        var name = 'swapads_sid=';
        var parts = document.cookie ? document.cookie.split(';') : [];
        for (var i = 0; i < parts.length; i++) {
            var c = parts[i].replace(/^\s+/, '');
            if (c.indexOf(name) === 0) {
                return c.substring(name.length, c.length);
            }
        }
        // No cookie yet - mint one.
        var sid = mintVisitorCookie();
        var days = 30;
        var expires = new Date(Date.now() + days * 86400000).toUTCString();
        document.cookie = 'swapads_sid=' + sid + '; expires=' + expires + '; path=/; SameSite=Lax';
        return sid;
    }

    /**
     * Enqueue the event into the operator's local queue.
     *
     * Uses fetch() to admin-ajax. blocking=false semantics achieved by
     * not awaiting the response (fire-and-forget at the browser level).
     * If admin-ajax fails, we silently drop the event - server has its
     * own dedup + rate-limit, and a missed click is acceptable for an
     * informational stat metric.
     */
    function enqueueBacklinkEvent(backlinkId) {
        var url = (window.ajaxurl || '/wp-admin/admin-ajax.php') +
                  '?action=swapads_statistics_enqueue';
        try {
            fetch(url, {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({
                    backlink_id: backlinkId,
                    partner_id: parseInt(
                        document.querySelector('meta[name="swapads-site-id"]')
                            ?.getAttribute('content') || '0', 10
                    ),
                    event_type: 'click',
                    ts_ms: Date.now(),
                    page_url: window.location.pathname,
                    swapads_sid: getOrMintVisitorId(),
                }),
                keepalive: true,  // survives page unload
            }).catch(function () {
                // Silent fail.
            });
        } catch (e) {
            // Silent fail.
        }
    }

    /**
     * Click handler: only fires for .swapads-backlink anchors.
     * Uses event delegation on document for performance.
     */
    document.addEventListener('click', function (event) {
        var target = event.target;
        // Walk up to find the anchor (handles clicks on inner elements).
        var anchor = null;
        if (target && target.closest) {
            anchor = target.closest('a.swapads-backlink');
        }
        if (!anchor) {
            return;
        }
        var sid = anchor.getAttribute('data-swapads-sid');
        if (!sid) {
            return;
        }
        enqueueBacklinkEvent(parseInt(sid, 10));
    }, { passive: true });

    // Set the visitor cookie on first load (so server has it for views).
    getOrMintVisitorId();
})();
