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()
const blobToBase64 = (blob: any) => {
   return new Promise(resolve => {
      const reader = new FileReader()
      reader.onloadend = () => resolve(reader.result)
      reader.readAsDataURL(blob)
   })
}

// export const svgtopng = async (svg: any, width: any, height: any) => {
//    // eslint-disable-next-line @typescript-eslint/ban-ts-comment
//    // @ts-ignore
//    const canvas = new OffscreenCanvas(width, height)
//    const ctx = canvas.getContext("2d")!
//    const v = 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")

//    // Render only first frame, ignoring animations and mouse.
//    await v.start()
//    const blob = await canvas.convertToBlob()
//    const base64 = await blobToBase64(blob)
//    return base64
// }

let canvas = null as any
export const svgtopng = async (svg: any, width: any, height: any) => {
   // console.log(canvas, +new Date() + '-----')

   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")

   // 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)
   ctx.clearRect(0, 0, canvas.width, canvas.height)
   await v.stop()
   v = null
   return base64
}

const convertToBlob = (canvas: any) => {
   return new Promise(resolve => {
      canvas.toBlob(resolve)
   })
}

const canvasAddPadding = async (sourceCanvas: any) => {
   const targetCanvas = document.createElement("canvas")
   targetCanvas.width = sourceCanvas.width + 400
   targetCanvas.height = sourceCanvas.height + 100
   // 坐标(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, 50)

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