/**
 * 使用 html-to-image 和 jsPDF 实现PDF导出功能
 */
import JsPDF from 'jspdf'
import { processElement } from './core'

const convertToPDF = async (dataUrl, fileName, format = 'PNG') => {
  const img = new Image()
  img.src = dataUrl

  await new Promise((resolve, reject) => {
    img.onload = resolve
    img.onerror = reject
  })

  const contentWidth = img.width
  const contentHeight = img.height
  const pdfWidth = 595.28
  const pdfHeight = 841.89
  const scale = pdfWidth / contentWidth
  const imgWidth = pdfWidth
  const imgHeight = contentHeight * scale

  const pdf = new JsPDF('p', 'pt', 'a4')

  if (imgHeight <= pdfHeight) {
    pdf.addImage(dataUrl, format, 0, 0, imgWidth, imgHeight)
  } else {
    const canvas = document.createElement('canvas')
    const ctx = canvas.getContext('2d')
    canvas.width = contentWidth
    canvas.height = pdfHeight / scale

    let currentY = 0
    let pageCount = 0

    while (currentY < contentHeight) {
      const remainingHeight = contentHeight - currentY
      const currentPageHeight = Math.min(canvas.height, remainingHeight)

      if (currentPageHeight < canvas.height) {
        canvas.height = currentPageHeight
      }

      ctx.clearRect(0, 0, canvas.width, canvas.height)
      ctx.drawImage(img, 0, currentY, contentWidth, currentPageHeight, 0, 0, canvas.width, currentPageHeight)

      if (pageCount > 0) {
        pdf.addPage()
      }

      const pageDataUrl = canvas.toDataURL(`image/${format.toLowerCase()}`, format === 'JPEG' ? 0.85 : 1.0)
      const pageImgHeight = currentPageHeight * scale
      pdf.addImage(pageDataUrl, format, 0, 0, imgWidth, pageImgHeight)

      currentY += currentPageHeight
      pageCount++
    }
  }

  pdf.save(`${fileName}.pdf`)
}

/**
 * 将HTML元素导出为PDF
 */
const exportToPDF = async (fileName, elementId, options = {}) => {
  const backgroundColor = options.backgroundColor || '#ffffff'
  const format = options.format || 'png'

  const dataUrl = await processElement(elementId, {
    beforeProcess: options.beforeExport,
    afterProcess: options.afterExport,
    format,
    quality: options.quality || 0.95,
    pixelRatio: options.pixelRatio || 2,
    backgroundColor
  })

  await convertToPDF(dataUrl, fileName, format.toUpperCase())
}

export const exportToPDFWithPng = async (fileName, elementId, options = {}) => {
  return exportToPDF(fileName, elementId, { ...options, format: 'png' })
}

export const exportToPDFWithJpeg = async (fileName, elementId, options = {}) => {
  return exportToPDF(fileName, elementId, { ...options, format: 'jpeg' })
}
