<template>
	<view>
		<canvas type="2d" canvas-id="reusableCanvas" :width="currentCanvasWidth" :height="currentCanvasHeight"
			class="offscreen-canvas"></canvas>
	</view>
</template>

<script>
	export default {
		name: "textToDotMatrix",
		props: {
			txts: {
				type: Array,
				default: () => [],
				validator: (value) => value.every(item => typeof item === 'string')
			},
			
			fontSize: {
				type: Number,
				default: 16,
				validator: (value) => value > 0 && value <= 100
			},
			bgColor: {
				type: String,
				default: "#ffffff"
			},
			color: {
				type: String,
				default: "#000000"
			}
		},
		data() {
			return {
				// 当前Canvas的宽高（动态调整）
				currentCanvasWidth: 0,
				currentCanvasHeight: 0,
				// Canvas上下文（复用）
				ctx: null
			};
		},
		computed: {
			validTxts() {
				return this.txts.filter(line => line.trim() !== '');
			}
		},
		mounted() {
			// 初始化Canvas上下文（只创建一次）
			this.ctx = uni.createCanvasContext('reusableCanvas', this);
		},
		methods: {
			/**
			 * 估算单行文本所需的Canvas宽度
			 */
			calcLineWidth(textLine) {
				return textLine.length * this.fontSize;
			},

			/**
			 * 清除Canvas内容
			 */
			clearCanvas() {
				this.ctx.setFillStyle('#FFFFFF');//this.bgColor
				this.ctx.fillRect(0, 0, this.currentCanvasWidth, this.currentCanvasHeight);
			},

			/**
			 * 复用单个Canvas处理所有文本行
			 */
			async drawAndGetPixels() {
				let binaryToHex = (binaryArray) => {
					if (!Array.isArray(binaryArray) || binaryArray.length !== 8) {
						throw new Error("输入必须是包含8个元素的二进制数组");
					}

					// 检查每个元素是否为0或1
					if (!binaryArray.every(bit => bit === 0 || bit === 1)) {
						throw new Error("数组元素必须只能是0或1");
					}

					// 将二进制数组转换为十进制数
					let decimalValue = 0;
					for (let i = 0; i < 8; i++) {
						// 计算每个位的权重并累加
						decimalValue += binaryArray[i] * Math.pow(2, 7 - i);
					}

					// 将十进制转换为十六进制字符串，并添加0x前缀
					const hexString = "0x" + decimalValue.toString(16).padStart(2, '0').toUpperCase();

					return hexString;
				}

				let convertCharToMatrix = (imageData, item) => {
					// console.log("imgOldData=", imageData)
					let matrix = [];



					let arr = [];
					for (let y = 0; y < this.fontSize; y++) {
						for (let x = 0; x < 16; x++) {
							// 计算像素在imageData中的索引 (RGBA格式)
							let index = (y * 16 + x) * 4;
							let R = imageData[index];
							let G = imageData[index+1];
							let B = imageData[index]+2;
							
							// let r = imageData[i];
							// let g = imageData[i+1];
							// let b = imageData[i+2];
							
							
							let gray = (R + G + B) / 3;
							let bit = gray < 255 ? 1 : 0;
							
							
							// 黑色像素（R值较低）视为1，白色视为0
							// let isBlack = R < 128 ? 1 : 0;
							arr.push(bit);

						}
					}
			

					let firstHalf = arr.slice(0, arr.length / 2); // [1, 2, ..., 128]
					let secondHalf = arr.slice(arr.length / 2); // [129, 130, ..., 256]



					for (let i = 0; i < this.fontSize; i++) {
						let tmp = [];
						for (let index = i; index < firstHalf.length; index += this.fontSize) {
							tmp.push(firstHalf[index]);
						}
						tmp = tmp.reverse();
						// console.log("tmp=",tmp.join(""));
						matrix.push(binaryToHex(tmp));

					}

					for (let i = 0; i < this.fontSize; i++) {
						let tmp = [];
						for (let index = i; index < secondHalf.length; index += this.fontSize) {
							tmp.push(secondHalf[index]);
						}
						tmp = tmp.reverse();

						matrix.push(binaryToHex(tmp));

					}


					
					// console.log("matrix=", matrix);
					return matrix;
				}

				let drawTxt = async (textLine) => {
					let result = {};
					let ctx = this.ctx;

					// 1. 动态调整Canvas尺寸
					this.currentCanvasWidth = this.calcLineWidth(textLine);
					this.currentCanvasHeight = 16;

					// 2. 清空Canvas（绘制背景）
					this.clearCanvas();

					// 3. 设置文字样式
					ctx.setFillStyle('#000000');//this.color
					ctx.setTextBaseline('middle');
					// ctx.setTextAlign('center')
					ctx.setFontSize(this.fontSize);
					ctx.font = `${this.fontSize}px PingFangBold", "PingFang SC", Arial, sans-serif`;

					// 4. 绘制当前行文本
					let currentX = 0;
					let currentY = this.fontSize / 2;
					for (let j = 0; j < textLine.length; j++) {
						let char = textLine[j];
						ctx.fillText(char, currentX, currentY);
						// 按实际字符宽度计算间距
						let charWidth = ctx.measureText(char).width;
						currentX += charWidth;
					}

					// 5. 异步绘制并获取像素数据（串行处理避免冲突）
					await new Promise((resolve, reject) => {
						ctx.draw(false, () => {
							uni.canvasGetImageData({
								canvasId: 'reusableCanvas',
								x: 0,
								y: 0,
								width: this.currentCanvasWidth,
								height: this.currentCanvasHeight,
								success: res => {
									console.log("获取到像素数据,",res.data.length/4)
									result = {
										line: textLine,
										pixelData: res.data,
										width: this.currentCanvasWidth,
										height: this.currentCanvasHeight
									};
									resolve();
								},
								fail: err => {
									// console.error(`处理第${i+1}行失败:`, err);
									reject(err)
								}
							});
						});
					});

					return result;
				}
				let arr = [];
				// 循环处理每行文本
				for (let i = 0; i < this.validTxts.length; i++) {

					let linePixls = [];
					let item = this.validTxts[i];
					// console.log("item=", item);
					for (var j = 0; j < item.length; j++) {
						let result = await drawTxt(item[j]);
						linePixls.push(convertCharToMatrix(result.pixelData, item));
					}
					// console.log("hexs=", linePixls.join(","));
					arr.push(linePixls);
				}

				return arr;
			}
		}
	};
</script>

<style>
	.offscreen-canvas {
		position: fixed;
		left: -9999px;
		top: -9999px;
		visibility: hidden;
	}
</style>