<template>
	<view class="lottery-grid" :style="[gridStyle]">
		<view v-for="(item, index) in gridItems" :key="index" :class="['grid-item', { 'prize-item': !item.isCenter }]">
			<template v-if="!item.isCenter">
				<slot :item="item" :index="index">
					<view class="grid-item-content" :style="[getItemStyle(item, index)]">
						<image class="grid-item-content-bg" v-if="gridItemBg" :src="gridItemBg"></image>
						<image class="grid-item-content-img" :src="item.simple_img" mode="widthFix"></image>
						<view class="grid-item-content-text">{{ item.show_text }}</view>
					</view>
				</slot>
			</template>
		</view>
		<view class="start-btn" :style="[startButtonStyle]" @click="!isRunning ? $emit('centerButtonClick') : null">
			<slot name="centerButton" v-if="$slots && $slots.centerButton"></slot>
			<view class="start-btn-content" v-else>
				{{ isRunning ? '抽奖中...' : '开始' }}
			</view>
		</view>
	</view>
</template>

<script>
	export default {
		props: {
			rows: {
				type: Number,
				default: 3,
			},
			cols: {
				type: Number,
				default: 3,
			},
			minSpeed: {
				type: Number,
				default: 50,
			},
			maxSpeed: {
				type: Number,
				default: 300,
			},
			accelerationRate: {
				type: Number,
				default: 2,
			},
			gridItemBg: {
				type: String,
				default: '',
			},
			//
			prizes: {
				type: Array,
				required: true,
			},
			// 新增 prizeItemStyle prop
			prizeItemStyle: {
				type: Object,
				default: () => ({
					borderRadius: '10rpx',
					fontWeight: '500',
					fontSize: '18rpx',
					color: '#CB1316',
				}),
			},
			// 新增 activeItemStyle prop
			activeItemStyle: {
				type: Object,
				default: () => ({
					backgroundColor: '#FF622B',
					color: '#FFF',
				}),
			},
		},
		data() {
			return {
				isRunning: false, // 抽奖是否正在进行
				currentIndex: -1, // 当前高亮的格子索引
				targetIndex: -1, // 最终停止的目标索引
				speed: 50, // 初始转动速度（毫秒）
				rounds: 0, // 经完成的轮数
				minRounds: 3, // 最小旋转轮数
				totalSteps: 0, // 总步数（用于控制停止）
				gridItems: [], // 存储所有格子信息的数组
				sequence: [], // 存储边缘格子索引的数组（按顺时针顺序）
				timerId: null, // 新增：定时器ID，用于清除未执行的定时器
			};
		},
		computed: {
			gridStyle() {
				return {
					gridTemplateColumns: `repeat(${this.cols}, 1fr)`,
					gridTemplateRows: `repeat(${this.rows}, 1fr)`,
				};
			},
			startButtonStyle() {
				return {
					gridArea: `2 / 2 / ${this.rows} / ${this.cols}`,
				};
			},
		},
		created() {
			this.validatePrizes();
			this.initializeGrid();
		},
		beforeDestroy() {
			// 新增：组件销毁前清除定时器，避免内存泄漏
			this.clearLotteryState();
		},
		methods: {
			validatePrizes() {
				const prizeSlots = (this.rows * this.cols) - (this.rows - 2) * (this.cols - 2); // 减去中心格子
				if (this.prizes.length !== prizeSlots) {
					throw new Error(
						`奖品数量不匹配。需要 ${prizeSlots} 个奖品，但提供了 ${this.prizes.length} 个。`,
					);
				}
				// 新增：验证每个奖品必须有唯一的id
				const prizeIds = this.prizes.map((item, idx) => {
					if (!item.id && item.id !== 0) { // 兼容0作为合法id
						throw new Error(`第 ${idx + 1} 个奖品缺少必填的id字段`);
					}
					return item.id;
				});
				// 验证id唯一性
				const uniqueIds = [...new Set(prizeIds)];
				if (uniqueIds.length !== prizeIds.length) {
					throw new Error('奖品列表中存在重复的id，请检查');
				}
			},

			initializeGrid() {
				// 初始化网格项目和序列数组
				this.gridItems = [];
				this.sequence = [];
				let prizeIndex = 0;

				// 遍历行和列，创建网格项目
				for (let i = 0; i < this.rows; i++) {
					for (let j = 0; j < this.cols; j++) {
						if (this.isCenter(i, j)) {
							// 如果是中心格，添加一个中心项目
							this.gridItems.push({
								isCenter: true,
							});
						} else {
							// 否则，添加一个奖品项目
							this.gridItems.push({
								...this.prizes[prizeIndex],
								isCenter: false,
							});
							prizeIndex++;

							// 如果是边缘格，将其索引添加到序列中
							if (i === 0 || i === this.rows - 1 || j === 0 || j === this.cols - 1) {
								this.sequence.push(i * this.cols + j);
							}
						}
					}
				}

				// 调整序列顺序
				this.adjustSequence();
			},

			isCenter(row, col) {
				// 判断给定的行列是否为中心格
				return row > 0 && row < this.rows - 1 && col > 0 && col < this.cols - 1;
			},

			adjustSequence() {
				// 调整序列顺序，使其按照顺时针方向排列
				const newSequence = [];
				// 上边
				for (let j = 0; j < this.cols; j++) {
					newSequence.push(j);
				}
				// 右边
				for (let i = 1; i < this.rows - 1; i++) {
					newSequence.push(i * this.cols + this.cols - 1);
				}
				// 下边
				for (let j = this.cols - 1; j >= 0; j--) {
					newSequence.push((this.rows - 1) * this.cols + j);
				}
				// 左边
				for (let i = this.rows - 2; i > 0; i--) {
					newSequence.push(i * this.cols);
				}
				this.sequence = newSequence;
			},

			// 新增：根据奖品ID查找其在sequence中的索引
			getTargetIndexById(prizeId) {
				const targetSeqIndex = this.sequence.findIndex(seqItem => {
					const gridItem = this.gridItems[seqItem];
					return gridItem.id === prizeId;
				});
				if (targetSeqIndex === -1) {
					throw new Error(`未找到id为「${prizeId}」的奖品，请检查奖品列表`);
				}
				return targetSeqIndex;
			},

			/**
			 * 开始抽奖（修改：参数改为奖品ID）
			 * @param {string|number} prizeId - 中奖奖品的唯一ID
			 */
			startLottery(prizeId) {
				// 开始抽奖
				if (this.isRunning) return;
				// 初始化抽奖参数
				this.isRunning = true;
				this.speed = 50;
				this.rounds = 0;
				// 核心修改：通过ID获取目标索引
				this.targetIndex = this.getTargetIndexById(prizeId);
				// 计算总步数
				this.totalSteps = this.minRounds * this.sequence.length + this.targetIndex + 1;
				// 开始运行抽奖
				this.runLottery();
			},

			runLottery() {
				// 先清除之前的定时器（防止多个定时器叠加）
				if (this.timerId) {
					clearTimeout(this.timerId);
				}
				
				// 运行抽奖过程
				this.currentIndex++;
				// 如果到达序列末尾，重置索引并增加轮数
				if (this.currentIndex >= this.sequence.length) {
					this.currentIndex = 0;
					this.rounds++;
				}

				// 计算当前步数
				const currentStep = this.rounds * this.sequence.length + this.currentIndex;

				// 如果达到总步数，结束抽奖
				if (currentStep >= this.totalSteps - 1) {
					this.currentIndex = this.targetIndex;
					this.isRunning = false;
					// 触发抽奖结束事件
					this.$emit('lottery-end', this.gridItems[this.sequence[this.currentIndex]]);
					return;
				}

				// 修改速度计算逻辑
				const progress = currentStep / this.totalSteps;
				this.speed = this.calculateSpeed(progress);

				// 保存定时器ID
				this.timerId = setTimeout(() => this.runLottery(), this.speed);
			},

			calculateSpeed(progress) {
				// 使用父组件传入的参数计算速度
				return (
					this.minSpeed +
					(this.maxSpeed - this.minSpeed) * Math.pow(progress, this.accelerationRate)
				);
			},

			isActive(index) {
				// 判断给定索引是否为当前活动项
				if (!this.isRunning && this.currentIndex === -1) return false;
				return this.sequence[this.currentIndex] === index;
			},

			// 移除 getItemStyle 方法，因为我们现在直接在模板中处理样式
			getItemStyle(item, index) {
				if (item.isCenter) {
					return {};
				}
				if (this.isActive(index)) {
					return {
						...this.prizeItemStyle,
						...this.activeItemStyle,
					};
				}
				return this.prizeItemStyle;
			},

			/**
			 * 新增：清除抽奖状态（重置所有抽中/运行状态）
			 * @param {boolean} emitEvent - 是否触发状态清除事件，默认true
			 */
			clearLotteryState(emitEvent = true) {
				// 1. 清除定时器（防止抽奖过程中清除后仍继续执行）
				if (this.timerId) {
					clearTimeout(this.timerId);
					this.timerId = null;
				}
				
				// 2. 重置核心状态变量
				this.isRunning = false;
				this.currentIndex = -1; // 清除高亮索引
				this.targetIndex = -1;
				this.speed = this.minSpeed;
				this.rounds = 0;
				this.totalSteps = 0;
				
				// 3. 可选：触发状态清除事件，通知父组件
				if (emitEvent) {
					this.$emit('lottery-state-cleared');
				}
			},
		},
	};
