<template>
  <view class="queue-code">
    <!-- 预览图片 -->
    <image
      v-if="previewUrl"
      :src="previewUrl"
      class="preview-image"
      :style="{width: width + 'px', height: height + 'px'}"
      mode="aspectFit"
    />
    <!-- 用于生成图片的canvas -->
    <canvas
      canvas-id="queueCode"
      id="queueCode"
      :style="{width: width + 'px', height: height + 'px'}"
    />
  </view>
</template>

<script>
import { getWxQRCode } from '@/api/common'
import { parseLocalUrl } from '@/utils'
/**
 * QueueCode 队伍小程序码组件
 * @description 用于展示和保存队伍小程序码，支持自定义底部文字
 * @property {String} scene - 小程序码的场景值
 * @property {String} title - 底部显示的队伍名称
 * @property {Number} width - 画布宽度，默认300
 * @property {Number} height - 画布高度，默认400
 * @property {String} page - 小程序码跳转的页面路径
 * @event {Function} onSave - 保存成功的回调
 * @event {Function} onError - 出错的回调
 */
export default {
  name: 'QueueCode',
  props: {
    scene: {
      type: String,
      required: true
    },
    title: {
      type: String,
      required: true
    },
    width: {
      type: Number,
      default: 240
    },
    height: {
      type: Number,
      default: 320
    },
    page: {
      type: String,
      default: null
    }
  },
  data() {
    return {
      ctx: null,
      previewUrl: '',
      qrCodePath: '',
      isLoading: false
    }
  },
  watch: {
    scene: {
      immediate: true,
      handler(val) {
        if (val) {
          this.init()
        }
      }
    }
  },
  methods: {
    async init() {
      if (this.isLoading) return
      this.isLoading = true
      try {
        // 获取小程序码
        await this.getWxacode()
        // 绘制画布
        await this.drawCanvas()
      } catch (error) {
        console.error('初始化小程序码失败:', error)
        this.$emit('error', error)
        uni.showToast({
          title: '生成小程序码失败',
          icon: 'none'
        })
      } finally {
        this.isLoading = false
      }
    },

    // 获取小程序码
    async getWxacode() {
      try {
        const res = await getWxQRCode(this.page, this.scene)
        if (res.code === 200 && res.data) {
          this.qrCodePath = parseLocalUrl(res.data)
        } else {
          throw new Error('获取小程序码失败')
        }
      } catch (error) {
        console.error('获取小程序码失败:', error)
        throw error
      }
    },

    // 绘制画布
    async drawCanvas() {
      return new Promise((resolve, reject) => {
        try {
          const ctx = uni.createCanvasContext('queueCode', this)

          // 绘制白色背景
          ctx.fillStyle = '#ffffff'
          ctx.fillRect(0, 0, this.width, this.height)

          // 绘制顶部大标题
          ctx.setFontSize(18)
          ctx.setFillStyle('#333333')
          ctx.setTextAlign('center')
          ctx.fillText('微信扫码', this.width/2, 30)

          // 绘制顶部小标题
          ctx.setFontSize(12)
          ctx.setFillStyle('#666666')
          ctx.setTextAlign('center')
          ctx.fillText('扫码取号·等待叫号·叫号进场', this.width/2, 55)

          // 下载并绘制二维码
          uni.downloadFile({
            url: this.qrCodePath,
            success: (res) => {
              const qrSize = 180
              const qrX = (this.width - qrSize) / 2
              const qrY = 70

              // 绘制二维码
              ctx.drawImage(res.tempFilePath, qrX, qrY, qrSize, qrSize)

              // 绘制底部标题背景
              const titleY = qrY + qrSize + 20
              const titleHeight = 50
              ctx.fillStyle = '#F8F9FA'
              ctx.fillRect(0, titleY, this.width, titleHeight)

              // 绘制底部标题
              const fontSize = 14
              ctx.setFontSize(fontSize)
              ctx.setFillStyle('#333333')
              ctx.setTextAlign('center')
              ctx.fillText(this.title, this.width/2, titleY + titleHeight/2 + fontSize/2)

              ctx.draw(false, () => {
                resolve()
              })
            },
            fail: (error) => {
              console.error('下载小程序码失败:', error)
              reject(error)
            }
          })
        } catch (error) {
          console.error('绘制画布失败:', error)
          reject(error)
        }
      })
    },

    // 保存图片
    async save() {
      if (this.isLoading) {
        uni.showToast({
          title: '正在生成小程序码，请稍后',
          icon: 'none'
        })
        return
      }

      try {
        // 获取用户授权
        const auth = await uni.authorize({
          scope: 'scope.writePhotosAlbum'
        }).catch(() => null)

        if (!auth) {
          uni.showModal({
            title: '提示',
            content: '需要保存相册权限，是否去设置？',
            success: (res) => {
              if (res.confirm) {
                uni.openSetting()
              }
            }
          })
          return
        }

        // 将画布内容保存为临时文件
        const res = await new Promise((resolve, reject) => {
          uni.canvasToTempFilePath({
            canvasId: 'queueCode',
            success: resolve,
            fail: reject
          }, this)
        })

        // 保存图片到相册
        await uni.saveImageToPhotosAlbum({
          filePath: res.tempFilePath
        })

        this.$emit('save')
        uni.showToast({
          title: '保存成功',
          icon: 'success'
        })
      } catch (error) {
        console.error('保存小程序码失败:', error)
        this.$emit('error', error)
        uni.showToast({
          title: '保存失败',
          icon: 'none'
        })
      }
    }
  }
}
</script>

<style lang="scss" scoped>
.queue-code {
  position: relative;
  display: flex;
  justify-content: center;
  align-items: center;

  .preview-image {
    background-color: #ffffff;
    border-radius: 8rpx;
  }

  canvas {
    background-color: #ffffff;
    border-radius: 8rpx;
    box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.05);
  }
}
</style>