(function () {
  if (window.__mcjSmtUploadTraceInjected)
    return
  window.__mcjSmtUploadTraceInjected = true

  const EVENT_NAME = 'mcj-smt-upload-trace'
  const emit = (type, payload) => {
    try {
      window.dispatchEvent(new CustomEvent(EVENT_NAME, { detail: { type, payload } }))
    }
    catch (_) { }
  }

  const bodyToText = (body) => {
    try {
      if (!body)
        return ''
      if (typeof body === 'string')
        return body
      if (body instanceof URLSearchParams)
        return body.toString()
      if (body instanceof FormData) {
        const arr = []
        body.forEach((v, k) => {
          arr.push(`${k}=${typeof v === 'string' ? v.slice(0, 200) : '[File]'}`)
        })
        return arr.join('&')
      }
      return JSON.stringify(body)
    }
    catch (_) {
      return ''
    }
  }

  const shouldTrace = (url, method, bodyText) => {
    const u = String(url || '').toLowerCase()
    const m = String(method || '').toLowerCase()
    const b = String(bodyText || '').toLowerCase()
    return /seller-acs|aliexpress|alicdn|mtop|material|image|upload|publish/.test(u)
      || /promptimages|opttype|image|upload|material/.test(b)
      || m === 'post'
      || m === 'put'
  }

  const shouldTraceResponse = (url, responseText) => {
    const u = String(url || '').toLowerCase()
    const r = String(responseText || '').toLowerCase()
    return /seller-acs|mtop|product\.publish|material|upload|image/.test(u)
      || /promptimages|opttype|image|upload|material|success|ret/.test(r)
  }

  const installHooksOnWindow = (targetWin, frameTag) => {
    if (!targetWin || targetWin.__mcjSmtUploadTracePatched)
      return
    targetWin.__mcjSmtUploadTracePatched = true

    const rawFetch = targetWin.fetch
    targetWin.fetch = function (input, init) {
    const url = typeof input === 'string' ? input : (input && input.url) || ''
    const method = (init && init.method) || 'GET'
    const bodyText = bodyToText(init && init.body)
    if (shouldTrace(url, method, bodyText)) {
        emit('fetch:req', { frame: frameTag, url, method, body: bodyText.slice(0, 4000) })
    }
      return rawFetch.call(targetWin, input, init).then(function (res) {
        try {
          const cloned = res.clone()
          cloned.text().then(function (txt) {
            if (shouldTraceResponse(url, txt)) {
              emit('fetch:res', { frame: frameTag, url, status: res.status, text: String(txt || '').slice(0, 2000) })
            }
          }).catch(function(){})
        } catch (_) {}
        return res
      })
    }

    const rawOpen = targetWin.XMLHttpRequest.prototype.open
    const rawSend = targetWin.XMLHttpRequest.prototype.send
    targetWin.XMLHttpRequest.prototype.open = function (method, url) {
      this.__mcj_method = method
      this.__mcj_url = url
      return rawOpen.apply(this, arguments)
    }
    targetWin.XMLHttpRequest.prototype.send = function (body) {
      const url = this.__mcj_url || ''
      const method = this.__mcj_method || 'GET'
      const bodyText = bodyToText(body)
      if (shouldTrace(url, method, bodyText)) {
        emit('xhr:req', { frame: frameTag, url, method, body: bodyText.slice(0, 4000) })
      }
      this.addEventListener('load', () => {
        try {
          const txt = this.responseText || ''
          if (shouldTraceResponse(url, txt)) {
            emit('xhr:res', { frame: frameTag, url, status: this.status, text: String(txt).slice(0, 2000) })
          }
        } catch (_) {}
      })
      return rawSend.call(this, body)
    }
  }

  const installFrameHooks = () => {
    const iframes = Array.from(document.querySelectorAll('iframe'))
    for (const iframe of iframes) {
      try {
        const w = iframe.contentWindow
        if (!w)
          continue
        // 仅同源 frame 可访问
        const frameTag = iframe.src || 'about:blank-frame'
        installHooksOnWindow(w, frameTag)
      }
      catch (_) {
        // 跨域 frame 无法注入，忽略
      }
    }
  }

  installHooksOnWindow(window, 'top')
  installFrameHooks()
  setInterval(installFrameHooks, 1500)

  emit('hook:ready', { ok: true, frame: 'top' })
  // 额外告知已尝试安装 frame hooks
  emit('hook:frames-scan', { count: document.querySelectorAll('iframe').length })
})()

