import { isAllowedEmbedUrl } from "./ad-guard";

const ATTR_RE = /\b(src|href)=["']([^"']+)["']/gi;
const CSS_URL_RE = /url\(\s*['"]?([^'")]+)['"]?\s*\)/gi;

function resolveRef(base: URL, ref: string): string {
  try {
    return new URL(ref, base).href;
  } catch {
    return ref;
  }
}

function assetProxyUrl(assetUrl: string, embedRef: string): string {
  return `/api/asset?u=${encodeURIComponent(assetUrl)}&ref=${encodeURIComponent(embedRef)}`;
}

export function rewriteGameHtml(html: string, pageUrl: string, embedRef: string): string {
  const base = new URL(pageUrl);

  let out = html.replace(ATTR_RE, (full, attr: string, value: string) => {
    if (value.startsWith("data:") || value.startsWith("blob:") || value.startsWith("#")) return full;
    if (value.startsWith("/api/asset")) return full;
    const absolute = resolveRef(base, value);
    if (!absolute.startsWith("http")) return full;
    return `${attr}="${assetProxyUrl(absolute, embedRef)}"`;
  });

  out = out.replace(CSS_URL_RE, (_full, value: string) => {
    if (value.startsWith("data:") || value.startsWith("/api/asset")) return _full;
    const absolute = resolveRef(base, value);
    if (!absolute.startsWith("http")) return _full;
    return `url("${assetProxyUrl(absolute, embedRef)}")`;
  });

  const runtimePatch = `<script>(function(){var R=${JSON.stringify(embedRef)};function P(u){return"/api/asset?u="+encodeURIComponent(u)+"&ref="+encodeURIComponent(R)}function W(u){return typeof u==="string"&&/^https?:\\/\\//i.test(u)?P(u):u}var sa=Element.prototype.setAttribute;Element.prototype.setAttribute=function(n,v){if((n==="src"||n==="href")&&typeof v==="string")return sa.call(this,n,W(v));return sa.call(this,n,v)};var os=Object.getOwnPropertyDescriptor(HTMLScriptElement.prototype,"src");if(os&&os.set){Object.defineProperty(HTMLScriptElement.prototype,"src",{set:function(v){os.set.call(this,W(String(v)))},get:os.get})}var f=window.fetch;window.fetch=function(i,o){var u=typeof i==="string"?i:i&&i.url;return f.call(this,u?W(u):i,o)};var xo=XMLHttpRequest.prototype.open;XMLHttpRequest.prototype.open=function(m,u){var a=[m,W(u)];for(var i=2;i<arguments.length;i++)a.push(arguments[i]);return xo.apply(this,a)}})();</script>`;

  const baseTag = `<base href="${base.origin}${base.pathname.replace(/\/[^/]*$/, "/")}">`;
  const headInject = `${baseTag}${runtimePatch}`;
  if (/<head[^>]*>/i.test(out)) return out.replace(/<head[^>]*>/i, (m) => `${m}${headInject}`);
  return `${headInject}${out}`;
}

export function proxiedEmbedUrl(embedUrl: string): string {
  if (!isAllowedEmbedUrl(embedUrl)) return embedUrl;
  return `/api/game-frame?u=${encodeURIComponent(embedUrl)}`;
}

export function isAllowedAssetProxy(assetUrl: string, embedRef: string | null): boolean {
  if (!embedRef || !isAllowedEmbedUrl(embedRef)) return false;
  try {
    const u = new URL(assetUrl);
    return u.protocol === "https:" || u.protocol === "http:";
  } catch {
    return false;
  }
}

export async function fetchProxied(url: string, timeoutMs = 25_000): Promise<Response> {
  return fetch(url, {
    headers: {
      "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
      accept: "*/*",
    },
    signal: AbortSignal.timeout(timeoutMs),
    redirect: "follow",
  });
}
