/** Remove marketing preheader blocks before display (bluemonday strips display:none). */

const HIDDEN_STYLE =
  /display\s*:\s*none|mso-hide\s*:\s*all|max-height\s*:\s*0|opacity\s*:\s*0|visibility\s*:\s*hidden/i

const HIDDEN_CLASS = /mcnPreviewText|preheader|preview-text/i

const INVISIBLE_RUN = /[\u034f\u200b-\u200f\ufeff\u00a0]{4,}/g

function hasSignificantChildElements(el: Element): boolean {
  for (const child of el.children) {
    const tag = child.tagName.toLowerCase()
    if (tag === "br" || tag === "wbr" || tag === "hr") continue
    return true
  }
  return false
}

function shouldStripElement(el: Element): boolean {
  if (el.hasAttribute("hidden")) return true
  if (el.getAttribute("aria-hidden") === "true") return true
  const cls = el.className?.toString() ?? ""
  if (HIDDEN_CLASS.test(cls)) return true
  const style = el.getAttribute("style") ?? ""
  if (!style) return false
  const compact = style.replace(/\s+/g, "")
  if (
    HIDDEN_STYLE.test(style) ||
    (compact.includes("overflow:hidden") && /max-height\s*:\s*0/.test(style))
  ) {
    return true
  }
  if (/font-size\s*:\s*0/i.test(style) && !hasSignificantChildElements(el)) {
    return true
  }
  return false
}

export function stripHiddenEmailHtml(html: string): string {
  if (!html.trim() || typeof DOMParser === "undefined") {
    return html
  }
  try {
    const doc = new DOMParser().parseFromString(html, "text/html")
    const remove: Element[] = []
    doc.body.querySelectorAll("*").forEach((el) => {
      if (shouldStripElement(el)) remove.push(el)
    })
    for (const el of remove) el.remove()
    return doc.body.innerHTML
  } catch {
    return html
  }
}

/** Strip invisible padding; keep line breaks (do not collapse plain-text quotes). */
export function stripInvisibleTextRuns(text: string): string {
  return text
    .replace(INVISIBLE_RUN, " ")
    .split("\n")
    .map((line) => line.replace(/[^\S\n]+/g, " ").trimEnd())
    .join("\n")
    .replace(/\n{3,}/g, "\n\n")
    .trim()
}
