  console.log("mother script running");
  
  // Store original functions
  const originalFetch = window.fetch;
  const originalXHROpen = XMLHttpRequest.prototype.open;
  const originalCreateElement = document.createElement;

  function getURL(resource){
    if (typeof resource === "string") {
      const isURL = URL.canParse(resource);
      if (isURL) return URL.parse(resource)
      else {
        const urlTry = (window.location.origin + resource);
        if (URL.canParse(urlTry)) return URL.parse(urlTry)
        else return null
      }
    }
    else if ("pathname" in resource) return resource
    else if ("method" in resource) return URL.parse(resource.url)
    else {
      console.warn("weird fetch", resource);
      return null
    }
  }
  function reRouteToHyperware(url){
    console.log("Rewriting URL:", url);
    if (url.origin === window.location.origin)
      url.pathname = HYPERWARE_APP_PATH + url.pathname;
    else console.warn("external fetch?", url.href);
    return url  
  }
  // Log all network activity for debugging
  window.fetch = async function(resource, options) {
    const url1 = getURL(resource);
    if (!url) return
    const url = reRouteToHyperware(url1);
    const res = await originalFetch(url, options);
    const resc = res.clone();
    const headers = {};
    for (let [k, v] of resc.headers.entries()){
      headers[k] = v;
    }
    console.warn({url, status: resc.status, headers});
    return res
  };
  
  XMLHttpRequest.prototype.open = function(method, url, ...rest) {
    console.log("XHR intercepted:", url);
    let newUrl = url;
    if (url.includes('/_next/') || url.includes('/static/chunks/')) {
      console.log("Rewriting XHR URL:", url);
      newUrl = HYPERWARE_APP_PATH + url;
    }
    // return originalXHROpen.call(this, method, newUrl, ...rest);
  };
  
  // Most important: intercept script tag creation since webpack uses this
  document.createElement = function(tagName) {
    const element = originalCreateElement.call(document, tagName);
    console.log("dynamic element created", tagName);
    const ltn = tagName.toLowerCase();
    
    if (ltn === 'link' || ltn === "a") {
      let originalHref = '';
      Object.defineProperty(element, 'href', {
        get: function() {
          return originalHref;
        },
        set: function(value) {
          console.log("setting href", {new: value, old: element.getAttribute("href")});
          const uri = typeof value === "string" ? value : value.toString();
          const url = getURL(uri);
          originalHref = url;
          return url;
        }
      });
    }
    if (['script', 'img', 'video', 'audio', 'track', 'iframe'].includes(ltn)) {
      // Add a property setter interceptor for the src attribute
      let originalSrc = '';
      Object.defineProperty(element, 'src', {
        get: function() {
          return originalSrc;
        },
        set: function(value) {
          const uri = typeof value === "string" ? value : value.toString();
          console.log("setting src", {new: value, old: element.src});
          // if (uri.includes("vercel")){
          //   console.log({element});
          //   return ""
          // }
          const url = getURL(uri);
          if (!url) return
          originalSrc = url
          return url;
        }
      });
    }
    if (ltn === 'img') {
       const originalSetAttribute = element.setAttribute;
        element.setAttribute = function(name, value) {
          let newValue = value;
          console.log("setting img", {name, value});
          if (name === "src" || name === "href"){
            const uri = typeof value === "string" ? value : value.toString();
            const url1 = getURL(uri);
            if (url1) newValue = reRouteToHyperware(url1);
          }
          return originalSetAttribute.call(this, name, newValue);
        };    
    }
    if (ltn === 'meta') {
       const originalSetAttribute = element.setAttribute;
        element.setAttribute = function(name, value) {
          if (name === 'http-equiv' && value.toLowerCase() === 'refresh') {
            console.warn("META REFRESH DETECTED");
            console.trace("Meta refresh stack trace");
            debugger;
          }
          return originalSetAttribute.call(this, name, value);
        };    
    }
    else console.log("element created", {tagName, element});
    
    return element;
  };
  
  // Add monitoring of script tags to see what's happening
  function observeMutations(){
    let oldHref = document.location.href;
    // let oldHref2 = window.location.href;
    const body = document.querySelector("body");
    const observer = new MutationObserver(mutations => {
      if (oldHref !== document.location.href){
      console.warn("mutation", {new: document.location.href, old: oldHref});
      // console.warn("mutationw", {neww: window.location.href, oldw: oldHref2});
        
      };

    for (let mutation of mutations){
      console.log(mutation.type, mutation)
      for (let node of mutation.addedNodes){
        const attrs = node.getAttributeNames();
        const data = Array.from(attrs).reduce((acc, item) => ({...acc, [item]: node.getAttribute(item)}), {});
        data.outerHTML = node.outerHTML;
        data.tagName = node.tagName;
        fuckNext();
      }
    }
    });
    observer.observe(body, {childList: true, subtree: true, attributes: true, attributeOldValue: true})

  }
  
// next router crap

