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

interface Position {
  x: number
  y: number
}

export function editQRCodeImg() {
  const title = document.title
  const desc = document.head.querySelector('meta[name="author"]')
    ? document.head.querySelector<HTMLMetaElement>('meta[name="description"]')!
        .content
    : ""
  const href = location.href
  const authorDom = (document.querySelector(".author-name") ||
    document.querySelector(".article-box__meta .item")) as HTMLElement
  const hostname = location.hostname

  const author = authorDom ? authorDom.innerText : ""
  const encodedContent = encodeURIComponent(title)
  const encodedAuthor = encodeURIComponent(author)
  const encodedDesc = encodeURIComponent(desc)
  let encodedBook = null
  const encodedUrl = encodeURIComponent(href)

  hostname.includes("csdn") && (encodedBook = encodeURIComponent("《CSDN》"))
  hostname.includes("zhihu") && (encodedBook = encodeURIComponent("《知乎》"))
  hostname.includes("baidu") && (encodedBook = encodeURIComponent("《百度》"))
  hostname.includes("jianshu") && (encodedBook = encodeURIComponent("《简书》"))
  hostname.includes("jb51") &&
    (encodedBook = encodeURIComponent("《脚本之家》"))
  hostname.includes("cnblogs") &&
    (encodedBook = encodeURIComponent("《博客园》"))
  hostname.includes("51cto") && (encodedBook = encodeURIComponent("《51CTO》"))
  hostname.includes("juejin") && (encodedBook = encodeURIComponent("《掘金》"))
  hostname.includes("php") &&
    (encodedBook = encodeURIComponent("《php中文网》"))
  hostname.includes("oschina") &&
    (encodedBook = encodeURIComponent("《开源中国》"))
  hostname.includes("segmentfault") &&
    (encodedBook = encodeURIComponent("《思否》"))
  hostname.includes("weixin") && (encodedBook = encodeURIComponent("《微信》"))
  hostname.includes("medium") &&
    (encodedBook = encodeURIComponent("《medium》"))

  // 基础链接地址，这里假设为 example.com
  const baseUrl = "https://code-box.fun/editor-quote?"
  const finalUrl = `${baseUrl}content=${encodedContent}&author=${encodedAuthor}&book=${encodedBook}&url=${encodedUrl}`
  window.open(finalUrl)
}

