import { Canvg, presets } from "canvg"

// https://gist.githubusercontent.com/n1ru4l/9c7eff52fe084d67ff15ae6b0af5f171/raw/da9fe36d72171d4e36b92aced587b48dc5182792/offscreen-canvas-polyfill.js
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
if (!window.OffscreenCanvas) {
   // eslint-disable-next-line @typescript-eslint/ban-ts-comment
   // @ts-ignore
   window.OffscreenCanvas = class OffscreenCanvas {
      canvas: HTMLCanvasElement
      constructor(width: number, height: number) {
         this.canvas = document.createElement("canvas")
         this.canvas.width = width
         this.canvas.height = height

         // eslint-disable-next-line @typescript-eslint/ban-ts-comment
         // @ts-ignore
         this.canvas.convertToBlob = () => {
            return new Promise(resolve => {
               this.canvas.toBlob(resolve)
            })
         }

         // eslint-disable-next-line @typescript-eslint/ban-ts-comment
         // @ts-ignore
         return this.canvas
      }
   }
}

const preset: any = presets.offscreen()
export const blobToBase64 = (blob: any) => {
   return new Promise(resolve => {
      const reader = new FileReader()
      reader.onloadend = () => resolve(reader.result)
      reader.readAsDataURL(blob)
   })
}

export const addMusicTitle = (canvas: any, title: any) => {
   canvas.getContext("2d")
   const water = document.createElement("canvas")

   // 小水印画布大小
   water.width = canvas.width
   water.height = canvas.height + 120
   const waterCtx = water.getContext("2d") as CanvasRenderingContext2D
   waterCtx.font = `66pt Calibri`
   waterCtx.fillStyle = "#000"
   waterCtx.textAlign = "center"
   waterCtx.drawImage(canvas, 0, 40)
   waterCtx.fillText(title, canvas.width / 2, 160)
   return water
}

let canvas = null as any
export const svgtoblob = async (svg: any, width: any, height: any, name: string, isShowPadding = true) => {
   if (!canvas) {
      // eslint-disable-next-line @typescript-eslint/ban-ts-comment
      // @ts-ignore
      canvas = new OffscreenCanvas(width, height)
   }

   const ctx = canvas.getContext("2d")!
   let v: any = await Canvg.fromString(ctx!, svg, preset)

   /**
    * Resize SVG to fit in given size.
    * @param width
    * @param height
    * @param preserveAspectRatio
    */
   // v.resize(width * 2, height * 2, "xMidYMid meet")
   v.resize(width / 1.2, height / 1.2, "xMidYMid meet")

   // Render only first frame, ignoring animations and mouse.
   await v.start()
   // const blob = await canvas.convertToBlob()
   // const base64 = await blobToBase64(blob)
   const base64 = await canvasAddPadding(canvas, name, isShowPadding)
   ctx.clearRect(0, 0, canvas.width, canvas.height)
   await v.stop()
   v = null
   return base64
}

const convertToBlob = (canvas: any, type = "image/png") => {
   return new Promise((resolve, reject) => {
      canvas.toBlob((blob: Blob) => {
         if (blob) {
            resolve(blob)
         } else {
            reject(new Error("转换失败"))
         }
      }, type)
   })
}