</script>

<style scoped>
	.lottery-grid {
		display: grid;
		grid-gap: 10rpx;
		width: 100%;
		height: 100%;
		max-width: 500px;
		max-height: 500px;
		margin: 0 auto;
		position: relative;
	}

	.grid-item {
		display: flex;
		justify-content: center;
		align-items: center;
		font-size: 14px;
		aspect-ratio: 1;
		/* padding: 4rpx;
		width: 141rpx;
		height: 141rpx; */
	}

	.grid-item-content {
		position: relative;
		display: flex;
		flex-direction: column;
		align-items: center;
		justify-content: center;
		width: 100%;
		height: 100%;
		background: #FEE9CE;
		border-radius: 20rpx;
		border: 4rpx solid #FEDEBE;
		box-sizing: border-box;
	}

	.grid-item-content-bg {
		position: absolute;
		top: 0;
		left: 0;
		width: 100%;
		height: 100%;
	}

	.grid-item-content-img {
		width: 56%;
		/* height: 50%; */
		position: relative;
		z-index: 9;
	}

	.grid-item-content-text {
		margin-top: 10rpx;
		position: relative;
		z-index: 1;
	}

	.prize-item {
		/* 移除默认样式，由父组件控制 */
	}

	.start-btn {
		position: absolute;
		cursor: pointer;
		width: 100%;
		height: 100%;
	}

	.start-btn-content {
		display: flex;
		justify-content: center;
		align-items: center;
		background-color: #ff6b6b;
		color: white;
		font-weight: bold;
		font-size: 18px;
		width: 100%;
		height: 100%;
		border-radius: 10rpx;
	}
</style>