(function () {
  if (window.__gmapsCollectorNetworkHookInstalled) {
    return;
  }

  window.__gmapsCollectorNetworkHookInstalled = true;

  const MESSAGE_TYPE = "GMAPS_COLLECTOR_NETWORK_PAYLOAD";
  const RESPONSE_PREFIX = '/*""*/';

  function normalizeBody(body) {
    return String(body || "").trim();
  }

  function looksLikeMapsPayload(body) {
    const text = normalizeBody(body);
    if (!text) {
      return false;
    }

    if (text.startsWith(RESPONSE_PREFIX)) {
      return true;
    }

    if (text.startsWith(")]}'")) {
      return true;
    }

    if (text.startsWith("[") || text.startsWith("{")) {
      return (
        text.includes('"d":"') ||
        text.includes('"d":') ||
        text.includes('query_place_id') ||
        text.includes('google.com/maps/place') ||
        text.includes('google.com/maps/preview/place') ||
        text.includes('"0x') ||
        text.includes('/g/')
      );
    }

    return false;
  }

  function shouldCapture(url, body) {
    if (!url || typeof body !== "string" || !body) {
      return false;
    }

    if (!looksLikeMapsRequest(url)) {
      return false;
    }

    return looksLikeMapsPayload(body);
  }

  function looksLikeMapsRequest(url) {
    if (!url || !url.startsWith(location.origin)) {
      return false;
    }

    return (
      url.includes("/maps/preview/") ||
      url.includes("/maps/rpc/") ||
      url.includes("/_/Maps") ||
      url.includes("/_/") ||
      url.includes("batchexecute") ||
      url.includes("preview/place") ||
      url.includes("preview/entity")
    );
  }

  function postPayload(url, body, transport) {
    if (!shouldCapture(url, body)) {
      return;
    }

    window.postMessage(
      {
        source: "gmaps-collector",
        type: MESSAGE_TYPE,
        transport,
        url,
        body
      },
      "*"
    );
  }

  const originalOpen = XMLHttpRequest.prototype.open;
  const originalSend = XMLHttpRequest.prototype.send;

  XMLHttpRequest.prototype.open = function (...args) {
    this.__gmapsCollectorMethod = args[0];
    this.__gmapsCollectorUrl = args[1];
    return originalOpen.apply(this, args);
  };

  XMLHttpRequest.prototype.send = function (...args) {
    this.addEventListener("load", function () {
      try {
        if (this.readyState !== 4) {
          return;
        }

        if (typeof this.responseText !== "string") {
          return;
        }

        postPayload(this.__gmapsCollectorUrl || this.responseURL, this.responseText, "xhr");
      } catch (_error) {
        return;
      }
    });

    return originalSend.apply(this, args);
  };

  const originalFetch = window.fetch;

  function resolveFetchUrl(requestLike, response) {
    const rawUrl =
      response?.url ||
      (typeof requestLike === "string"
        ? requestLike
        : requestLike?.url || "");
    if (!rawUrl) {
      return "";
    }

    try {
      return new URL(rawUrl, location.origin).toString();
    } catch (_error) {
      return String(rawUrl);
    }
  }

  window.fetch = function (...args) {
    return Promise.resolve(originalFetch.apply(this, args)).then((response) => {
      try {
        const url = resolveFetchUrl(args[0], response);
        if (!looksLikeMapsRequest(url)) {
          return response;
        }

        Promise.resolve()
          .then(async () => {
            const cloned = response.clone();
            const body = await cloned.text();
            postPayload(url, body, "fetch");
          })
          .catch(() => {});
      } catch (_error) {
        return response;
      }

      return response;
    });
  };
})();
