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

function truncateText(value, maxLength) {
  const normalized = normalizeSpace(value);
  if (!normalized) {
    return "";
  }

  return normalized.length <= maxLength
    ? normalized
    : `${normalized.slice(0, Math.max(0, maxLength - 1))}…`;
}

function buildSampleKey(sample) {
  return [
    normalizeSpace(sample?.title).toLowerCase(),
    normalizeSpace(sample?.rawCardText).toLowerCase(),
    (Array.isArray(sample?.highlightTexts) ? sample.highlightTexts : []).map((item) => normalizeSpace(item).toLowerCase()).join("|"),
  ].join("::");
}

export function buildKeywordHitRateFallbackSample(result) {
  const title = truncateText(result?.title, 120);
  const rawCardText = truncateText(result?.rawCardText, 320);
  const highlightTexts = (Array.isArray(result?.highlightTexts) ? result.highlightTexts : [])
    .map((item) => truncateText(item, 60))
    .filter(Boolean)
    .slice(0, 6);

  return {
    title,
    rawCardText,
    highlightTexts,
  };
}

export function collectKeywordHitRateFallbackSamples(existingSamples, pageResults, limit = 18) {
  const output = Array.isArray(existingSamples) ? [...existingSamples] : [];
  const normalizedLimit = Number.isInteger(limit) && limit > 0 ? limit : 18;
  const seen = new Set(output.map((sample) => buildSampleKey(sample)));

  for (const result of Array.isArray(pageResults) ? pageResults : []) {
    if (output.length >= normalizedLimit) {
      break;
    }

    const sample = buildKeywordHitRateFallbackSample(result);
    if (!sample.title && !sample.rawCardText && sample.highlightTexts.length === 0) {
      continue;
    }

    const key = buildSampleKey(sample);
    if (!key || seen.has(key)) {
      continue;
    }

    seen.add(key);
    output.push(sample);
  }

  return output;
}

export function countKeywordHitRateEvidenceSamples(samples) {
  return (Array.isArray(samples) ? samples : []).filter((sample) => {
    return normalizeSpace(sample?.rawCardText).length > 0
      || (Array.isArray(sample?.highlightTexts) && sample.highlightTexts.some((item) => normalizeSpace(item).length > 0));
  }).length;
}

export function shouldRunKeywordHitRateLlmFallback(options) {
  const enabled = options?.enabled !== false;
  if (!enabled) {
    return { shouldRun: false, reason: "llm_fallback_disabled" };
  }

  if (!options?.client) {
    return { shouldRun: false, reason: "llm_client_unavailable" };
  }

  const totalCount = Number(options?.totalCount ?? 0);
  if (!Number.isFinite(totalCount) || totalCount <= 0) {
    return { shouldRun: false, reason: "no_results" };
  }

  const localHitCount = Number(options?.localHitCount ?? 0);
  const localHitRate = Number(options?.localHitRate ?? 0);
  if ((Number.isFinite(localHitCount) && localHitCount > 0) || (Number.isFinite(localHitRate) && localHitRate > 0)) {
    return { shouldRun: false, reason: "local_hits_present" };
  }

  const samples = Array.isArray(options?.samples) ? options.samples : [];
  const minSampleCount = Number.isInteger(options?.minSampleCount) && options.minSampleCount > 0
    ? options.minSampleCount
    : 8;
  if (samples.length < minSampleCount) {
    return {
      shouldRun: false,
      reason: "insufficient_samples",
      sampleCount: samples.length,
      minSampleCount,
    };
  }

  const evidenceCount = countKeywordHitRateEvidenceSamples(samples);
  if (evidenceCount <= 0) {
    return {
      shouldRun: false,
      reason: "no_semantic_evidence",
      sampleCount: samples.length,
      evidenceCount,
    };
  }

  return {
    shouldRun: true,
    reason: "eligible_for_llm_fallback",
    sampleCount: samples.length,
    evidenceCount,
  };
}

export function buildKeywordHitRateFallbackSampleBlocks(sampleResults) {
  const samples = (Array.isArray(sampleResults) ? sampleResults : []).slice(0, 24);

  return samples.map((sample, index) => {
    const highlightText = Array.isArray(sample.highlightTexts) && sample.highlightTexts.length > 0
      ? sample.highlightTexts.join(" | ")
      : "无";

    return [
      `样本${index + 1}`,
      `标题: ${sample.title || "无"}`,
      `卡片全文: ${sample.rawCardText || "无"}`,
      `高亮词: ${highlightText}`,
    ].join("\n");
  }).join("\n\n");
}

export function deriveContactEnrichmentSkipReason(options) {
  if (options?.brandZeroHitStop) {
    return "brand_zero_hit_stop";
  }

  const resultCount = Number(options?.resultCount ?? 0);
  if (!Number.isFinite(resultCount) || resultCount <= 0) {
    return "no_results";
  }

  if (options?.isValidSearch || options?.shouldForceContactEnrichment) {
    return "";
  }

  return "visual_invalid_skip";
}