let fuckingNext = false;
  // Wait for Next.js to initialize
  const fuckNext = () => {
    if (fuckingNext) return
    if (window.next && window.next.router) {
      console.log("next router", window.next.router);
      // Store original router methods
      const originalPush = window.next.router.push;
      const originalReplace = window.next.router.replace;
      const originalPrefetch = window.next.router.prefetch;
      
      // Override router methods
      window.next.router.push = function() {
        console.log("Router push intercepted:", arguments);
        // Return without calling the original to prevent navigation
        return new Promise(() => {}); // Return a never-resolving promise
      };
      
      window.next.router.replace = function() {
        console.log("Router replace intercepted:", arguments);
        // Return without calling the original to prevent navigation
        return new Promise(() => {});
      };
      window.next.router.refresh= function() {
        console.log("Router refresh intercepted:", arguments);
        // Return without calling the original to prevent navigation
        return new Promise(() => {});
      };
      window.next.router.prefetch = function() {
        console.log("Router prefetch  intercepted:", arguments);
        return originalPrefetch.call(arguments)
      };
      window.next.router.hmrRefresh = function() {
        console.log("Router hmrRefresh intercepted:", arguments);
        // Return without calling the original to prevent navigation
        return new Promise(() => {});
      };
      window.next.router.forward = function() {
        console.log("Router forward intercepted:", arguments);
        // Return without calling the original to prevent navigation
        return new Promise(() => {});
      };
      window.next.router.back= function() {
        console.log("Router back intercepted:", arguments);
        // Return without calling the original to prevent navigation
        return new Promise(() => {});
      };
      
      console.log("Next.js router methods intercepted");
      fuckingNext = true;
    } else {
      console.log("Next.js router not found");
    }
  };
  
  // Listeners
  // Start observing when body is available
  document.addEventListener("DOMContentLoaded",observeMutations);
  navigation.addEventListener("navigate", (e) => {
    console.log("navigation", e.destination)
    console.log("navigation", e.info)
    console.log("navigation", e.navigationType)
    console.log("navigation", e.userInitiated)
    console.log("navigation", e.canIntercept)
    e.intercept({
      async handler(){
        console.log("intercepting navigation")
      }
    })
  })
  window.addEventListener("hashchange", (e) => {
    console.warn("navigation", window.location)
  })
  window.addEventListener('beforeunload', function(e) {
    remoteLog("unloading!!", e);
  });
  window.addEventListener('popstate', function(e) {
    remoteLog("popstate", e);
  });
  window.addEventListener('pageswap', function(e) {
    remoteLog("pageswap", e);
  });
  
const originalListener = window.addEventListener;

 window.addEventListener = function(type, listener, options) {
    if (type === 'popstate') {
      console.log("Popstate event listener added");
      // Replace with no-op function
      return originalListener.call(this, type, function(e) {
        console.log("Popstate event prevented", e);
        e.preventDefault();
        e.stopImmediatePropagation();
      }, options);
    }
    return originalListener.call(this, type, listener, options);
  };
    
  // // prevent redirects
  // const originalLocationDescriptor = Object.getOwnPropertyDescriptor(window, 'location');
  // // Override location to prevent redirects
  // let interceptedLocation = { ...location };
  // Object.defineProperty(window, 'location', {
  //   get: function() {
  //     return interceptedLocation;
  //   },
  //   set: function(value) {
  //     console.log("PREVENTED REDIRECT to:", value);
  //     console.trace("Redirect stack trace");
  //     // Don't actually set it, just log it
  //     return interceptedLocation;
  //   }
  // });
  
  // // Also overwrite properties on our fake location
  // for (let prop in interceptedLocation) {
  //   if (typeof interceptedLocation[prop] !== 'function') {
  //     Object.defineProperty(interceptedLocation, prop, {
  //       get: function() {
  //         return location[prop];
  //       },
  //       set: function(value) {
  //         console.log(`PREVENTED location.${prop} change to:`, value);
  //         console.trace(`location.${prop} change stack trace`);
  //         // Don't actually apply the change
  //       }
  //     });
  //   }
  // }

    // Store logs in sessionStorage
    const originalConsoleLog = console.warn;
    console.warn= function(...args) {{
      remoteLog(...args);
      // originalConsoleLog.apply(this, args);
    };
    // console.log = function() {{
    //   const jon = JSON.stringify(arguments);
    //   remoteLog(jon);
    //   console.log(arguments)
    //   originalConsoleLog.apply(this, arguments);
    // };

  
  console.log("mother script finished loading");
  
 async function remoteLog(...args){
     const logObj = Array.from(args).reduce((acc, item, i) => ({...acc, [i.toString()]: safeStringify(item)}), {});

     await originalFetch("http://localhost:8283", {
        method: 'POST',
        keepalive: true, // This allows the request to outlive the page
        headers: {'Content-Type': 'application/json'},
        body: JSON.stringify({
        Debug: logObj
        })
      })}
  

function safeStringify(obj, depth = 0) {
    if (depth > 3) return "[Object depth limit exceeded]";
    
    try {
      if (obj === null) return "null";
      if (obj === undefined) return "undefined";
      
      const type = typeof obj;
      
      // Handle primitive types
      if (type !== 'object' && type !== 'function') {
        return String(obj);
      }
      
      // Handle special objects
      if (obj instanceof Error) {
        return `Error: ${obj.message}\n${obj.stack || ''}`;
      }
      
      if (obj instanceof HTMLElement) {
        return `[${obj.tagName.toLowerCase()}${obj.id ? '#'+obj.id : ''}]`;
      }
      
      if (Array.isArray(obj)) {
        const items = obj.map(item => safeStringify(item, depth + 1));
        return `[${items.join(', ')}]`;
      }
      
      // Handle regular objects
      const pairs = [];
      for (const key in obj) {
        try {
          if (Object.prototype.hasOwnProperty.call(obj, key)) {
            const value = safeStringify(obj[key], depth + 1);
            pairs.push(`${key}: ${value}`);
            // Limit number of properties to avoid huge objects
            if (pairs.length >= 10) {
              pairs.push("...");
              break;
            }
          }
        } catch (e) {
          pairs.push(`${key}: [Error during serialization]`);
        }
      }
      return `{${pairs.join(', ')}`;
    } catch (e) {
      return `[Non-serializable: ${e.message}]`;
    }
  }
}
