<template>
  <uv-popup 
    ref="popup"
    :overlayOpacity="0.6"
    mode="center"
    bgColor="none"
    :zIndex="1000000"
    @change="onPopupChange"
  >
    <view class="popup__view">
      <view class="canvas" style="width: 566rpx; height: 1060rpx; overflow: hidden;">
        <canvas id="myCanvas" canvas-id="firstCanvas1" type="2d" style="width: 100%; height: 100%;"></canvas>
      </view>

      <button class="btn" @click="saveImg">
        <view class="content">保存到相册</view>
      </button>
    </view>
  </uv-popup>
</template>


<script>
	import { mapState } from 'vuex'

  export default {
		data() {
			return {
				wxCodeImage: '',
				baseUrl: 'https://image.hhlm1688.com/',
				canvas: {},
        retry: 10,
			}
		},
    computed: {
			...mapState(['userInfo', 'configList']),
    },
    async onLoad() {
    },
    methods: {
      open() {
        this.retry = 10
        this.$refs.popup.open();
      },
      close() {
        this.$refs.popup.close();
      },
			async fetchQrCode(path) {
        // todo: delete
        this.wxCodeImage = 'https://uploadfile.bizhizu.cn/up/e3/64/e0/e364e0f7f6af11f11abdafc22d17b15c.jpg'
        return
				try {
          const path = `pages/index/index?userId=${this.userInfo.id}`
					this.wxCodeImage = (await this.$fetch('getInviteCode', { path }))?.url

				} catch (err) {

				}
			},
      // 生成有圆角的矩形
      drawBg(ctx, x, y, width, height, radius) {
        ctx.beginPath();
        ctx.arc(x + radius, y + radius, radius, Math.PI, Math.PI * 3 / 2);
        ctx.lineTo(width - radius + x, y);
        ctx.arc(width - radius + x, radius + y, radius, Math.PI * 3 / 2, Math.PI * 2);
        ctx.lineTo(width + x, height + y - radius);
        ctx.arc(width - radius + x, height - radius + y, radius, 0, Math.PI * 1 / 2);
        ctx.lineTo(radius + x, height + y);
        ctx.arc(radius + x, height - radius + y, radius, Math.PI * 1 / 2, Math.PI);
        ctx.closePath();
        ctx.fillStyle = '#fff'
        ctx.fill()
      },
      drawCoverImg(canvas, ctx, x, y, width, height, radius, lineWidth) {
        return new Promise(resolve => {
          // 海报图片
          const paperImage = canvas.createImage()
          console.log('paperImage', paperImage)
          // todo: fetch
          paperImage.src = 'https://i1.hdslb.com/bfs/archive/c0101b4ce06e6bdda803728408e79c8f8b8d0725.jpg'
          paperImage.onload = () => {
            console.log('paperImage onload')
            
            ctx.beginPath();
            ctx.arc(x + radius, y + radius, radius, Math.PI, Math.PI * 3 / 2);
            ctx.lineTo(width - radius + x, y);
            ctx.arc(width - radius + x, radius + y, radius, Math.PI * 3 / 2, Math.PI * 2);
            ctx.lineTo(width + x, height + y);
            ctx.lineTo(x, height + y);
            ctx.closePath();
            ctx.lineWidth = lineWidth;
            ctx.strokeStyle = '#F8F8F8';
            ctx.stroke();

            ctx.clip();

            ctx.drawImage(paperImage, x, y, width, height)

            resolve()
          }
        })
      },
      drawContentBg(ctx, x, y, width, height, radius) {
        
        ctx.beginPath();
        // ctx.arc(x + radius, y + radius, radius, Math.PI, Math.PI * 3 / 2);
        ctx.moveTo(x, y);
        ctx.lineTo(width + x, y);
        ctx.lineTo(width + x, height + y - radius);
        ctx.arc(width - radius + x, height - radius + y, radius, 0, Math.PI * 1 / 2);
        ctx.lineTo(radius + x, height + y);
        ctx.arc(radius + x, height - radius + y, radius, Math.PI * 1 / 2, Math.PI);
        ctx.closePath();
        
        let gradient = ctx.createLinearGradient(x, y, x, y + height);
        gradient.addColorStop('0', '#DAF3FF');
        gradient.addColorStop('0.2', '#FBFEFF');
        gradient.addColorStop('1.0', '#FBFEFF');
        ctx.fillStyle = gradient
        ctx.fill()
      },
      drawAvatar(canvas, ctx, x, y, r) {
        console.log('drawAvatar', 'x', x, 'y', y, 'r', r)

        return new Promise(resolve => {
          // 头像图片
          const avatarImage = canvas.createImage()
          avatarImage.src = this.userInfo.headImage
          avatarImage.onload = () => {
            console.log('avatarImage onload')
            
            ctx.beginPath();
            console.log('arc', 'x', x + r, 'y', y + r, 'r', r)
            ctx.arc(x + r, y + r, r, 0, 2 * Math.PI);
            ctx.clip();

            const size = r*2
            console.log('size', size)
            ctx.drawImage(avatarImage, x, y, size, size)

            resolve()
          }
        })
      },
      drawMultilineText(ctx, text, x, y, maxWidth, lineHeight) {
        console.log('drawMultilineText', 'x', x, 'y', y)
        let line = '';
    
        for (let n = 0; n < text.length; n++) {
          const testLine = line + text[n];
          const metrics = ctx.measureText(testLine);
          const testWidth = metrics.width;
          if (testWidth > maxWidth && n > 0) {
            ctx.fillText(line, x, y);
            console.log(n, 'line', line, 'x', x, 'y', y)
            line = text[n];
            y += lineHeight;
          } else {
            line = testLine;
          }
        }
        console.log('line', line, 'x', x, 'y', y)
        ctx.fillText(line, x, y);
      },
      drawQrCodeImg(canvas, ctx, x, y, size) {
        return new Promise(resolve => {
          //二维码图片
          const coderImage = canvas.createImage()
          coderImage.src = this.wxCodeImage
          coderImage.onload = () => {
            console.log('coderImage onload')
            ctx.drawImage(coderImage, x, y, size, size)

            resolve()
          }
        })
      },
			draw() {

				wx.createSelectorQuery().in(this)
					.select('#myCanvas') // 绘制的canvas的id
					.fields({
						node: true,
						size: true
					})
					.exec(async (res) => {
            console.log('res', res)
            if (!res?.[0]?.node) {
              if (!this.retry) {
                console.log('retry fail')
                return
              }
              console.log('retry')
              this.retry -= 1
              setTimeout(() => {
                this.draw()
              }, 200)
              return
            }
						const canvas = res[0].node
						// 渲染上下文
						const ctx = canvas.getContext('2d')
						// Canvas 画布的实际绘制宽高
						const width = res[0].width
						const height = res[0].height
						// 初始化画布大小
						const dpr = wx.getWindowInfo().pixelRatio

						//根据dpr调整
						// dpr  2 4
						//      3 6
						console.log("--dpr", dpr)
						canvas.width = width * dpr
						canvas.height = height * dpr

						let Ratio = canvas.width / 566

						this.canvas = canvas
						ctx.scale(dpr, dpr)
						ctx.clearRect(0, 0, width, height)

						ctx.fillStyle = 'transparent'
						ctx.fillRect(0, 0, canvas.width, canvas.height)

            ctx.save()
            
            let radius = 48 * Ratio / dpr
            let w = 566 * Ratio / dpr
            let h = 1060 * Ratio / dpr
            this.drawBg(ctx, 0, 0, w, h, radius)

            ctx.restore();
            ctx.save()

            let lineWidth = 2 * Ratio / dpr
            let x = lineWidth
            let y = lineWidth
            w = 566 * Ratio / dpr - lineWidth * 2
            h = 400 * Ratio / dpr - lineWidth * 2
            await this.drawCoverImg(canvas, ctx, x, y, w, h, radius, lineWidth)

            ctx.restore();
            ctx.save()

            x = lineWidth
            y = 400 * Ratio / dpr + lineWidth
            h = 660 * Ratio / dpr - lineWidth * 2
            this.drawContentBg(ctx, x, y, w, h, radius, lineWidth)

            ctx.restore();
            ctx.save()

            radius = Math.floor(27 * Ratio / dpr)
            x = Math.floor(40 * Ratio / dpr)
            y = Math.floor(440 * Ratio / dpr)
            await this.drawAvatar(canvas, ctx, x, y, radius)

            ctx.restore();
            ctx.save()

            let text = this.userInfo.nickName
            let maxWidth = 560 * Ratio / dpr
            let lineHeight = 17 * Ratio / dpr
            x = 100 * Ratio / dpr
            y = 474 * Ratio / dpr
            ctx.font = "normal normal normal 11px normal";
            ctx.fillStyle = "#7D7D7D";
            this.drawMultilineText(ctx, text, x, y, maxWidth, lineHeight)

            ctx.restore();
            ctx.save()
            
            maxWidth = 560 * Ratio / dpr
            lineHeight = 60 * Ratio / dpr
            ctx.font = "normal normal 600 16px normal";
            ctx.fillStyle = "#181818";
            text = '邀请您'
            x = 40 * Ratio / dpr
            y = 564 * Ratio / dpr
            this.drawMultilineText(ctx, text, x, y, maxWidth, lineHeight)
            y += lineHeight
            text = '探索新世界，开启研学之旅！'
            this.drawMultilineText(ctx, text, x, y, maxWidth, lineHeight)
            
            ctx.restore();
            ctx.save()

            text = '是否渴望一场充满知识与乐趣的冒险？现在，我们诚挚邀请你加入我们的研学小程序，开启一场别开生面的学习之旅！'
            maxWidth = 486 * Ratio / dpr
            lineHeight = 30 * Ratio / dpr
            ctx.font = "normal normal normal 10px normal";
            ctx.fillStyle = "#7D7D7D";
            x = 40 * Ratio / dpr
            y = 690 * Ratio / dpr
            this.drawMultilineText(ctx, text, x, y, maxWidth, lineHeight)

            ctx.restore();
            ctx.save()
            
            // 设置虚线样式
            ctx.setLineDash([4, 4]); // 第一个参数是实线长度, 第二个参数是间隔长度
            ctx.lineDashOffset = 2; // 设置虚线的起始偏移量
            ctx.lineWidth = lineWidth;
            ctx.strokeStyle = '#DADADA';
            // 开始绘制
            ctx.beginPath();
            x = 40 * Ratio / dpr
            y = 778 * Ratio / dpr
            ctx.moveTo(x, y);
            x += 486 * Ratio / dpr
            ctx.lineTo(x, y);
            ctx.stroke();

            ctx.restore();
            ctx.save()

            maxWidth = 250 * Ratio / dpr
            lineHeight = 44 * Ratio / dpr
            ctx.font = "normal normal 600 13px normal";
            ctx.fillStyle = "#181818";
            text = '立即加入我们，'
            x = 40 * Ratio / dpr
            y = 879 * Ratio / dpr
            this.drawMultilineText(ctx, text, x, y, maxWidth, lineHeight)
            text = '开启你的研学之旅！'
            y += lineHeight
            this.drawMultilineText(ctx, text, x, y, maxWidth, lineHeight)

            ctx.restore();
            ctx.save()

            x = 316 * Ratio / dpr
            y = 810 * Ratio / dpr
            let size = 210 * Ratio / dpr
            await this.drawQrCodeImg(canvas, ctx, x, y, size)

            uni.hideLoading()

					})

			},
      async init() {
        uni.showLoading({
            title: '加载中...'
        });

        await this.fetchQrCode()
        uni.hideLoading();

				uni.showLoading({
					title: "拼命绘画中..."
				})
        this.draw()
      },
			saveImg() {
				this.$authorize('scope.writePhotosAlbum').then((res) => {
					this.imgApi()
				})
			},
			imgApi() {
        uni.showLoading({
            title: '保存中...'
        });
				wx.canvasToTempFilePath({
					x: 0,
					y: 0,
					width: this.canvas.width,
					height: this.canvas.height,
					canvas: this.canvas,
					success: (res) => {
						let tempFilePath = res.tempFilePath;
						this.saveImgToPhone(tempFilePath)
					},
					fail: (err) => {
						console.log('--canvasToTempFilePath--fail', err)
				    uni.hideLoading();
					}
				}, this);

			},
			saveImgToPhone(image) {
				/* 获取图片的信息 */
				uni.getImageInfo({
					src: image,
					success: function(image) {
						/* 保存图片到手机相册 */
						uni.saveImageToPhotosAlbum({
							filePath: image.path,
							success: function() {
								uni.showModal({
									title: '保存成功',
									content: '图片已成功保存到相册',
									showCancel: false
								});
							},
							complete(res) {
								console.log(res);
				        uni.hideLoading();
							}
						});
					}
				});
			},
      onPopupChange(e) {
        if (!e.show) {
          return
        }

        this.init()
      },
    },
  }
</script>

<style scoped lang="scss">
  .canvas {
    border-radius: 48rpx;
  }

  .btn {
    margin-top: 32rpx;
    width: 100%;
    padding: 22rpx 0;
    box-sizing: border-box;
    font-family: PingFang SC;
    font-weight: 500;
    font-size: 36rpx;
    line-height: 1.4;
    color: #FFFFFF;
    background: linear-gradient(to right, #21FEEC, #019AF9);
    border: 2rpx solid #00A9FF;
    border-radius: 41rpx;
  }
</style>