import type { DocPageLayout } from "@/lib/drive/doc-page-setup"
import { buildParagraphStylesCss } from "@/lib/drive/docs-paragraph-styles-css"
import type { DocParagraphStylesCatalog } from "@/lib/drive/docs-paragraph-styles"
import type { DocsExportSnapshot } from "@/lib/drive/docs-export-snapshot"

const PRINT_STYLE_ID = "docs-print-dynamic-styles"

function buildPageRule(pageLayout: DocPageLayout): string {
  const wMm = pageLayout.format.widthMm
  const hMm = pageLayout.format.heightMm
  const landscape =
    pageLayout.format.widthMm > pageLayout.format.heightMm ||
    (pageLayout.format.widthMm === pageLayout.format.heightMm && false)
  const size = landscape ? `${hMm}mm ${wMm}mm` : `${wMm}mm ${hMm}mm`
  return `@page { size: ${size}; margin: 0; }`
}

function injectPrintStyles(
  pageLayout: DocPageLayout,
  paragraphStyles: DocParagraphStylesCatalog
): () => void {
  const existing = document.getElementById(PRINT_STYLE_ID)
  existing?.remove()

  const style = document.createElement("style")
  style.id = PRINT_STYLE_ID
  style.textContent = [
    buildPageRule(pageLayout),
    buildParagraphStylesCss(paragraphStyles, ".ultidrive-richtext-editor, .ultidrive-richtext-region-editor"),
  ].join("\n")
  document.head.appendChild(style)

  return () => {
    style.remove()
  }
}

async function waitForPrintLayout(): Promise<void> {
  if (typeof document !== "undefined" && document.fonts?.ready) {
    await document.fonts.ready
  }
  await new Promise<void>((resolve) => requestAnimationFrame(() => resolve()))
  await new Promise<void>((resolve) => requestAnimationFrame(() => resolve()))
}

export type DocsPrintMode = "print" | "pdf-capture"

export async function prepareDocsPrintEnvironment(
  snapshot: DocsExportSnapshot,
  mode: DocsPrintMode = "print"
): Promise<() => void> {
  const root = document.documentElement
  root.classList.add("docs-printing")
  if (mode === "pdf-capture") {
    root.classList.add("docs-pdf-capture")
  }

  const removeStyles = injectPrintStyles(snapshot.pageLayout, snapshot.paragraphStyles)
  await waitForPrintLayout()

  return () => {
    root.classList.remove("docs-printing", "docs-pdf-capture")
    removeStyles()
  }
}

export async function printDocsDocument(snapshot: DocsExportSnapshot): Promise<void> {
  const cleanup = await prepareDocsPrintEnvironment(snapshot, "print")

  const onAfterPrint = () => {
    cleanup()
    window.removeEventListener("afterprint", onAfterPrint)
  }
  window.addEventListener("afterprint", onAfterPrint)

  window.print()

  // Fallback cleanup if afterprint never fires (some browsers)
  window.setTimeout(() => {
    if (document.documentElement.classList.contains("docs-printing")) {
      cleanup()
    }
  }, 2000)
}
