(function () {
  'use strict';

  var cfg = window.NiwaTraffic || {};
  if (!cfg.enabled || !cfg.endpoint) {
    return;
  }

  var sessionTtl = Number(cfg.sessionTtl || 1800) * 1000;
  var batchSize = Math.max(1, Math.min(20, Number(cfg.batchSize || 8)));
  var queue = [];
  var flushTimer = null;
  var visitorKey = 'niwa_ai_traffic_visitor';
  var sessionKey = 'niwa_ai_traffic_session';
  var lastSeenKey = 'niwa_ai_traffic_last_seen';
  var attrCookie = 'niwa_ai_traffic_attr';
  var sessionCookie = 'niwa_ai_traffic_session';
  var clickIds = ['gclid', 'gbraid', 'wbraid', 'fbclid', 'msclkid', 'ttclid'];

  function storageGet(key) {
    try {
      return window.localStorage.getItem(key) || '';
    } catch (err) {
      return '';
    }
  }

  function storageSet(key, value) {
    try {
      window.localStorage.setItem(key, value);
    } catch (err) {
      // Storage can be unavailable in private browsing.
    }
  }

  function sessionGet(key) {
    try {
      return window.sessionStorage.getItem(key) || '';
    } catch (err) {
      return '';
    }
  }

  function sessionSet(key, value) {
    try {
      window.sessionStorage.setItem(key, value);
    } catch (err) {
      // Session storage can be unavailable in hardened browsers.
    }
  }

  function makeId(prefix) {
    var random = '';
    if (window.crypto && window.crypto.getRandomValues) {
      var bytes = new Uint32Array(4);
      window.crypto.getRandomValues(bytes);
      random = Array.prototype.map.call(bytes, function (n) {
        return n.toString(16);
      }).join('');
    } else {
      random = String(Math.random()).slice(2) + String(Date.now());
    }
    return prefix + '_' + random;
  }

  function setCookie(name, value, maxAgeSeconds) {
    document.cookie = name + '=' + encodeURIComponent(value) +
      '; path=/; max-age=' + String(maxAgeSeconds) + '; SameSite=Lax';
  }

  function getVisitorId() {
    var id = storageGet(visitorKey);
    if (!id) {
      id = makeId('v');
      storageSet(visitorKey, id);
    }
    return id;
  }

  function getSessionId() {
    var now = Date.now();
    var id = storageGet(sessionKey);
    var lastSeen = Number(storageGet(lastSeenKey) || 0);
    if (!id || !lastSeen || (now - lastSeen) > sessionTtl) {
      id = makeId('s');
    }
    storageSet(sessionKey, id);
    storageSet(lastSeenKey, String(now));
    setCookie(sessionCookie, id, Math.ceil(sessionTtl / 1000));
    return id;
  }

  function urlParams() {
    try {
      return new URL(window.location.href).searchParams;
    } catch (err) {
      return new URLSearchParams(window.location.search || '');
    }
  }

  function currentAttribution() {
    var params = urlParams();
    var data = {
      source: params.get('utm_source') || '',
      medium: params.get('utm_medium') || '',
      campaign: params.get('utm_campaign') || '',
      term: params.get('utm_term') || '',
      content: params.get('utm_content') || '',
      channel: '',
      referrer_host: referrerHost()
    };

    for (var i = 0; i < clickIds.length; i++) {
      var value = params.get(clickIds[i]);
      if (value) {
        data.click_id_name = clickIds[i];
        data.click_id_value = value;
        break;
      }
    }

    if (data.source || data.medium || data.campaign || data.click_id_name || data.referrer_host) {
      setCookie(attrCookie, JSON.stringify(data), 90 * 24 * 60 * 60);
    }

    return data;
  }

  function referrerHost() {
    if (!document.referrer) {
      return '';
    }
    try {
      var host = new URL(document.referrer).hostname.replace(/^www\./, '').toLowerCase();
      var siteHost = String(cfg.siteHost || window.location.hostname).replace(/^www\./, '').toLowerCase();
      return host && host !== siteHost ? host : '';
    } catch (err) {
      return '';
    }
  }

  function baseEvent(type, meta) {
    var attr = currentAttribution();
    return {
      event_id: makeId('e'),
      event_type: type,
      session_id: getSessionId(),
      visitor_id: getVisitorId(),
      occurred_at: new Date().toISOString(),
      page_url: window.location.href,
      page_title: document.title || '',
      referrer_url: document.referrer || '',
      utm_source: attr.source || '',
      utm_medium: attr.medium || '',
      utm_campaign: attr.campaign || '',
      utm_term: attr.term || '',
      utm_content: attr.content || '',
      click_id_name: attr.click_id_name || '',
      click_id_value: attr.click_id_value || '',
      meta: meta || {}
    };
  }

  function enqueue(type, meta) {
    queue.push(baseEvent(type, meta));
    if (queue.length >= batchSize) {
      flush();
      return;
    }
    if (!flushTimer) {
      flushTimer = window.setTimeout(flush, 2500);
    }
  }

  function flush() {
    if (flushTimer) {
      window.clearTimeout(flushTimer);
      flushTimer = null;
    }
    if (!queue.length) {
      return;
    }

    var batch = queue.splice(0, 20);
    var body = JSON.stringify({ events: batch });
    if (navigator.sendBeacon) {
      try {
        var ok = navigator.sendBeacon(cfg.endpoint, new Blob([body], { type: 'application/json' }));
        if (ok) {
          return;
        }
      } catch (err) {
        // Fall through to fetch.
      }
    }

    if (window.fetch) {
      window.fetch(cfg.endpoint, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        credentials: 'same-origin',
        keepalive: true,
        body: body
      }).catch(function () {});
    }
  }

  function trackPageviewOnce() {
    var key = 'niwa_ai_pv_' + window.location.pathname + window.location.search;
    if (sessionGet(key)) {
      return;
    }
    sessionSet(key, '1');
    enqueue('pageview', { screen: screen.width + 'x' + screen.height });
  }

  function installEngagementSignals() {
    window.setTimeout(function () {
      enqueue('engaged_view', { seconds: 10 });
    }, 10000);

    var scrolled = false;
    window.addEventListener('scroll', function () {
      if (scrolled) {
        return;
      }
      var doc = document.documentElement;
      var total = Math.max(doc.scrollHeight - window.innerHeight, 1);
      var depth = Math.round((window.scrollY / total) * 100);
      if (depth >= 50) {
        scrolled = true;
        enqueue('scroll_depth', { depth: depth });
      }
    }, { passive: true });

    if (document.body && document.body.classList.contains('single-post')) {
      window.setTimeout(function () {
        enqueue('blog_read', { seconds: 20 });
      }, 20000);
    }
  }

  if (document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded', function () {
      trackPageviewOnce();
      installEngagementSignals();
    });
  } else {
    trackPageviewOnce();
    installEngagementSignals();
  }

  window.addEventListener('pagehide', flush);
  window.NiwaTrafficTrack = enqueue;
}());
