<template>
  <div>
    <component :is="tag" ref="wrapRef" />
  </div>
</template>

<script lang="ts">
import { PropType } from 'vue'
import { Component, Prop, Vue, Ref } from 'vue-property-decorator'
import { QRCodeRenderersOptions, LogoType } from './types'
import { toCanvas } from './toCanvas'
import { toDataURL } from 'qrcode'
import { downloadByUrl } from '@/utils/file/download'

@Component({
  name: 'EtQrcode',
})
export default class EtQrcode extends Vue {
  @Ref() private readonly wrapRef!: HTMLCanvasElement | HTMLImageElement | null

  @Prop({
    type: [String, Array] as PropType<string | any[]>,
  })
  value!: string | any[]

  /**
   * 参数
   */
  @Prop({
    type: Object as PropType<QRCodeRenderersOptions>,
    default: null,
  })
  options!: QRCodeRenderersOptions

  /**
   * 宽度
   */
  @Prop({
    type: Number as PropType<number>,
    default: 200,
  })
  width!: number

  /**
   * 中间logo图标
   */
  @Prop({
    type: [String, Object] as PropType<Partial<LogoType> | string>,
    default: '',
  })
  logo!: Partial<LogoType> | string

  /**
   * img 不支持内嵌logo
   */
  @Prop({
    type: String as PropType<'canvas' | 'img'>,
    default: 'canvas',
    validator: (v: string) => ['canvas', 'img'].includes(v),
  })
  tag!: 'canvas' | 'img'

  private url = ''

  private async createQrcode() {
    try {
      if (!this.wrapRef) return

      if (this.tag === 'canvas') {
        const url: string = await toCanvas({
          canvas: this.wrapRef,
          width: this.width,
          logo: this.logo as any,
          content: this.value,
          options: this.options || {},
        })
        this.url = url
        /**
         * 二维码生成完成事件
         * @property {string} url 二维码链接
         */
        this.$emit('done', url)
        return
      }

      if (this.tag === 'img') {
        const url: string = await toDataURL(this.value, {
          errorCorrectionLevel: 'H',
          width: this.width,
          ...this.options,
        })
        ;(this.wrapRef as HTMLImageElement).src = url
        this.url = url
        /**
         * 二维码生成完成事件
         * @property {string} url 二维码链接
         */
        this.$emit('done', url)
      }
    } catch (error) {
      /**
       * 二维码生成失败事件
       * @property {Error} error 报错参数
       */
      this.$emit('error', error)
    }
  }

  /**
   * 下载二维码
   * @public
   * @property {string} fileName 文件名
   */
  public download(fileName?: string) {
    if (!this.url) return
    downloadByUrl({
      url: this.url,
      fileName,
    })
  }

  mounted() {
    this.createQrcode()
  }
}
</script>
