(function () {
  try {
    console.log('[TrendsSniffer] injected script loaded');
    var MAX_BODY_SIZE = 120000;
    function trimBody(text) {
      if (typeof text !== 'string') return '';
      return text.length > MAX_BODY_SIZE ? text.slice(0, MAX_BODY_SIZE) : text;
    }

    function emitLifecycle(eventName, extra) {
      try {
        var payload = {
          event: eventName,
          ts: Date.now(),
          visibilityState: document.visibilityState,
          hidden: document.hidden,
          hasFocus: typeof document.hasFocus === 'function' ? document.hasFocus() : null,
          extra: extra || '',
        };
        console.log('[TrendsSniffer][lifecycle]', payload);
        window.postMessage(
          {
            __trendsSniffer: true,
            type: 'trends-lifecycle',
            payload: payload,
          },
          location.origin,
        );
      } catch (err) {
        console.log('[TrendsSniffer][lifecycle][error]', err);
      }
    }

    // -- Lifecycle Diagnostic: 记录可见性/冻结相关事件 --
    var observedEvents = ['visibilitychange', 'freeze', 'resume', 'focus', 'blur', 'pageshow', 'pagehide'];
    for (var evIndex = 0; evIndex < observedEvents.length; evIndex++) {
      (function (eventName) {
        window.addEventListener(
          eventName,
          function (eventObj) {
            var extra = '';
            if (eventObj && typeof eventObj === 'object' && 'persisted' in eventObj) {
              extra = 'persisted=' + String(eventObj.persisted);
            }
            emitLifecycle(eventName, extra);
          },
          true,
        );
        document.addEventListener(
          eventName,
          function (eventObj) {
            var extra = '';
            if (eventObj && typeof eventObj === 'object' && 'persisted' in eventObj) {
              extra = 'persisted=' + String(eventObj.persisted);
            }
            emitLifecycle('document:' + eventName, extra);
          },
          true,
        );
      })(observedEvents[evIndex]);
    }
    emitLifecycle('init', 'visibilityHook=disabled');

    var API_BASE = 'https://trends.google.com/trends/api/widgetdata/';
    var ENDPOINTS = ['relatedsearches', 'multiline'];

    function normalize(url) {
      try {
        return new URL(url, location.origin).href;
      } catch (_) {
        return '' + url;
      }
    }
    function matchEndpoint(url) {
      if (typeof url !== 'string') return null;
      var abs = normalize(url);
      for (var i = 0; i < ENDPOINTS.length; i++) {
        if (abs.startsWith(API_BASE + ENDPOINTS[i])) return ENDPOINTS[i];
      }
      return null;
    }

    var XHR = XMLHttpRequest && XMLHttpRequest.prototype;
    if (!XHR) {
      console.log('[TrendsSniffer][init] XMLHttpRequest prototype not available');
      return;
    }
    if (XHR.__trendsSnifferPatched) {
      console.log('[TrendsSniffer][init] already patched');
      return;
    }

    var origOpen = XHR.open;
    var origSend = XHR.send;

    XHR.open = function (method, url) {
      try {
        this.__trends_url = url;
        this.__trends_method = method;
      } catch (e) {
        console.log('[TrendsSniffer][open][error]', e);
      }
      return origOpen.apply(this, arguments);
    };

    XHR.send = function (body) {
      var url = this.__trends_url;
      var method = this.__trends_method;
      var endpoint = matchEndpoint(url);

      if (endpoint) {
        var startTime = Date.now();
        console.log('[TrendsSniffer][send] capturing', endpoint, method, url);

        this.addEventListener('load', function () {
          var duration = Date.now() - startTime;
          var abs = normalize(url);
          console.log(
            '[TrendsSniffer] XHR intercepted ' + endpoint + ':',
            abs,
            'status:',
            this.status,
            'time:',
            duration + 'ms',
            'len:',
            (this.responseText || '').length,
          );
          try {
            window.postMessage(
              {
                __trendsSniffer: true,
                kind: 'xhr',
                type: 'trends-' + endpoint,
                url: abs,
                status: this.status,
                body: trimBody(this.responseText),
              },
              location.origin,
            );
          } catch (e) {
            console.log('[TrendsSniffer][postMessage][error]', e);
          }
        });

        this.addEventListener('error', function () {
          console.log('[TrendsSniffer][error]', method, url, 'status:', this.status);
        });
      }

      try {
        return origSend.apply(this, arguments);
      } catch (e) {
        console.log('[TrendsSniffer][send][error]', e);
        throw e;
      }
    };

    XHR.__trendsSnifferPatched = true;
    console.log('[TrendsSniffer][init] XHR hooked');

    var origFetch = window.fetch;
    if (typeof origFetch === 'function' && !window.__trendsSnifferFetchPatched) {
      window.fetch = async function (input, init) {
        try {
          var url = typeof input === 'string' ? input : input && input.url;
          var endpoint = matchEndpoint(url);

          if (!endpoint) {
            return origFetch.apply(this, arguments);
          }

          var startTime = Date.now();
          var resp = await origFetch.apply(this, arguments);
          var duration = Date.now() - startTime;
          var abs = normalize(url);
          console.log(
            '[TrendsSniffer] fetch intercepted ' + endpoint + ':',
            abs,
            'status:',
            resp && resp.status,
            'time:',
            duration + 'ms',
          );
          try {
            var cloned = resp.clone();
            var text = '';
            try {
              text = await cloned.text();
            } catch (_) {}
            window.postMessage(
              {
                __trendsSniffer: true,
                kind: 'fetch',
                type: 'trends-' + endpoint,
                url: abs,
                status: resp && resp.status,
                body: trimBody(text),
              },
              location.origin,
            );
          } catch (e) {
            console.log('[TrendsSniffer][fetch][postMessage][error]', e);
          }
          return resp;
        } catch (e) {
          console.log('[TrendsSniffer][fetch][error]', e);
          return origFetch.apply(this, arguments);
        }
      };
      window.__trendsSnifferFetchPatched = true;
      console.log('[TrendsSniffer][init] fetch hooked');
    }
  } catch (err) {
    console.log('[TrendsSniffer][init][error]', err);
  }
})();
