<template>
	<view class="circle-container">
		<canvas :canvas-id="canvasId" :style="{ width: size + 'px', height: size + 'px' }"></canvas>
		<view class="circle-text">
			<view class="percent">{{ percent }}<text class="mini-text">%</text></view>
			<view class="tips">充电枪正在<text class="tips-text">充电中</text></view>
		</view>
	</view>
</template>

<script>
export default {
	name: "qs-circle-percent",
	props: {
		canvasId: {
			type: String,
			default: "11", // 进度颜色
		},
		percent: {
			type: Number,
			default: 0, // 当前进度百分比
		},
		size: {
			type: Number,
			default: 200, // 圆尺寸
		},
		lineWidth: {
			type: Number,
			default: 5, // 线宽
		},
		color: {
			type: [String, Array, Object],
			default: () => "#ff7b00", // 进度颜色 - 支持单色、渐变色数组或渐变配置对象
		},
		backgroundColor: {
			type: String,
			default: "#f2f2f2", // 背景圆颜色
		},
		angle: {
			type: Number,
			default: 360, // 显示的圆弧角度（360=全圆, 180=半圆, 120=三分之一圆）
		},
		// 渐变配置参数
		gradientConfig: {
			type: Object,
			default: () => ({
				type: 'linear', // 'linear' 或 'radial'
				colorStops: [], // 渐变色停止点，如 [{offset: 0, color: '#ff7b00'}, {offset: 1, color: '#ffaa00'}]
				angle: 0 // 线性渐变角度（度）
			})
		},
	},
	data() {
		return {
			ctx: null,
		};
	},
	mounted() {
		this.$nextTick(() => {
			this.initCanvas();
		})
	},
	watch: {
		percent() {
			this.drawCircle();
		},
		angle() {
			this.drawCircle();
		},
	},
	methods: {
		initCanvas() {
			const ctx = uni.createCanvasContext(this.canvasId, this);
			this.ctx = ctx;
			this.drawCircle();
		},
		drawCircle() {
			const { ctx, percent, size, lineWidth, color, backgroundColor, angle } = this;
			const radius = (size - lineWidth) / 2;
			const center = size / 2;
			ctx.clearRect(0, 0, size, size);

			// 计算起始角度和结束角度
			const startAngle = (Math.PI / 2) + (Math.PI * (180 - angle) / 360);
			const endAngle = (Math.PI * 2 + Math.PI / 2) - (Math.PI * (180 - angle) / 360);

			// 背景弧
			ctx.beginPath();
			ctx.arc(center, center, radius, startAngle, endAngle, false);
			ctx.setStrokeStyle(backgroundColor);
			ctx.setLineWidth(lineWidth);
			ctx.setLineCap("round");
			ctx.stroke();

			// 进度弧
			const progressAngle = startAngle + ((endAngle - startAngle) * percent / 100);
			ctx.beginPath();
			ctx.arc(center, center, radius, startAngle, progressAngle, false);

			// 根据 color 类型设置颜色
			if (typeof color === 'string') {
				// 单色
				ctx.setStrokeStyle(color);
			} else if (Array.isArray(color)) {
				// 渐变色数组
				if (color.length >= 2) {
					const gradient = this.createGradient(ctx, center, radius, startAngle, progressAngle, color);
					ctx.setStrokeStyle(gradient);
				} else {
					ctx.setStrokeStyle(color[0] || "#ff7b00");
				}
			} else if (typeof color === 'object' && color.colorStops && color.colorStops.length > 0) {
				// 渐变配置对象
				const gradient = this.createGradientFromConfig(ctx, center, radius, startAngle, progressAngle, color);
				ctx.setStrokeStyle(gradient);
			} else {
				ctx.setStrokeStyle("#ff7b00");
			}

			ctx.setLineCap("round");
			ctx.setLineWidth(lineWidth);
			ctx.stroke();
			ctx.draw();
		},

		// 创建基于颜色数组的渐变
		createGradient(ctx, center, radius, startAngle, progressAngle, colorArray) {
			// 使用中心点创建径向渐变，更适合圆形
			const gradient = ctx.createLinearGradient(
				center - radius * Math.cos(startAngle),
				center - radius * Math.sin(startAngle),
				center + radius * Math.cos(progressAngle),
				center + radius * Math.sin(progressAngle)
			);

			const step = 1 / (colorArray.length - 1);
			colorArray.forEach((color, index) => {
				gradient.addColorStop(Math.min(step * index, 1), color);
			});

			return gradient;
		},

		// 根据配置对象创建渐变
		createGradientFromConfig(ctx, center, radius, startAngle, endAngle, config) {
			let gradient;

			if (config.type === 'radial') {
				// 径向渐变
				gradient = ctx.createRadialGradient(
					center,
					center,
					0,
					center,
					center,
					radius
				);
			} else {
				// 线性渐变 - 根据角度计算起点和终点
				const angleInRadians = (config.angle || 0) * Math.PI / 180;
				const halfRadius = radius * 0.7; // 调整半径以适配弧形
				const startX = center - halfRadius * Math.cos(angleInRadians);
				const startY = center - halfRadius * Math.sin(angleInRadians);
				const endX = center + halfRadius * Math.cos(angleInRadians);
				const endY = center + halfRadius * Math.sin(angleInRadians);

				gradient = ctx.createLinearGradient(startX, startY, endX, endY);
			}

			// 添加颜色停止点
			config.colorStops.forEach(stop => {
				gradient.addColorStop(stop.offset, stop.color);
			});

			return gradient;
		}
	},
};
</script>

<style lang="scss" scoped>
.circle-container {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	position: relative;
}

.circle-text {
	position: absolute;
	text-align: center;
	font-size: 18rpx;
	font-weight: bold;
	color: #333;
	top: 50rpx;

	.percent {
		font-weight: 800;
		font-size: 80rpx;
		color: #2B303A;

		.mini-text {
			font-weight: normal;
			font-size: 28rpx;
		}
	}

	.tips {
		font-weight: 800;
		font-size: 24rpx;

		.tips-text {
			color: #3EB6F8;
		}
	}
}
</style>