<template>
	<view class="main" @click="end" >
		<!-- <view class="title-container">
			{{name}}
		</view> -->
		<view v-if="options.length>0" class="canvas-container">
			<canvas canvas-id="canvas" id="canvas" :style="canvasStyle" />
			
		</view>
		<!-- <image src="./national-2024-1.png"
		style="width: 560rpx; height: 560rpx;z-index: 999; margin-top: -560rpx;"
		></image> -->
		<image src="./national-2024-7.png"
		style="width: 660rpx; height: 640rpx;z-index: 999; margin-top: -600rpx;"
		></image>
		<image src="./national-2024-6.png" 
		style="width: 660rpx; height: 500rpx;    margin-top: -160rpx;"
		></image>
		<view class="show1" style="    position: relative;
    top: -280rpx;
    color: rgba(157, 58, 15, 1);
    font-size: 56rpx;" >
			{{name}}
		</view>
		<!-- <view v-if="showBtn" btn-container>
			<button type="primary" :disabled="isLottery" @click="playReward">{{btnTitle}}</button>
		</view> -->
	</view>
</template>
<script>
	var img2=require('./national-2024-2.png')
	var img3=require('./national-2024-3.png')
	var ctx = null;
	export default {

		props: {
			// 弹窗内容 ，当 turnModalContent=【】时，默认弹窗内容为抽奖结果，并且不展示标题
			turnModalContent: {
				type: Array,
			
				default () {
					return []
				}
			},
			// 减速，值越小，减速效果越明显 turnReduceSpeed
			turnReduceSpeed: {
				type: Number,
				default: 50
			},
			// 表示转速：表示再转多少圈再进行抽奖
			turnCircle: {
				type: Number,
				default: 0
			},
			// 转盘名称
			name: {
				type: String,
				default: "摇奖中..."
			},
			// 画布宽度
			width: {
				type: Number,
				default: 100,

			},
			// 画布高度
			height: {
				type: Number,
				default: 100
			},
			// 画布内字体大小
			fontSize: {
				type: Number,
				default: 18
			},
			// 钩子函数，抽奖开始前执行，返回值为选项列表下标，若返回值为-1，则进行随机抽奖
			setWinnerFn: {
				type: Function,
				default: null,
			},
			// // 钩子函数，抽奖开始前执行
			// beforePlay: {
			// 	type: Function,
			// 	default: null,
			// },
			// // 钩子函数，抽奖结束后执行
			// afterPlay: {
			// 	type: Function,
			// 	default: null,
			// },
			// 如果 true，则 使用组件默认的选项数据
			isUseDefaultOptions: {
				type: Boolean,
				default: false
			},
			// 选项列表
			data: {
				type: Array,
				default: []
			},
			// 是否要展示开始按钮
			showBtn: {
				type: Boolean,
				default: false,
			},
			// 按钮文本
			btnTitle: {
				type: String,
				default: "开始"
			}
		},
		data() {
			return {
				img2:img2,
				img3:img3,
				options: [{
						id: 0, // 唯一id
						name: '水饺', // 名称
						// "weight": 50, //  中奖权重，0-100
						img: '', // 展示图片
						color: "#f6e174" // 轮盘区域底色
					},
					{
						id: 2,
						name: '火锅',
						img: '',
						color: "#94494d"
					},
					{
						id: 3,
						name: '川菜',
						img: '',
						color: "#ffaa7f"
					},
					{
						id: 4,
						name: '麻辣烫',
						img: '',
						color: "#a48342"
					},
					{
						id: 5,
						name: '炸鸡汉堡',
						img: '',
						color: "#a25f81"
					}
					
				],
				isLottery: false, // 是否正在抽奖
			};
		},
		computed: {
			canvasStyle() {
				return "width:" + this.width + "rpx; height:" + this.height + "rpx;";
			},

		},
		methods: {
			end(){
				if (this.isLottery) {
					
					uni.showToast({
						title: "摇奖中...",
						icon: "none"
					})
				}else{
					this.$emit("end")
				}
			},
			async playReward() {
				if (this.isLottery) {
					return
				}
				this.isLottery = true
				let len = this.options.length
				if (len == 0) {
					return;
				}
				//console.log("playReward")
				// if (this.beforePlay) {
				// () => this.beforePlay()
				// this.beforePlay()
				this.$emit("beforePlay")
				// }

				let num = -1;
				if (this.setWinnerFn) {
					// 自定义抽奖结果
					let res = () => this.setWinnerFn(this.options)
					if (res != undefined && res >= 0) {
						num = res
					}
					 
				}

				if (num < 0) {
					// 进行权重抽奖
					let optionIndex = this.lotteryWeight(this.options)
					if (optionIndex != undefined || optionIndex >= 0) {
						num = optionIndex
					}
				}
				if (num < 0) {
					// 没有自动抽奖结果 && 没有定义选项权重，则进行随机数抽奖
					num = Math.floor(Math.random() * len)
				}

				const result = await this.roateCanvas(num)
				//console.log("抽奖结果：", result.name)
				this.name=result.name
				this.isLottery = false
				let title = ""
				let content = result.name
				if (this.turnModalContent.length > 0) {
					// 若设置了 content ，则随机取一个 content 内容，并且 title 将展示为抽奖结果 
					title = result.name
					content = this.turnModalContent[Math.floor(Math.random() * this.turnModalContent.length)]
				}
				


			},

			initBtnCanvas() {
				let angleTo = 0
				let ctx = uni.createCanvasContext("canvasBtn", this);
				// 6. 画中心点圆
				// 圆中心点的坐标 x： 宽度的一半
				let center_x = uni.upx2px(this.width)  / 2;
				// 圆中心点的坐标 y： 高度的一半
				let center_y = uni.upx2px(this.height) / 2;

				// 1. 先清除画布上在该矩形区域内的内容
				ctx.clearRect(0, 0, uni.upx2px(this.width), uni.upx2px(this.height));

				ctx.translate(center_x, center_y);

				// 6. 画中心点圆
				ctx.beginPath();
				// ctx.arc(0, 0, 15, 0, Math.PI * 2); // 15 为中心点圆的半径
				ctx.moveTo(0, -50); // 三角形顶点坐标
				ctx.lineTo(-20, 10); // 左下角坐标
				ctx.lineTo(20, 10); // 右下角坐标
				ctx.setFillStyle("#ff0000");
				ctx.fill();
				ctx.draw();
			},
			initCanvas: function(ctx, angleTo) {

				const len = this.options.length; //数组长度
				if (len == 0) {
					//console.log("options len == 0")
					return;
				}
				if (!angleTo) {
					angleTo = 0
				}
				// 圆中心点的坐标 x： 宽度的一半
				let center_x = uni.upx2px(this.width) / 2;
				// 圆中心点的坐标 y： 高度的一半
				let center_y = uni.upx2px(this.height) / 2;
				// 圆的弧度的总度数，2π表示画圆
				let totalAngle = 2 * Math.PI;
				// 平均一个选项占用的孤度数
				let avgAngle = totalAngle / len;

				let radius = center_x - 14;
				let fontSize = this.getFontSize()

				// 1. 先清除画布上在该矩形区域内的内容
				ctx.clearRect(0, 0,uni.upx2px( this.width),uni.upx2px( this.height));

				ctx.translate(center_x, center_y);
				// 2. 设置画布内字体大小
				ctx.setFontSize(fontSize);
				ctx.setLineWidth(14);
				ctx.save();

				// 3. 画外圆
				ctx.rotate(angleTo * Math.PI / 180);
				var beginAngle = 2 * Math.PI / 360 * (-90);
				// ctx.setStrokeStyle("#ffaa00");
				ctx.setStrokeStyle("#ffffff");
				ctx.arc(0, 0, radius - 3, 0, Math.PI * 2);
				ctx.stroke();

				// 4. 划分区域，并且填充颜色
				ctx.setLineWidth(0.1);
				beginAngle = 2 * Math.PI / 360 * (-90);
				//绘制填充形状
				for (var i = 0; i < len; i++) {
					ctx.save();
					ctx.beginPath();
					ctx.moveTo(0, 0);
					ctx.setStrokeStyle(this.options[i].color);
					ctx.setFillStyle(this.options[i].color);

					ctx.arc(0, 0, radius, beginAngle, beginAngle + avgAngle, false);
					//ctx.stroke();
					
					beginAngle = beginAngle + avgAngle;
					ctx.fill();
					ctx.save();
					
					
					 
				}
			
				// 5. 绘制选项文字
				beginAngle = 0; //avgAngle / 2;
				for (var i = 0; i < len; i++) {
					var ry = -(center_x / 2) - 25;
					//绘制旋转文字
					ctx.rotate((beginAngle + (avgAngle * 0.5))); //顺时针旋转
					ctx.setTextAlign("center");
					ctx.setFillStyle("#9D3A0F");
					ctx.fillText(this.options[i].name, 0, ry);
					
				
					  
					ctx.restore();
					beginAngle = beginAngle + avgAngle;
				}
				
				 var img = new Image();  
				// img.onload = function() {
					
					
					beginAngle = 0; //avgAngle / 2;
					for (var i = 0; i < len; i++) {
						
						ctx.save();
						var ry = -(center_x / 2) - 25;
						//绘制旋转文字
						ctx.rotate((beginAngle + (avgAngle * 0.5))); //顺时针旋转
					
						
						if(this.options[i].id==1){
							ctx.drawImage(this.img2,uni.upx2px(-17*2) ,uni.upx2px( -90*2), uni.upx2px(64), uni.upx2px(64));
						}else{
							ctx.drawImage(this.img3,uni.upx2px(-17*2) ,uni.upx2px( -90*2), uni.upx2px(64), uni.upx2px(64));
						}
						
						
						//  ctx.draw(true)
						  
						ctx.restore();
						beginAngle = beginAngle + avgAngle;
					}
					//ctx.draw();	 
					
				// }
				 
				//  img.src=this.img3
				  
				
				
				
				ctx.save();
				// 6. 画中心点圆
				ctx.beginPath();
				ctx.arc(0, 0, 15, 0, Math.PI * 2); // 15 为中心点圆的半径
				ctx.setFillStyle("#FFFFFF");
				ctx.fill();
				ctx.draw();
			},
			// 根据设置的权重进行抽奖
			lotteryWeight(prizes) {
				if (!prizes || prizes.length == 0) {
					//console.log("奖品列表为空")
					return -1
				}
				let winPrizesIndex = [] // 抽中的奖品下标，多个是因为如果存在多个奖品的权重一致的情况，则再进行随机抽奖
				let winPrizeWeight = 0; // 抽中的奖品的权重

				let round = Math.random() * 100; // 生成一个 0-100的随机数
				//console.log("lotteryWeight 生成的 round：", round)
				for (let index = 0; index < prizes.length; index++) {
					let prize = prizes[index];
					let weight = prize['weight']
					if (!weight) {
						// 没有设置权重，则跳过
						//console.log("奖品 ", prize.name, " 未设置权重，则不参与抽奖")
						continue
					}
					if (weight <= 0) {
						// 如果奖品的权重设置<0,则表示不参与抽奖
						//console.log("奖品 ", prize.name, " 不参与抽奖")
						continue
					}
					if (round > weight) {
						// 随机数超过了权重，则未抽中
						continue
					}
					if (weight < winPrizeWeight) {
						// 权重比之前抽中的还小，则跳过
						//console.log("奖品 ", prize.name, "小于已经抽中的奖品", winPrizeWeight, " 不参与抽奖")
						continue
					}
					if (weight == winPrizeWeight) {
						// 本次抽中的奖品和已经抽中的奖品权重一致，则加入抽中列表
						//console.log("再抽中奖品 ", prize.name, " 中奖")
						winPrizesIndex.push(index)
						continue
					}
					if (weight > winPrizeWeight) {
						// 权重比之前抽中的还大，则重置抽中奖品
						winPrizesIndex = [index]
						winPrizeWeight = weight
						//console.log("奖品 ", prize.name, " 中奖")
						continue
					}
				}
				if (winPrizesIndex.length <= 0) {
					// 本次没有抽中奖品
					//console.log("本次没有抽中奖品")
					return -1
				}
				if (winPrizesIndex.length == 1) {
					// 只抽中了一个奖品，这直接返回
					let index = winPrizesIndex[0];
					//console.log("奖品 ", prizes[index], " 抽中");
					return index
				}
				if (winPrizesIndex.length > 1) {
					// 抽中多个，则再进行随机抽奖
					//console.log(" 抽中多个，则再进行随机抽奖");
					let index = round % winPrizesIndex.length
					index = Math.floor(index)
					//console.log("再次抽中结果:", winPrizesIndex[index])
					return winPrizesIndex[index]

				}


				//console.log("其他抽奖情况")
				return -1

			},
			// 旋转画布，num 表示选项 options 的下标
			roateCanvas(num) {
				let len = this.options.length
				let angle = 360 / len;
				angle = num * angle + angle / 2;
				angle = angle || 0;
				angle = 360 - angle;
				angle += 360 * 5;
				if (this.turnCircle > 0) {
					let turnCircle = this.turnCircle
					// 最多只能转 10 圈
					if (turnCircle > 10) {
						turnCircle = 10
					}
					angle += 360 * turnCircle;
				}
				let that = this;
				let count = 1;
				// 减速，值越小，减速效果越明显 
				let turnReduceSpeed = this.turnReduceSpeed
				if (turnReduceSpeed == 0) {
					turnReduceSpeed = 1
				}
				let baseStep = turnReduceSpeed;
				// 起始滚动速度
				let baseSpeed = 1;
				let result = {}
				return new Promise((resolve, reject) => {
					let timer = setInterval(function() {
						
						that.initCanvas(that.ctx, count);
						if (count == angle) {
							clearInterval(timer);
							result = that.options[num];
							resolve(result)
						}
						count = count + baseStep * (((angle - count) / angle) > baseSpeed ? baseSpeed :
							((angle -
								count) / angle)) + 0.1;

						if (angle - count < 0.5) {
							count = angle;
						}
					}, 25);
				});
			},
			getFontSize() {
				let fontSize = this.fontSize
				if (this.options.length > 10) {
					if (this.fontSize >= 18) {
						fontSize = this.fontSize - (this.options.length - 10)
					}
				}

				return uni.upx2px(fontSize*2)
			},
			// 生成随机颜色
			genRandColor() {
				// 生成随机的 RGB 值
				var r = Math.floor(Math.random() * 256); // 0 到 255 之间的随机数
				var g = Math.floor(Math.random() * 256);
				var b = Math.floor(Math.random() * 256);

				// 将 RGB 值转换为 Hex 颜色表示
				var hexColor = "#" + this.componentToHex(r) + this.componentToHex(g) + this.componentToHex(b);

				return hexColor;
			},
			componentToHex(c) {
				var hex = c.toString(16);
				return hex.length === 1 ? "0" + hex : hex;
			},
			initOptions: function() {
				let defaultOptions = this.options
				if (this.isUseDefaultOptions) {
					// 使用默认数据
				} else {
					this.options = this.data
				}
				// 所有默认的颜色
				let allDefColorArr = defaultOptions.map(item => item.color);

				// 找到最大的 id
				let maxId = -Infinity;

				this.options.forEach(item => {
					if (!item.id) {
						return
					}
					if (item.id > maxId) {
						maxId = item.id;
					}
				});
				// 填充 id，确保 id 唯一
				var existIds = []
				for (var i = 0; i < this.options.length; i++) {
					let item = this.options[i]
					if (item['id'] == undefined || item.id == 0 || existIds.includes(item.id)) {
						// id 不存在，或者 id 重复了
						this.options[i]['id'] = maxId + 1
					}
					existIds.push(this.options[i].id)
					if (item['color'] == undefined || item.color == "") {

					}
				}
				// 填充颜色，确保颜色唯一
				let availableColor = JSON.parse(JSON.stringify(allDefColorArr)) // 可用颜色
				let existColor = [] // 存在颜色
				for (var i = 0; i < this.options.length; i++) {
					let item = this.options[i]
					if (item['color'] == undefined || item.color == "") {
						continue
					}
					let color = item.color
					existColor.push(color)
					// 过滤掉已经用了的 color
					availableColor = availableColor.filter(item => item !== color);

				}
				// 剩下的 allDefColorArr 都是可用的颜色
				for (var i = 0; i < this.options.length; i++) {
					let item = this.options[i]

					if (item['color'] == undefined || item.color == "") {
						if (availableColor.length == 0) {
							// 没有可用颜色了，则随机生成一个
							let color = ''
							for (var j = 0; j < 100; j++) {
								if (color != '') {
									continue
								}
								let genColor = this.genRandColor()
								if (!existColor.includes(genColor)) {
									existColor.push(color)
									color = genColor
								}
							}
							this.options[i]['color'] = color
							continue
						}
						const color = availableColor.shift();
						existColor.push(color)
						this.options[i].color = color
					}


				}
			},
			init() {
				this.initOptions();
				this.ctx = uni.createCanvasContext("canvas", this);
				this.initCanvas(this.ctx, 0);
				this.initBtnCanvas();
				this.playReward()
			}
		},
		// 初始化画布
		mounted: function() {
			//console.log("lottery mounted init......")
			this.init()
		}
	}
