import React, { forwardRef, useCallback, useEffect, useMemo, useRef, useImperativeHandle } from 'react'
import classNames from 'classnames'
import QRCode from 'qrcode'
import html2canvas from 'html2canvas'
import styles from './style.less'

export default forwardRef((props, ref) => {
  const { className, width = 430, border, content, title, fileName, onError } = props

  const rootRef = useRef()
  const canvasRef = useRef()

  const { style1, style2 } = useMemo(() => {
    return {
      style1: {
        border: border ? '2px solid rgba(0,0,0)' : 'none',
        borderRadius: border ? '8px' : 'none'
      },
      style2: {
        width: `${width}px`,
        height: `${width}px`,
      }
    }
  }, [width, border])

  const qrOption = useMemo(() => ({
    margin: 0,
    width: width,
    errorCorrectionLevel: 'M'
  }), [width])

  useEffect(() => {
    if (content) {
      QRCode.toCanvas(canvasRef.current, content, qrOption, onError)
    }
  }, [content, qrOption, onError])

  useImperativeHandle(ref, () => ({
    download: () => {
      return new Promise((resolve, reject) => {
        html2canvas(rootRef.current).then((canvas) => {
          const imageData = canvas.toDataURL('image/png', .8);
          const link = document.createElement('a');
          link.download = `${fileName || 'qrcode'}.png`
          link.href = imageData
          link.click()
          resolve()
        }).catch(reject)
      })
    },
    getCanvas: () => {
      return new Promise((resolve, reject) => {
        html2canvas(rootRef.current).then((canvas) => {
          resolve(canvas)
        }).catch(reject)
      })
    }
  }), [fileName])

  return (
    <div className={classNames(className, styles['qrcode-box'])} ref={rootRef}>
      <div className={styles['qrcode-container']} style={style1}>
        <canvas ref={canvasRef} style={style2}/>
      </div>
      {
        title && <h3>{title}</h3>
      }
    </div>
  )
})
