function normalizeText(value) {
  return String(value ?? "").replace(/\s+/g, " ").trim();
}

const SEARCH_INPUT_HINT_PATTERN = /(?:\bkeywords?\b|搜索|搜|找货源|找工厂|关键词|商品|货源|search)/i;
const LOGIN_INPUT_HINT_PATTERN = /(?:\blogin\b|signin|sms|captcha|verify|verification|mobile|phone|passwd|password|account|member|登录|短信|验证码|手机|手机号|账号|密码)/i;
const SEARCH_SUBMIT_HINT_PATTERN = /(?:搜索|找货源|找工厂|搜一下|search)/i;
const LOGIN_SUBMIT_HINT_PATTERN = /(?:登录|注册|验证码|短信|发送验证码|获取验证码)/i;
const LOGIN_PAGE_TEXT_PATTERN = /(?:登录|验证码|手机号|短信登录|账号登录|请先登录|淘宝会员|阿里巴巴会员)/i;

function readRect(candidate) {
  return candidate?.rect ?? { x: 0, y: 0, width: 0, height: 0 };
}

function buildInputHaystack(candidate) {
  return normalizeText([
    candidate?.id,
    candidate?.name,
    candidate?.placeholder,
    candidate?.ariaLabel,
    candidate?.className,
    candidate?.autocomplete,
    candidate?.formAction,
    candidate?.title,
  ].join(" ")).toLowerCase();
}

function buildSubmitHaystack(candidate) {
  return normalizeText([
    candidate?.text,
    candidate?.value,
    candidate?.ariaLabel,
    candidate?.title,
    candidate?.name,
    candidate?.className,
    candidate?.formAction,
    candidate?.role,
    candidate?.type,
  ].join(" ")).toLowerCase();
}

export function isLikelyLoginInputCandidate(candidate) {
  return LOGIN_INPUT_HINT_PATTERN.test(buildInputHaystack(candidate));
}

export function scoreSearchInputCandidate(candidate) {
  const haystack = buildInputHaystack(candidate);
  const rect = readRect(candidate);
  let score = 0;

  if (SEARCH_INPUT_HINT_PATTERN.test(haystack)) {
    score += 160;
  }

  if (haystack.includes("keywords") || haystack.includes("keyword")) {
    score += 80;
  }

  if (candidate?.formAction && /search|offer_search/i.test(candidate.formAction)) {
    score += 60;
  }

  if (rect.width >= 280) {
    score += 30;
  }

  if (rect.y > 0 && rect.y <= 260) {
    score += 20;
  }

  if (rect.width < 140 || rect.height < 20) {
    score -= 60;
  }

  if (isLikelyLoginInputCandidate(candidate)) {
    score -= 260;
  }

  return score;
}

export function pickBestSearchInputCandidate(candidates) {
  if (!Array.isArray(candidates) || candidates.length === 0) {
    return null;
  }

  const scored = candidates
    .map((candidate) => ({ candidate, score: scoreSearchInputCandidate(candidate) }))
    .sort((left, right) => right.score - left.score);

  if ((scored[0]?.score ?? -Infinity) < 90) {
    return null;
  }

  return scored[0]?.candidate ?? null;
}

export function scoreSearchSubmitCandidate(candidate, anchorRect = null) {
  const haystack = buildSubmitHaystack(candidate);
  const rect = readRect(candidate);
  let score = 0;

  if (SEARCH_SUBMIT_HINT_PATTERN.test(haystack)) {
    score += 180;
  }

  if (candidate?.formAction && /search|offer_search/i.test(candidate.formAction)) {
    score += 60;
  }

  if (["button", "submit"].includes(String(candidate?.type ?? "").toLowerCase())) {
    score += 20;
  }

  if (String(candidate?.role ?? "").toLowerCase() === "button") {
    score += 15;
  }

  if (anchorRect) {
    const verticalDistance = Math.abs((rect.y + rect.height / 2) - (anchorRect.y + anchorRect.height / 2));
    const horizontalOffset = rect.x - (anchorRect.x + anchorRect.width);

    if (verticalDistance <= 96) {
      score += 24;
    }

    if (horizontalOffset >= -40 && horizontalOffset <= 220) {
      score += 18;
    }
  }

  if (LOGIN_SUBMIT_HINT_PATTERN.test(haystack)) {
    score -= 180;
  }

  return score;
}

export function pickBestSearchSubmitCandidate(candidates, anchorRect = null) {
  if (!Array.isArray(candidates) || candidates.length === 0) {
    return null;
  }

  const scored = candidates
    .map((candidate) => ({ candidate, score: scoreSearchSubmitCandidate(candidate, anchorRect) }))
    .sort((left, right) => right.score - left.score);

  if ((scored[0]?.score ?? -Infinity) < 100) {
    return null;
  }

  return scored[0]?.candidate ?? null;
}

export function looksLikeLoginInterstitial({ url = "", bodyText = "", inputCandidates = [] } = {}) {
  if (/login\.taobao\.com|login\.1688\.com/i.test(String(url))) {
    return true;
  }

  const normalizedBodyText = normalizeText(bodyText);
  const loginFieldCount = inputCandidates.filter((candidate) => isLikelyLoginInputCandidate(candidate)).length;

  return loginFieldCount > 0 && LOGIN_PAGE_TEXT_PATTERN.test(normalizedBodyText);
}