</script>
<style scoped>
	.main {
		display: flex;
		flex-direction: column;
		justify-content: center;
		align-items: center;
	}

	.title-container {
		font-size: 50rpx;
		margin-top: 120rpx;
		margin-bottom: 40rpx;
		z-index: 100;
	}

	.canvas-container {
		position: relative;
		width: fit-content;
		height: fit-content;
		z-index: 99;
	}

	.canvasBtn {
		position: absolute;
		top: 0%;
	}

	.canvas-btn {
		position: absolute;
		top: 50%;
		left: 50%;
		background-color: #ffffff;
		transform: translate(-50%, -50%);
		width: 110rpx;
		height: 110rpx;
		border-radius: 50%;
		line-height: 110rpx;
		text-align: center;
		font-size: 45rpx;
		text-shadow: 0 -1px 1px rgba(0, 0, 0, 0.6);
		box-shadow: 0 3px 5px rgba(0, 0, 0, 0.6);
		text-decoration: none;
	}


	/* 	.canvas-btn::before {
		content: "";
		position: absolute;
		top: -15px;
		left: 50%;
		transform: translateX(-50%);
		width: 0;
		height: 0;
		border-left: 10px solid transparent;
		border-right: 10px solid transparent;
		border-bottom: 20px solid #ffffff;
	} */

	.canvas-btn.isLottery {
		background-color: #CCCCCC;
	}

	/* 	.canvas-btn.isLottery {
		pointer-events: none;
		background: #CCCCCC;
		color: #ccc;
	} */

	/* 	.canvas-btn.isLottery::before {
		border-bottom-color: #CCCCCC;
	}

	.canvas-btn.isLottery::after {
		border-bottom-color: #CCCCCC;
	} */
</style>