import { parseHTML } from "linkedom";

// thanks claude for writing this

const DOC_HTML =
  "<!DOCTYPE html><html><head></head><body><input type='hidden' name='ui_metrics' value=''></body></html>";

let innerTextPatched = false;

function patchInnerText(document) {
  if (innerTextPatched) return;
  let proto = Object.getPrototypeOf(document.createElement("div"));
  while (proto && !Object.getOwnPropertyDescriptor(proto, "innerText")) {
    proto = Object.getPrototypeOf(proto);
  }
  if (proto) {
    Object.defineProperty(proto, "innerText", {
      configurable: true,
      get() {
        return this.textContent;
      },
      set(v) {
        this.textContent = String(v);
      },
    });
    innerTextPatched = true;
  }
}

export function solveJsInstrumentation(challengeJs) {
  const { document } = parseHTML(DOC_HTML);
  patchInnerText(document);

  if (typeof document.getElementsByName !== "function") {
    document.getElementsByName = (name) => document.querySelectorAll(`[name="${name}"]`);
  }

  try {
    Object.defineProperty(document, "readyState", { configurable: true, get: () => "complete" });
  } catch {}

  document.addEventListener = (type, fn) => {
    if (type === "DOMContentLoaded") {
      try {
        fn();
      } catch {}
    }
  };
  document.removeEventListener = () => {};

  const sandboxWindow = {
    setTimeout: (fn) => {
      try {
        fn();
      } catch {}
    },
    clearTimeout: () => {},
    addEventListener: (type, fn) => {
      if (type === "DOMContentLoaded" || type === "load") {
        try {
          fn();
        } catch {}
      }
    },
    removeEventListener: () => {},
    document,
  };

  const navigator = {
    userAgent:
      "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.0.0 Safari/537.36",
    language: "en-US",
    languages: ["en-US", "en"],
    platform: "MacIntel",
    vendor: "Google Inc.",
    appName: "Netscape",
    cookieEnabled: true,
  };
  const screen = {
    width: 1512,
    height: 982,
    availWidth: 1512,
    availHeight: 944,
    colorDepth: 30,
    pixelDepth: 30,
  };
  const location = {
    href: "https://x.com/",
    protocol: "https:",
    host: "x.com",
    hostname: "x.com",
    pathname: "/",
  };
  sandboxWindow.navigator = navigator;
  sandboxWindow.screen = screen;
  sandboxWindow.location = location;

  const runner = new Function(
    "document",
    "window",
    "navigator",
    "screen",
    "location",
    "self",
    "globalThis",
    challengeJs,
  );

  runner(document, sandboxWindow, navigator, screen, location, sandboxWindow, sandboxWindow);

  const input = document.getElementsByName("ui_metrics")[0];
  const value = input?.value || null;

  if (!value) {
    throw new Error("js_instrumentation challenge produced no ui_metrics value");
  }
  if (value.startsWith("exception ")) {
    throw new Error(`js_instrumentation challenge threw: ${value}`);
  }

  return value;
}

export default solveJsInstrumentation;
