(() => {
  if (window.__MMW_ADMIN_PAGE_PROBE__) return;
  window.__MMW_ADMIN_PAGE_PROBE__ = true;
  if (isProbeBlockedHost(location.hostname)) return;

  const ACTION_LOG = "MMW_ADMIN_PAGE_PROBE_LOG";
  const ACTION_CONFIG = "MMW_ADMIN_PAGE_PROBE_CONFIG";
  const MAX_EVENTS = 2600;
  const MAX_REFERENCE_EVENTS = 2200;
  const MAX_STRING = 4000;
  const MAX_ARRAY = 80;
  const MAX_KEYS = 120;
  const MAX_DEPTH = 14;
  const MIN_LOG_GAP_MS = 250;
  const MAX_LOGS_PER_MINUTE = 240;
  const MAX_REFERENCE_LOGS_PER_MINUTE = 1200;
  const SENSITIVE_KEY_RE = /token|authorization|cookie|password|passwd|secret|session|csrf|credential|access[_-]?key|refresh[_-]?key/i;
  const QIANCHUAN_CREATE_RE = /(^|\.)qianchuan\.jinritemai\.com$/i;
  const QIANCHUAN_CREATE_PATH_RE = /\/ad\/api\/creation\/v1\/ad\/create\b/i;
  const QIANCHUAN_API_RE = /(^|\.)qianchuan\.jinritemai\.com$|(^|\.)jinritemai\.com$|(^|\.)oceanengine\.com$|(^|\.)byteadverts\.com$|(^|\.)bytedance\.com$|(^|\.)toutiao\.com$|(^|\.)douyin\.com$|(^|\.)zijieapi\.com$/i;
  const QIANCHUAN_MATERIAL_PATH_RE = /\/.*(?:upload|material|creative|video|image|media|asset|file|tos|aweme|toutiao|template|title).*/i;
  const SENSITIVE_QUERY_KEYS = new Set(["msToken", "a_bogus", "verifyFp", "fp", "verify_fingerprint", "x-bogus"]);

  let enabled = false;
  let referenceCapture = normalizeReferenceCapture();
  let seq = 0;
  let referenceSeq = 0;
  let lastLogAt = 0;
  let lastReferenceLogAt = 0;
  let hooksInstalled = false;
  const minuteWindow = [];
  const referenceMinuteWindow = [];

  window.addEventListener("message", (event) => {
    if (event.source !== window) return;
    const data = event.data;
    if (!data || data.action !== ACTION_CONFIG) return;
    enabled = data.enabled === true;
    referenceCapture = normalizeReferenceCapture(data.referenceCapture);
    if (enabled) ensureProbeHooks();
  });

  function ensureProbeHooks() {
    if (hooksInstalled) return;
    hooksInstalled = true;
    patchFetch();
    patchXhr();
    patchPostMessage();
    patchStorage();
    observeReferenceHooks();
  }

  function patchFetch() {
    const nativeFetch = window.fetch;
    if (typeof nativeFetch !== "function" || nativeFetch.__mmwAdminProbePatched) return;

    const patchedFetch = async function(input, init = {}) {
      if (!enabled) return nativeFetch.apply(this, arguments);
      const startedAt = Date.now();
      const request = summarizeFetchInput(input, init);
      captureFetchRequestBody(input, init, request);
      try {
        const response = await nativeFetch.apply(this, arguments);
        summarizeFetchResponse(response, request).then((summary) => {
          const matched = summary.referenceMatch?.matched === true;
          const reserved = matched ? reserveReferenceLogSlot() : reserveProbeLogSlot();
          if (!reserved) return;
          emit(matched ? "reference-fetch" : "fetch", { request, response: summary, durationMs: Date.now() - startedAt }, "info", true);
        });
        return response;
      } catch (error) {
        const logReserved = reserveProbeLogSlot();
        if (logReserved) emit("fetch-error", {
          request,
          durationMs: Date.now() - startedAt,
          error: error?.message || String(error)
        }, "error", true);
        throw error;
      }
    };

    patchedFetch.__mmwAdminProbePatched = true;
    window.fetch = patchedFetch;
  }

  function patchXhr() {
    const proto = window.XMLHttpRequest?.prototype;
    if (!proto || proto.__mmwAdminProbePatched) return;

    const nativeOpen = proto.open;
    const nativeSend = proto.send;
    const nativeSetRequestHeader = proto.setRequestHeader;

    proto.open = function(method, url) {
      this.__mmwAdminProbe = {
        method: String(method || "GET").toUpperCase(),
        url: String(url || ""),
        headers: {},
        startedAt: 0
      };
      return nativeOpen.apply(this, arguments);
    };

    proto.setRequestHeader = function(name, value) {
      if (this.__mmwAdminProbe && name) this.__mmwAdminProbe.headers[name] = value;
      return nativeSetRequestHeader.apply(this, arguments);
    };

    proto.send = function(body) {
      if (!enabled || !this.__mmwAdminProbe) return nativeSend.apply(this, arguments);
      const meta = this.__mmwAdminProbe;
      meta.startedAt = Date.now();
      meta.body = summarizeBody(body);
      emitTargetRequestBody("xhr", {
        method: meta.method,
        url: meta.url,
        headers: sanitizeValue(meta.headers),
        body: meta.body
      });
      this.addEventListener("loadend", () => {
        const response = summarizeXhrResponse(this, meta);
        const matched = response.referenceMatch?.matched === true;
        const logReserved = matched ? reserveReferenceLogSlot() : reserveProbeLogSlot();
        if (!logReserved) return;
        emit(matched ? "reference-xhr" : "xhr", {
          request: {
            method: meta.method,
            url: meta.url,
            headers: sanitizeValue(meta.headers),
            body: meta.body
          },
          response,
          durationMs: Date.now() - meta.startedAt
        }, "info", true);
      }, { once: true });
      return nativeSend.apply(this, arguments);
    };

    proto.__mmwAdminProbePatched = true;
  }

  function patchPostMessage() {
    const nativePostMessage = window.postMessage;
    if (typeof nativePostMessage !== "function" || nativePostMessage.__mmwAdminProbePatched) return;

    const patchedPostMessage = function(message, targetOrigin, transfer) {
      if (enabled && !isProbeMessage(message)) {
        const match = matchReferenceCapture({
          kind: "postMessage",
          body: safeStringify(message),
          message
        });
        const matched = match.matched === true;
        const reserved = matched ? reserveReferenceLogSlot() : reserveProbeLogSlot();
        if (reserved) emit(matched ? "reference-postMessage" : "postMessage", {
          targetOrigin: String(targetOrigin || ""),
          referenceMatch: matched ? match : undefined,
          message: sanitizeValue(message)
        }, "info", true);
      }
      return nativePostMessage.apply(this, arguments);
    };

    patchedPostMessage.__mmwAdminProbePatched = true;
    window.postMessage = patchedPostMessage;
  }

  function patchStorage() {
    const proto = window.Storage?.prototype;
    if (!proto || proto.__mmwAdminProbeStoragePatched) return;
    const nativeSetItem = proto.setItem;
    const nativeRemoveItem = proto.removeItem;
    const nativeClear = proto.clear;

    proto.setItem = function(key, value) {
      const result = nativeSetItem.apply(this, arguments);
      emitStorageChange("storage-set", this, key, value);
      return result;
    };

    proto.removeItem = function(key) {
      const result = nativeRemoveItem.apply(this, arguments);
      emitStorageChange("storage-remove", this, key, "");
      return result;
    };

    proto.clear = function() {
      const result = nativeClear.apply(this, arguments);
      emitStorageChange("storage-clear", this, "*", "");
      return result;
    };

    proto.__mmwAdminProbeStoragePatched = true;
  }

  function emitStorageChange(eventName, storage, key, value) {
    if (!enabled || !referenceCapture.enabled) return;
    const store = storage === window.localStorage ? "localStorage" : storage === window.sessionStorage ? "sessionStorage" : "storage";
    const match = matchReferenceCapture({
      kind: "storage",
      storageKey: key,
      body: `${key || ""} ${String(value || "")}`
    });
    if (!match.matched || !reserveReferenceLogSlot()) return;
    emit(`reference-${eventName}`, {
      store,
      key: String(key || ""),
      value: summarizeTextBody(String(value || ""), ""),
      referenceMatch: match
    }, "info", true);
  }

  function observeReferenceHooks() {
    if (!window.MutationObserver || !document.documentElement) return;
    const observer = new MutationObserver((mutations) => {
      if (!enabled || !referenceCapture.enabled) return;
      for (const mutation of mutations) {
        for (const node of mutation.addedNodes || []) inspectAddedReferenceNode(node);
      }
    });
    observer.observe(document.documentElement, { childList: true, subtree: true });
  }

  function inspectAddedReferenceNode(node) {
    if (!node || node.nodeType !== 1) return;
    const candidates = [node];
    try {
      candidates.push(...Array.from(node.querySelectorAll?.(".hook,[class*='hook'],[data-url]") || []).slice(0, 12));
    } catch {}
    for (const item of candidates) {
      if (!isReferenceHookNode(item)) continue;
      const text = String(item.textContent || "");
      const dataUrl = String(item.getAttribute?.("data-url") || "");
      const match = matchReferenceCapture({
        kind: "dom",
        url: dataUrl,
        body: `${item.className || ""} ${dataUrl} ${text.slice(0, 4000)}`
      });
      if (!match.matched || !reserveReferenceLogSlot()) continue;
      emit("reference-dom-hook", {
        tag: String(item.tagName || "").toLowerCase(),
        className: String(item.className || ""),
        dataUrl,
        textLength: text.length,
        textSample: summarizeTextBody(decodeMaybeUri(text).slice(0, 2200), ""),
        referenceMatch: match
      }, "info", true);
    }
  }

  function isReferenceHookNode(node) {
    const className = String(node?.className || "");
    const dataUrl = String(node?.getAttribute?.("data-url") || "");
    if (/\bhook(_data|_detail|_pc|_skulist|_confirm)?\b/i.test(className)) return true;
    if (referenceCapture.hookSelectors.some((selector) => {
      try {
        return node.matches?.(selector);
      } catch {
        return false;
      }
    })) return true;
    return Boolean(dataUrl && matchReferenceCapture({ kind: "dom", url: dataUrl }).matched);
  }

  function summarizeFetchInput(input, init) {
    const request = input instanceof Request ? input : null;
    const headers = {
      ...(request ? headersToObject(request.headers) : {}),
      ...headersToObject(init?.headers)
    };
    return {
      method: String(init?.method || request?.method || "GET").toUpperCase(),
      url: String(request?.url || input || ""),
      headers: sanitizeValue(headers),
      body: summarizeBody(init?.body)
    };
  }

  function captureFetchRequestBody(input, init, request) {
    const capture = classifyQianchuanCapture(request?.url, request);
    if (!capture) return;
    if (init && Object.prototype.hasOwnProperty.call(init, "body")) {
      emitTargetRequestBody("fetch", request, capture);
      return;
    }
    if (!(input instanceof Request)) {
      emitTargetRequestBody("fetch", request, capture);
      return;
    }
    try {
      input.clone().text().then((text) => {
        emitTargetRequestBody("fetch", {
          ...request,
          body: summarizeTextBody(text, request.headers?.["content-type"] || request.headers?.["Content-Type"] || "")
        }, capture);
      }).catch(() => emitTargetRequestBody("fetch", request, capture));
    } catch {
      emitTargetRequestBody("fetch", request, capture);
    }
  }

  function emitTargetRequestBody(transport, request, capture = "") {
    const captureName = capture || classifyQianchuanCapture(request?.url, request);
    if (!captureName) return;
    emit("reference-request-body", {
      capture: captureName,
      transport,
      request: {
        method: String(request?.method || "GET").toUpperCase(),
        url: sanitizeUrlForLog(request?.url || ""),
        headers: sanitizeValue(request?.headers || {}),
        body: request?.body ?? null
      }
    }, "info", true);
  }

  function classifyQianchuanCapture(url, request = {}) {
    try {
      const parsed = new URL(String(url || ""), location.href);
      if (QIANCHUAN_CREATE_RE.test(parsed.hostname) && QIANCHUAN_CREATE_PATH_RE.test(parsed.pathname)) {
        return "qianchuan-ad-create";
      }
      if (!QIANCHUAN_API_RE.test(parsed.hostname)) return "";
      const method = String(request?.method || "GET").toUpperCase();
      if (method === "GET" || method === "HEAD") return "";
      const body = request?.body;
      if (isUploadLikeBody(body) || QIANCHUAN_MATERIAL_PATH_RE.test(parsed.pathname)) {
        return "qianchuan-material-upload";
      }
      return "";
    } catch {
      return "";
    }
  }

  function shouldCaptureRequestBody(url) {
    return Boolean(classifyQianchuanCapture(url));
  }

  function isUploadLikeBody(body) {
    if (!body) return false;
    if (body?.type === "FormData") return hasFileLikeValue(body.value);
    if (typeof FormData !== "undefined" && body instanceof FormData) {
      for (const value of body.values()) {
        if (typeof File !== "undefined" && value instanceof File) return true;
        if (typeof Blob !== "undefined" && value instanceof Blob) return true;
      }
      return false;
    }
    return hasFileLikeValue(body);
  }

  function hasFileLikeValue(value, depth = 0) {
    if (!value || depth > 5) return false;
    if (typeof File !== "undefined" && value instanceof File) return true;
    if (typeof Blob !== "undefined" && value instanceof Blob) return true;
    if (typeof value !== "object") return false;
    if (value.file && (value.size || value.type)) return true;
    if (Array.isArray(value)) return value.some((item) => hasFileLikeValue(item, depth + 1));
    return Object.values(value).some((item) => hasFileLikeValue(item, depth + 1));
  }

  async function summarizeFetchResponse(response, request) {
    const summary = {
      url: response?.url || "",
      status: response?.status,
      ok: response?.ok,
      statusText: response?.statusText || "",
      contentType: response?.headers?.get?.("content-type") || ""
    };
    if (!shouldReadResponseText(summary.contentType)) {
      summary.body = `[${summary.contentType || "non-text"} response]`;
      summary.referenceMatch = matchReferenceCapture({
        kind: "fetch",
        url: summary.url || request?.url || ""
      });
      return summary;
    }
    try {
      const text = await response.clone().text();
      summary.body = summarizeTextBody(text, summary.contentType);
      summary.referenceMatch = matchReferenceCapture({
        kind: "fetch",
        url: summary.url || request?.url || "",
        body: text
      });
    } catch (error) {
      summary.bodyError = error?.message || String(error);
      summary.referenceMatch = matchReferenceCapture({
        kind: "fetch",
        url: summary.url || request?.url || ""
      });
    }
    return summary;
  }

  function summarizeXhrResponse(xhr, request) {
    const contentType = xhr.getResponseHeader?.("content-type") || "";
    const summary = {
      url: xhr.responseURL || "",
      status: xhr.status,
      statusText: xhr.statusText || "",
      contentType
    };
    if (!shouldReadResponseText(contentType)) {
      summary.body = `[${contentType || xhr.responseType || "non-text"} response]`;
      summary.referenceMatch = matchReferenceCapture({
        kind: "xhr",
        url: summary.url || request?.url || ""
      });
      return summary;
    }
    try {
      if (!xhr.responseType || xhr.responseType === "text" || xhr.responseType === "json") {
        const rawBody = xhr.responseType === "json" ? safeStringify(xhr.response) : String(xhr.responseText || "");
        summary.body = xhr.responseType === "json"
          ? sanitizeValue(xhr.response)
          : summarizeTextBody(rawBody, contentType);
        summary.referenceMatch = matchReferenceCapture({
          kind: "xhr",
          url: summary.url || request?.url || "",
          body: rawBody
        });
      } else {
        summary.body = `[${xhr.responseType || "binary"} response]`;
        summary.referenceMatch = matchReferenceCapture({
          kind: "xhr",
          url: summary.url || request?.url || ""
        });
      }
    } catch (error) {
      summary.bodyError = error?.message || String(error);
      summary.referenceMatch = matchReferenceCapture({
        kind: "xhr",
        url: summary.url || request?.url || ""
      });
    }
    return summary;
  }

  function shouldReadResponseText(contentType) {
    const text = String(contentType || "").toLowerCase();
    return !text || /json|text|javascript|xml|html|x-www-form-urlencoded/.test(text);
  }

  function summarizeBody(body) {
    if (body === undefined || body === null || body === "") return null;
    if (typeof FormData !== "undefined" && body instanceof FormData) {
      const result = {};
      let count = 0;
      for (const [key, value] of body.entries()) {
        if (count >= MAX_KEYS) break;
        result[key] = value instanceof File
          ? { file: value.name, type: value.type, size: value.size }
          : sanitizeValue(value);
        count += 1;
      }
      return { type: "FormData", value: result };
    }
    if (typeof URLSearchParams !== "undefined" && body instanceof URLSearchParams) {
      return { type: "URLSearchParams", value: sanitizeValue(Object.fromEntries(body.entries())) };
    }
    if (typeof body === "string") return summarizeTextBody(body, "");
    if (body instanceof Blob) return { type: "Blob", size: body.size, mime: body.type };
    if (body instanceof ArrayBuffer) return { type: "ArrayBuffer", bytes: body.byteLength };
    if (ArrayBuffer.isView(body)) return { type: body.constructor?.name || "TypedArray", bytes: body.byteLength };
    return sanitizeValue(body);
  }

  function summarizeTextBody(text, contentType) {
    const value = String(text || "");
    const trimmed = value.trim();
    if (trimmed && (contentType.includes("json") || /^[\[{]/.test(trimmed))) {
      try {
        return sanitizeValue(JSON.parse(trimmed));
      } catch {}
    }
    return truncate(value, MAX_STRING);
  }

  function headersToObject(headers) {
    if (!headers) return {};
    try {
      if (headers instanceof Headers) return Object.fromEntries(headers.entries());
      if (Array.isArray(headers)) return Object.fromEntries(headers);
      if (typeof headers === "object") return { ...headers };
    } catch {}
    return {};
  }

  function sanitizeValue(value, depth = 0, key = "") {
    if (SENSITIVE_KEY_RE.test(key)) return "[redacted]";
    if (value === null || value === undefined) return value;
    if (typeof value === "string") return truncate(value, MAX_STRING);
    if (typeof value === "number" || typeof value === "boolean") return value;
    if (typeof value === "bigint") return String(value);
    if (typeof value === "function") return "[function]";
    if (depth >= MAX_DEPTH) return "[depth-limit]";
    if (Array.isArray(value)) {
      const items = value.slice(0, MAX_ARRAY).map((item) => sanitizeValue(item, depth + 1, key));
      if (value.length > MAX_ARRAY) items.push(`[${value.length - MAX_ARRAY} more]`);
      return items;
    }
    if (typeof value === "object") {
      const result = {};
      for (const [itemKey, itemValue] of Object.entries(value).slice(0, MAX_KEYS)) {
        result[itemKey] = sanitizeValue(itemValue, depth + 1, itemKey);
      }
      return result;
    }
    return String(value);
  }

  function normalizeReferenceCapture(config = {}) {
    const rules = config?.rules && typeof config.rules === "object" ? config.rules : {};
    return {
      enabled: config?.enabled === true,
      urlKeywords: cleanTermList(rules.urlKeywords, 120),
      bodyKeywords: cleanTermList(rules.bodyKeywords, 160),
      messageKeywords: cleanTermList(rules.messageKeywords, 120),
      storageKeys: cleanTermList(rules.storageKeys, 80),
      hookSelectors: cleanTermList(rules.hookSelectors, 60),
      manifestMatches: cleanTermList(rules.manifestMatches, 80)
    };
  }

  function matchReferenceCapture(input = {}) {
    if (!referenceCapture.enabled) return { matched: false };
    const url = String(input.url || "");
    const body = String(input.body || "");
    const storageKey = String(input.storageKey || "");
    const messageText = input.message ? safeStringify(input.message) : body;
    const hits = [];

    collectTermHits("url", referenceCapture.urlKeywords, url, hits);
    collectTermHits("body", referenceCapture.bodyKeywords, body, hits);
    collectTermHits("message", referenceCapture.messageKeywords, messageText, hits);
    collectTermHits("storage", referenceCapture.storageKeys, storageKey, hits);

    if (!hits.length && input.kind !== "postMessage") {
      collectTermHits("manifest", referenceCapture.manifestMatches, url, hits);
    }

    return {
      matched: hits.length > 0,
      kind: String(input.kind || ""),
      hits: hits.slice(0, 12)
    };
  }

  function collectTermHits(type, terms, text, hits) {
    const target = String(text || "").toLowerCase();
    if (!target) return;
    for (const term of terms) {
      const needle = String(term || "").toLowerCase();
      if (!needle) continue;
      if (target.includes(needle)) hits.push({ type, term });
      if (hits.length >= 16) return;
    }
  }

  function cleanTermList(value, limit) {
    const source = Array.isArray(value) ? value : [];
    const result = [];
    const seen = new Set();
    for (const item of source) {
      const text = String(item || "").trim();
      const key = text.toLowerCase();
      if (!text || seen.has(key)) continue;
      seen.add(key);
      result.push(text.slice(0, 240));
      if (result.length >= limit) break;
    }
    return result;
  }

  function safeStringify(value) {
    try {
      return typeof value === "string" ? value : JSON.stringify(value);
    } catch {
      return String(value || "");
    }
  }

  function decodeMaybeUri(value) {
    const text = String(value || "");
    try {
      return decodeURIComponent(text);
    } catch {
      return text;
    }
  }

  function sanitizeUrlForLog(url) {
    try {
      const parsed = new URL(String(url || ""), location.href);
      for (const key of Array.from(parsed.searchParams.keys())) {
        if (SENSITIVE_QUERY_KEYS.has(key) || SENSITIVE_KEY_RE.test(key)) parsed.searchParams.set(key, "[redacted]");
      }
      return parsed.toString();
    } catch {
      return String(url || "").replace(/([?&](?:msToken|a_bogus|verifyFp|fp|verify_fingerprint|x-bogus)=)[^&]+/gi, "$1[redacted]");
    }
  }

  function emit(event, payload, level = "info", reserved = false) {
    if (!enabled || seq >= MAX_EVENTS) return;
    if (!reserved && !reserveProbeLogSlot()) return;
    seq += 1;
    window.postMessage({
      action: ACTION_LOG,
      data: {
        event,
        level,
        seq,
        href: location.href,
        payload: sanitizeValue(payload)
      }
    }, "*");
  }

  function reserveProbeLogSlot() {
    if (!enabled || seq >= MAX_EVENTS) return false;
    const now = Date.now();
    if (now - lastLogAt < MIN_LOG_GAP_MS) return false;
    lastLogAt = now;
    while (minuteWindow.length && now - minuteWindow[0] > 60000) minuteWindow.shift();
    if (minuteWindow.length >= MAX_LOGS_PER_MINUTE) return false;
    minuteWindow.push(now);
    return true;
  }

  function reserveReferenceLogSlot() {
    if (!enabled || !referenceCapture.enabled || referenceSeq >= MAX_REFERENCE_EVENTS || seq >= MAX_EVENTS) return false;
    const now = Date.now();
    if (now - lastReferenceLogAt < 80) return false;
    lastReferenceLogAt = now;
    while (referenceMinuteWindow.length && now - referenceMinuteWindow[0] > 60000) referenceMinuteWindow.shift();
    if (referenceMinuteWindow.length >= MAX_REFERENCE_LOGS_PER_MINUTE) return false;
    referenceMinuteWindow.push(now);
    referenceSeq += 1;
    return true;
  }

  function isProbeMessage(message) {
    return message && typeof message === "object" && (
      message.action === ACTION_LOG || message.action === ACTION_CONFIG
    );
  }

  function truncate(value, max) {
    const text = String(value || "");
    return text.length > max ? `${text.slice(0, max)}...[truncated ${text.length - max}]` : text;
  }

  function isProbeBlockedHost(hostname) {
    const host = String(hostname || "").toLowerCase();
    return /(^|\.)pay\.weixin\.qq\.com$/.test(host)
      || /(^|\.)wxpay\.qq\.com$/.test(host)
      || /(^|\.)alipay\.com$/.test(host)
      || /(^|\.)alipayobjects\.com$/.test(host)
      || /(^|\.)paypal\.com$/.test(host);
  }
})();
