/** Hauteur utile du corps d’un iframe d’aperçu mail (évite le scrollHeight fantôme). */

export const EMAIL_PREVIEW_MIN_IFRAME_HEIGHT = 120
export const EMAIL_PREVIEW_HEIGHT_BUFFER = 8
export const EMAIL_PREVIEW_MEASURE_ROOT_SELECTOR = "[data-ultimail-measure-root]"

const CONTENT_MEASURE_SELECTORS =
  "p,div,span,td,th,li,h1,h2,h3,h4,h5,h6,table,img,blockquote,pre,hr,a,section,article,footer,header"

function roundPreviewHeight(raw: number): number {
  return Math.max(
    EMAIL_PREVIEW_MIN_IFRAME_HEIGHT,
    Math.ceil(raw / 4) * 4 + EMAIL_PREVIEW_HEIGHT_BUFFER
  )
}

export function resolveEmailPreviewMeasureRoot(doc: Document): HTMLElement {
  return (
    doc.querySelector<HTMLElement>(EMAIL_PREVIEW_MEASURE_ROOT_SELECTOR) ??
    doc.body
  )
}

export function measureEmailPreviewIframeHeight(doc: Document): number {
  const root = resolveEmailPreviewMeasureRoot(doc)
  const view = doc.defaultView
  if (!root || !view) return EMAIL_PREVIEW_MIN_IFRAME_HEIGHT

  const scrollEstimate = Math.max(
    root.scrollHeight,
    root.offsetHeight,
    doc.body?.scrollHeight ?? 0,
    doc.body?.offsetHeight ?? 0,
    doc.documentElement?.scrollHeight ?? 0,
    doc.documentElement?.offsetHeight ?? 0
  )

  const rootTop = root.getBoundingClientRect().top
  let contentBottom = rootTop

  for (const el of root.querySelectorAll(CONTENT_MEASURE_SELECTORS)) {
    const cs = view.getComputedStyle(el)
    if (cs.display === "none" || cs.visibility === "hidden") continue
    const rect = el.getBoundingClientRect()
    if (rect.height < 1 && rect.width < 1) continue
    contentBottom = Math.max(contentBottom, rect.bottom)
  }

  const hasVisibleLayout = contentBottom > rootTop + 8
  if (hasVisibleLayout) {
    const boundEstimate = Math.ceil(contentBottom - rootTop) + 4
    // Prefer bounds over scrollHeight (phantom tail in newsletters), but never
    // shrink below scroll when inline/absolute content extends past last block.
    const contentHeight = Math.max(
      boundEstimate,
      Math.min(scrollEstimate, boundEstimate + 48)
    )
    return roundPreviewHeight(contentHeight)
  }

  return roundPreviewHeight(scrollEstimate + 2)
}