export default function makerQRCodeImg() {
  const qrcodepostmaker = document.createElement("canvas")
  qrcodepostmaker.id = "qrcodepostmaker"
  qrcodepostmaker.style.display = "none"
  document.body.appendChild(qrcodepostmaker)

  // 文本换行处理
  const textComputer = (
    text: string,
    style: string,
    width: number,
    ctx: CanvasRenderingContext2D
  ): string[] => {
    if (text.replace(/\s/g, "").length === 0) {
      return []
    }
    ctx.font = style
    let temp = 0
    const row: string[] = []
    for (let i = 0; i <= text.length; i++) {
      if (ctx.measureText(text.substring(temp, i)).width >= width) {
        row.push(text.substring(temp, i - 1))
        temp = i - 1
      } else if (i === text.length) {
        row.push(text.substring(temp, i))
      }
    }
    return row
  }

  // 绘制文本
  const textWriter = (
    textArr: string[],
    Style: string,
    align: CanvasTextAlign,
    color: string,
    borderColor: string,
    fontSize: number,
    lineHeight: number,
    pos: Position,
    ctx: CanvasRenderingContext2D
  ): Position => {
    ctx.font = Style
    ctx.textAlign = align
    ctx.fillStyle = color
    ctx.strokeStyle = borderColor
    for (const text of textArr) {
      pos.y += fontSize * lineHeight
      ctx.fillText(text, pos.x, pos.y)
    }
    return pos
  }

  // 生成海报
  const makerQRPost = (): void => {
    const canvas = document.querySelector<HTMLCanvasElement>("#qrcodepostmaker")
    const ctx = canvas.getContext("2d")
    if (!ctx) return

    const QRCodeData = ctx.getImageData(0, 0, canvas.width, canvas.height)
    const title = document.title
    const desc = document.head.querySelector('meta[name="description"]')
      ? document.head.querySelector<HTMLMetaElement>(
          'meta[name="description"]'
        )!.content
      : ""
    const cardWidth = 360
    const lineHeight = 1.6
    const margin = 36
    const titleStyle = 'Bold 18px "Microsoft YaHei"'
    const descStyle = '16px "Microsoft YaHei"'

    const titleArray = textComputer(
      title,
      titleStyle,
      cardWidth - margin * 2,
      ctx
    )
    const descArray = textComputer(desc, descStyle, cardWidth - margin * 2, ctx)

    const cardHeight =
      margin * 2.5 +
      18 * titleArray.length * lineHeight +
      16 * descArray.length * lineHeight +
      (descArray.length ? margin / 2 : 0) +
      300

    canvas.width = cardWidth
    canvas.height = cardHeight

    const myGradient = ctx.createLinearGradient(0, 0, 0, cardHeight)
    myGradient.addColorStop(0, "#2980B9")
    myGradient.addColorStop(0.5, "#6DD5FA")
    myGradient.addColorStop(1, "#FFFFFF")

    ctx.fillStyle = myGradient
    ctx.fillRect(0, 0, cardWidth, cardHeight)
    ctx.fillStyle = "#FFFFFF"

    ctx.beginPath()
    ctx.arc(margin * 0.4, cardHeight - margin * 5, margin, 0, Math.PI * 2, true)
    ctx.arc(
      cardWidth - margin * 0.4,
      cardHeight - margin * 3,
      margin * 0.8,
      0,
      Math.PI * 2,
      true
    )
    ctx.fillRect(0, cardHeight - margin * 5, cardWidth / 2, margin * 5)
    ctx.fillRect(
      cardWidth / 2,
      cardHeight - margin * 3,
      cardWidth / 2,
      margin * 3
    )
    ctx.fill()

    const titleEnd = textWriter(
      titleArray,
      titleStyle,
      "center",
      "black",
      "rgba(255, 255, 255, 0.6)",
      18,
      lineHeight,
      { x: cardWidth / 2, y: margin },
      ctx
    )
    const descEnd = textWriter(
      descArray,
      descStyle,
      "left",
      "black",
      "rgba(255, 255, 255, 0.6)",
      16,
      lineHeight,
      { x: margin, y: titleEnd.y + margin / 2 },
      ctx
    )

    ctx.fillStyle = "white"
    ctx.fillRect((cardWidth - 288) / 2, descEnd.y + margin - 24, 288, 288)
    ctx.putImageData(QRCodeData, (cardWidth - 256) / 2, descEnd.y + margin)

    textWriter(
      ["（长按识别二维码进行访问）"],
      descStyle,
      "center",
      "rgba(0, 0, 0, 0.6)",
      "rgba(255, 255, 255, 0.6)",
      16,
      lineHeight,
      { x: cardWidth / 2, y: descEnd.y + margin + 256 },
      ctx
    )
    textWriter(
      ["codebox-一键复制代码/下载文章"],
      descStyle,
      "center",
      "rgba(0, 0, 0, 0.6)",
      "rgba(255, 255, 255, 0.6)",
      16,
      lineHeight,
      { x: cardWidth / 2, y: descEnd.y + margin + 280 },
      ctx
    )

    saveAs(canvas.toDataURL("image/png"), title + ".png")
    qrcodepostmaker.parentNode?.removeChild(qrcodepostmaker)
  }

  let tryTimes = 30
  const makeQRCode = window.setInterval(() => {
    try {
      QRCode.toCanvas(
        document.getElementById("qrcodepostmaker"),
        window.location.href,
        { width: 260, errorCorrectionLevel: "Q" },
        (error) => {
          if (error) {
            console.log(error)
            return
          }
          makerQRPost()
        }
      )
      window.clearInterval(makeQRCode)
    } catch (error) {
      console.log(error)
      tryTimes--
      if (!tryTimes) {
        window.clearInterval(makeQRCode)
        alert("没能成功载入功能库，请刷新重试~")
      }
    }
  }, 200)
}
