import QRCode from "qrcode"
import JSZip from "jszip"
import { saveAs } from "file-saver"


/**
 * 自动换行
 */
function wrapText(ctx, text, maxWidth) {

  const chars = text.split("")
  const lines = []
  let current = ""

  chars.forEach(c => {

    const testLine = current + c
    const width = ctx.measureText(testLine).width

    if (width <= maxWidth) {
      current = testLine
    } else {
      lines.push(current)
      current = c
    }

  })

  if (current) lines.push(current)

  return lines
}


/**
 * 生成二维码canvas
 */
export async function generateQRCodeCanvas(id, text) {

  const TEXT_SIZE = 15
  const TEXT_TOP_MARGIN = -4
  const TEXT_BOTTOM_PADDING = 2
  const SCALE = 4

  const qrCanvas = document.createElement("canvas")

  await QRCode.toCanvas(qrCanvas, id, {
    errorCorrectionLevel: "L",
    margin: 1,
    scale: SCALE
  })

  const qrWidth = qrCanvas.width

  const canvas = document.createElement("canvas")
  const ctx = canvas.getContext("2d")

  ctx.font = TEXT_SIZE + "px Arial"

  const lines = wrapText(ctx, text, qrWidth+30)

  const lineHeight = TEXT_SIZE + 1
  const textHeight = lines.length * lineHeight

  const totalHeight =
    qrWidth +
    TEXT_TOP_MARGIN +
    textHeight +
    TEXT_BOTTOM_PADDING

  canvas.width = qrWidth
  canvas.height = totalHeight

  ctx.fillStyle = "#fff"
  ctx.fillRect(0, 0, canvas.width, canvas.height)

  ctx.drawImage(qrCanvas, 0, 0)

  ctx.fillStyle = "#000"
  ctx.textAlign = "center"

  let y = qrWidth + TEXT_TOP_MARGIN + lineHeight

  lines.forEach(line => {

    ctx.fillText(line, qrWidth / 2, y)

    y += lineHeight

  })

  return canvas
}


/**
 * 单个下载
 */
export async function downloadSingleQRCode(id, text) {

  const canvas = await generateQRCodeCanvas(id, text)

  const link = document.createElement("a")
  link.href = canvas.toDataURL("image/png")
  link.download = text + ".png"
  link.click()

}


/**
 * 批量ZIP下载
 */
export async function downloadBatchQRCodeZip(list, zipName = "qrcode") {

  const zip = new JSZip()

  for (let item of list) {

    const canvas = await generateQRCodeCanvas(item.id, item.code)

    const base64 = canvas.toDataURL("image/png").split(",")[1]

    zip.file(`${item.code}.png`, base64, { base64: true })

  }

  const content = await zip.generateAsync({
    type: "blob",
    compression: "DEFLATE",
    compressionOptions: { level: 6 }
  })

  saveAs(content, `${zipName}.zip`)

}