

const SSO_LOGIN_JSONP =
  'https://sso.bidcenter.com.cn/Inc/member_login_crs_domain.ashx'

const TOKEN_SESSION_KEY = 'bidcenter_search_interface_token'
/** 与采招网页面一致：JSONP 登录成功但未下发 token 时，依赖浏览器携带的采招网 cookie 调搜索接口 */
const JSONP_MEMBER_SESSION_KEY = 'bidcenter_member_jsonp_session'

/**
 * @param {string} username
 * @param {string} password
 * @returns {Promise<object>}
 */
export function loginBidcenterMemberJsonp(username, password) {
  const name = (username || '').trim()
  const pwd = (password || '').trim()
  if (!name || !pwd) {
    return Promise.reject(new Error(''))
  }

  const cb = `__bidcenterLogin_${Date.now()}_${Math.random().toString(36).slice(2, 9)}`
  return new Promise((resolve, reject) => {
    const timer = setTimeout(() => {
      cleanup()
      reject(new Error(''))
    }, 25000)

    let script
    function cleanup() {
      clearTimeout(timer)
      try {
        delete window[cb]
      } catch (e) { /* ignore */ }
      if (script && script.parentNode) {
        script.parentNode.removeChild(script)
      }
    }

    window[cb] = (data) => {
      cleanup()
      resolve(data)
    }

    script = document.createElement('script')
    script.onerror = () => {
      cleanup()
      reject(new Error(''))
    }
    // 与站点 $.getJSON 拼接一致：callback 为时间戳，jsoncallback 为 JSONP 函数名（见 member_login_crs_domain 调用方式）
    const srctime = Date.now()
    const qs = [
      `name=${encodeURIComponent(name)}`,
      `d=${srctime}`,
      `pwd=${encodeURIComponent(pwd)}`,
      'auto=0',
      'run=1',
      `callback=${srctime}`,
      `jsoncallback=${encodeURIComponent(cb)}`
    ].join('&')
    script.src = `${SSO_LOGIN_JSONP}?${qs}`
    document.body.appendChild(script)
  })
}

/**
 * �ӵ�¼ JSON �н��� interface �����õ� token
 * @param {object} r
 * @returns {string}
 */
function looksLikeSearchToken(s) {
  const t = String(s || '').trim()
  if (t.length < 16) return false
  // 采招网 token 多为较长十六进制 / Base64 风格，排除明显非 token 短句
  if (t.length > 2048) return false
  return /^[\w+/=\-:.]+$/i.test(t)
}

/**
 * 深度遍历对象，按字段名或值形态猜测搜索接口 token（各版本字段名不一致）
 * @param {object} root
 * @param {number} depth
 * @returns {string}
 */
export function pickTokenFromLoginResponseDeep(root, depth = 0) {
  if (!root || typeof root !== 'object' || depth > 8) return ''
  const preferNames =
    /^(token|interface_token|search_token|user_token|u_token|usertoken|access_token|loginkey|login_token|session_token|authkey|auth_key)$/i
  const maybeNames = /token|loginkey|session|authkey/i

  /** @type {string[]} */
  const candidates = []

  const visit = (obj, d) => {
    if (!obj || typeof obj !== 'object' || d > 8) return ''
    for (const k of Object.keys(obj)) {
      const v = obj[k]
      if (v == null) continue
      if (typeof v === 'string') {
        const t = v.trim()
        if (!t) continue
        if (preferNames.test(k) && looksLikeSearchToken(t)) return t
        if (maybeNames.test(k) && looksLikeSearchToken(t)) candidates.push(t)
      } else if (typeof v === 'object') {
        const nested = visit(v, d + 1)
        if (nested) return nested
      }
    }
    return ''
  }

  const direct = visit(root, depth)
  if (direct) return direct
  if (candidates.length) return candidates[0]

  const scanValues = (obj, d) => {
    if (!obj || typeof obj !== 'object' || d > 6) return ''
    for (const v of Object.values(obj)) {
      if (typeof v === 'string' && looksLikeSearchToken(v)) return v.trim()
      if (typeof v === 'object' && v) {
        const got = scanValues(v, d + 1)
        if (got) return got
      }
    }
    return ''
  }
  return scanValues(root, depth)
}

export function pickTokenFromLoginResponse(r) {
  if (!r || typeof r !== 'object') return ''
  const tryKeys = (obj) => {
    if (!obj || typeof obj !== 'object') return ''
    const keys = [
      'token',
      'interface_token',
      'search_token',
      'u_token',
      'user_token',
      'usertoken',
      'access_token',
      'loginkey',
      'login_token',
      'session_token',
      't',
      'key'
    ]
    for (const k of keys) {
      const v = obj[k]
      if (v != null && String(v).trim().length > 0) {
        return String(v).trim()
      }
    }
    return ''
  }
  return (
    tryKeys(r) ||
    tryKeys(r.data) ||
    tryKeys(r.user) ||
    tryKeys(r.result) ||
    tryKeys(r.Result) ||
    pickTokenFromLoginResponseDeep(r)
  )
}

/**
 * ��¼�ӿ������� next_token�����ڽ��������״������������һ�£�
 * @param {object} r
 * @returns {string}
 */
export function pickNextTokenFromLoginResponse(r) {
  if (!r || typeof r !== 'object') return ''
  const tryKeys = (obj) => {
    if (!obj || typeof obj !== 'object') return ''
    for (const k of ['next_token', 'nextToken', 'nexttoken']) {
      const v = obj[k]
      if (v != null && String(v).trim().length > 0) {
        return String(v).trim()
      }
    }
    return ''
  }
  return tryKeys(r) || tryKeys(r.data) || ''
}

export function getStoredBidcenterToken() {
  try {
    return sessionStorage.getItem(TOKEN_SESSION_KEY) || ''
  } catch (e) {
    return ''
  }
}

export function setStoredBidcenterToken(token) {
  try {
    if (token && String(token).trim()) {
      sessionStorage.setItem(TOKEN_SESSION_KEY, String(token).trim())
    } else {
      sessionStorage.removeItem(TOKEN_SESSION_KEY)
    }
  } catch (e) { /* ignore */ }
}

export function clearStoredBidcenterToken() {
  setStoredBidcenterToken('')
}

export function setBidcenterJsonpMemberSession(active) {
  try {
    if (active) {
      sessionStorage.setItem(JSONP_MEMBER_SESSION_KEY, '1')
    } else {
      sessionStorage.removeItem(JSONP_MEMBER_SESSION_KEY)
    }
  } catch (e) {
    /* ignore */
  }
}

export function getBidcenterJsonpMemberSession() {
  try {
    return sessionStorage.getItem(JSONP_MEMBER_SESSION_KEY) === '1'
  } catch (e) {
    return false
  }
}