const canvasAddPadding = async (sourceCanvas: any, name: string, isShowPadding = true) => {
   const targetCanvas = document.createElement("canvas")
   targetCanvas.width = sourceCanvas.width + (isShowPadding ? 400 : 160)
   targetCanvas.height = sourceCanvas.height + (isShowPadding ? 200 : 0)

   // 坐标(0,0) 表示从此处开始绘制，相当于偏移。
   const targetContext = targetCanvas.getContext("2d") as CanvasRenderingContext2D

   // const sourceContext = sourceCanvas.getContext("2d") as CanvasRenderingContext2D

   // 从源canvas中获取图像数据
   // const imageData = sourceContext.getImageData(0, 0, sourceCanvas.width, sourceCanvas.height)

   // 清空目标canvas
   targetContext.clearRect(0, 0, targetCanvas.width, targetCanvas.height)

   // 将图像数据绘制到目标canvas上，并添加边距
   // targetContext.putImageData(imageData, 200, 100)
   targetContext.fillStyle = "#fff"
   targetContext.fillRect(0, 0, targetCanvas.width, targetCanvas.height)
   // targetCanvas = await addMusicTitle(targetCanvas, name)

   // 小水印画布大小
   // const waterCtx = water.getContext("2d") as CanvasRenderingContext2D
   targetContext.font = `30pt Calibri`
   targetContext.fillStyle = "#000"
   targetContext.textAlign = "center"
   targetContext.drawImage(sourceCanvas, isShowPadding ? 200 : 80, isShowPadding ? 240 : 40)
   targetContext.fillText(name, targetCanvas.width / 2, isShowPadding ? 200 : 60)

   const blob = await convertToBlob(targetCanvas)
   targetContext.clearRect(0, 0, targetCanvas.width, targetCanvas.height)
   return blob
}

export const canvasAddTitle = async (sourceCanvas: any, name: string) => {
   const targetCanvas = document.createElement("canvas")
   targetCanvas.width = sourceCanvas.width
   targetCanvas.height = sourceCanvas.height + 90

   // 坐标(0,0) 表示从此处开始绘制，相当于偏移。
   const targetContext = targetCanvas.getContext("2d") as CanvasRenderingContext2D

   // const sourceContext = sourceCanvas.getContext("2d") as CanvasRenderingContext2D

   // 从源canvas中获取图像数据
   // const imageData = sourceContext.getImageData(0, 0, sourceCanvas.width, sourceCanvas.height)

   // 清空目标canvas
   targetContext.clearRect(0, 0, targetCanvas.width, targetCanvas.height)

   // 将图像数据绘制到目标canvas上，并添加边距
   // targetContext.putImageData(imageData, 200, 100)
   targetContext.fillStyle = "#fff"
   targetContext.fillRect(0, 0, targetCanvas.width, targetCanvas.height)
   // targetCanvas = await addMusicTitle(targetCanvas, name)

   // 小水印画布大小
   // const waterCtx = water.getContext("2d") as CanvasRenderingContext2D
   targetContext.font = `30pt Calibri`
   targetContext.fillStyle = "#000"
   targetContext.textAlign = "center"
   targetContext.drawImage(sourceCanvas, 0, 70)
   targetContext.fillText(name, targetCanvas.width / 2, 100)
   const blob = await convertToBlob(targetCanvas)
   // const base64 = await blobToBase64(blob)
   targetContext.clearRect(0, 0, targetCanvas.width, targetCanvas.height)
   return blob
}

export const convasToImg = (canvas: any) => {
   return canvas.toDataURL("image/png")
}

// // 获取文件blob格式
export const imgToCanvas = async (url: string) => {
   const img = document.createElement("img")
   img.setAttribute("crossOrigin", "anonymous")
   // 为了处理base64 和 连接加载不同的
   if (url && typeof url == "string" && url.includes("data:image")) {
      img.src = url
   } else {
      img.src = url + `?t=${+new Date()}`
   }

   // 防止跨域引起的 Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported.
   await new Promise(resolve => (img.onload = resolve))
   // 创建canvas DOM元素，并设置其宽高和图片一样
   const canvas = document.createElement("canvas")
   canvas.width = img.width
   canvas.height = img.height
   // 坐标(0,0) 表示从此处开始绘制，相当于偏移。
   const ctx = canvas.getContext("2d") as CanvasRenderingContext2D

   ctx.fillStyle = "rgb(255, 255, 255)"
   ctx.fillStyle = "#fff"
   ctx.fillRect(0, 0, img.width, img.height)
   ctx.drawImage(img, 0, 0)
   return canvas
}
