import { Canvg, presets } from 'canvg'

// https://gist.githubusercontent.com/n1ru4l/9c7eff52fe084d67ff15ae6b0af5f171/raw/da9fe36d72171d4e36b92aced587b48dc5182792/offscreen-canvas-polyfill.js
if (!window.OffscreenCanvas) {
  // @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

      // @ts-ignore
      this.canvas.convertToBlob = () => {
        return new Promise((resolve) => {
          this.canvas.toBlob(resolve)
        })
      }

      // @ts-ignore
      return this.canvas
    }
  }
}

const preset = presets.offscreen()

function blobToBase64(blob: Blob) {
  return new Promise((resolve, _) => {
    const reader = new FileReader()
    reader.onloadend = () => resolve(reader.result)
    reader.readAsDataURL(blob)
  })
}

export async function svgtopng(svg: string, width: number, height: number) {
  const canvas = new OffscreenCanvas(width, height)
  const ctx = canvas.getContext('2d')
  ctx!.fillStyle = '#FFFFFF'
  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
}
