const common = require('../common.js');

const FMBMS = require('./FMBMS.js');

const readServiceID = '0000FEE7-0000-1000-8000-00805F9B34FB';
const readID = '000036F6-0000-1000-8000-00805F9B34FB';
const writeServiceID = '0000FEE7-0000-1000-8000-00805F9B34FB';
const writeID = '000036F5-0000-1000-8000-00805F9B34FB';
const MTU = 115;
const app = getApp();
let subIndex = -1
let commands = []; // 升级包指令数组，每个指令是一个 ArrayBuffer
let currentCommandIndex = 1;

function acceptDevice(device) {
	return device.btid ? true : false;
}

function isSingleBt() {
	console.log('是单蓝牙');
	return true;
}

function haveBms() {
	console.log('是单蓝牙并且带bms');
	return true;
}

function isDevice(device, data) {
	// console.log(device,data,'device111');
	const advertisData = new Uint8Array(data.advertisData);
	// console.log(advertisData,'判断返回第几个字段是正常模式还是升级模式');
	//打印返回广播 判断返回字段是正常模式还是升级模式
	// console.log(advertisData.slice(4, 10).toString(),'device2222');
	const mac = device.btid
		.split('')
		.map((p, i) => parseInt(p + device.btid[i + 1], 16))
		.filter((p, i) => i % 2 == 0);

	// if ( advertisData.slice(4, 10).toString() == "095A5832") {
	//     return true;
	// }
	// if (data.name === "ZX2202220000000") {
	if (data.name === "865416038002201") {
		return true
	}

	return false;
}

function alterConnect(device, deviceId) {
	//登录 crc[0x1F,0x0F,0x5A,0x58,0x32,0x32,0x30,0x32,0x32,0x32,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x08,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x67,0xAC,0x53,0xE7,0x08,0x00]
	//登录 [[0x22,0x22,0x01,0x1F,0x0F,0x5A,0x58,0x32,0x32,0x30,0x32,0x32,0x32,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x08,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x67,0xAC,0x53,0xE7,0x08,0x00,crc_data,0xAA,0xAA]]
	//时间戳 0x67AC53E7 0x65,0xB3,0xED,0x6F 16:00:05
	//切换正常，工厂下发指令 [[0x22,0x22,0x54,0x01,0x01,0x12,0xAA,0xAA]]
	//OTA 升级指令 [[0x22,0x22,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,n,0xCB,0xAA,0xAA]]

	// const data = [0x1F, 0x0F, ,0x5A,0x58, 0x35, 0x32, 0x30, 0x32, 0x32, 0x32, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
	
	const data=[ 0x1F, 0x0F,0x38, 0x36, 0x35, 0x34, 0x31, 0x36, 0x30, 0x33, 0x38, 0x30, 0x30, 0x32, 0x32, 0x30, 0x31,0x08, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x67, 0xAC, 0x53, 0xE7, 0x08, 0x00]
	// console.log(data,'datatest');
	const crc_data = crc8IEEE8023(data)
	// console.log(crc_data, 111);
	// 示例数据（16进制字符串转换为字节数组）
	// const hexString = "1F0F38363534313630333830303232303108313233343536373867AC53E70800";
	// const byteArray = hexString.match(/.{1,2}/g).map(byte => parseInt(byte, 16));
	// console.log(byteArray,'byteArray');
	// 计算 CRC-8 IEEE 802.3 校验值
	// const crcResult = crc8IEEE8023(byteArray).toString(16).toUpperCase();
	// console.log("CRC-8 IEEE 802.3 Checksum:", crcResult.toString(16).toUpperCase());
	return [
		[0x22, 0x22, 0x01, 0x1F, 0x0F, 0x38, 0x36, 0x35, 0x34, 0x31, 0x36, 0x30, 0x33, 0x38, 0x30, 0x30, 0x32, 0x32, 0x30, 0x31, 0x08, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x67, 0xAC, 0x53, 0xE7, 0x08, 0x00,
			crc_data, 0xAA, 0xAA
		]
	]
	//return [sendCommand(0x01, [0xAB, 0xCD, 0xAB, 0xCD])]
}

function crc8IEEE8023(data) {
    const poly = 0x07; // IEEE 802.3 polynomial x^8 + x^2 + x + 1
    let crc = 0x00;

    for (let i = 0; i < data.length; i++) {
        crc ^= data[i];
        for (let j = 0; j < 8; j++) {
            if (crc & 0x80) {
                crc = ((crc << 1) ^ poly) & 0xFF;
            } else {
                crc = (crc << 1) & 0xFF;
            }
        }
    }
    return crc;
}



//收到硬件方向软件方发送的数据
function readData(device, value, data) {
	// console.log(value, 'test1111');
	var value = new Uint8Array(value);
	
	const normalArray = Array.from(value); // 或 [...uint8Array]
	console.log(normalArray, 'value**************************');
	// switch (value[0]) {
	// 		case 0:
	// 			//登陆成功准备
	// 			switchFactory(device)
	// 			break;
	// 	}
	switch(normalArray[3]){
		case 0x00:
		sendNextCommand(device.mac_id)
		break;
		
		case 0x01:
		test()
		break;
	}

	return data;
}
function test(){
	currentCommandIndex=1
	console.log(commands[currentCommandIndex],'test');
}


function sendCommand(cmd, data = []) {
	const startCmd = [0x02, 0x02]
	const endCmd = [0xAA, 0xAA]
	data = startCmd.concat(cmd).concat(endCmd)
	console.log(data,'打印是否切换正常模式');
	return data
}

function stateUpdate(device, deviceId) {
	return [sendCommand(0x04), sendCommand(0x02, FMBMS
.BMSRead())]; //return [[0x02,0x00,0x15,0x15,0x00,0x4e,0x57,0x00,0x13,0x00,0x00,0x00,0x00,0x06,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x68,0x00,0x00,0x01,0x27,0x7b]]
}

function turnOn(device, deviceId) {
	return [sendCommand(0x02, FMBMS.BMSTurnOn())];
}

function turnOff(device, deviceId) {
	return [sendCommand(0x02, FMBMS.BMSTurnOff())];
}

function switchFactory(device, deviceId) {
	//切换正常，工厂模式指令
	//切换工厂模式 [[0x22,0x22,0x54,0x01,0x01,0x12,0xAA,0xAA]]
	//切换正常模式 [[0x22,0x22,0x54,0x01,0x00,0x15,0xAA,0xAA]]
	return [[0x22,0x22,0x54,0x01,0x01,0x12,0xAA,0xAA]]
	// return [sendCommand([0x54, 0x01, 0x01, 0x12])];
}
//升级按钮
function otaUpgrade(device){
	
	const data = readBinBinarayToCommand()
	data.then(result=>{commands=result})
	
	// console.log(data,'datatest111');
	return data
}
async function readBinBinarayToCommand() {
	let res =await uni.request({
	  url: 'https://opt.bms16.com/ota.BIN', // 文件的网络地址
	  method: 'GET',
	  responseType: 'arraybuffer', // 指定响应类型为 arraybuffer
	});
	const arrayBuffer=res[1].data
	const uint8Array = new Uint8Array(arrayBuffer); // 转换为 Uint8Array
	const test = splitArrayIntoChunks(uint8Array, 80); // 分割成长度为 80 的数组
	const data =makeArr(test)
	// const tests=data.slice(data.length-3)
	// console.log(data.length,tests[0],'testtest数组');
	// console.log(tests,'tests');
	return data
}

function sendNextCommand(mac_id) {
	console.log(commands[currentCommandIndex],'command');
    if (currentCommandIndex >= commands.length) {
        console.log('所有指令发送完成');
        return;
    }
	const deviceId = Object.keys(app.globalData.connectionState).find((i) => app.globalData.connectionState[i].device.mac_id == mac_id);
    if (deviceId == undefined) {
		console.log('deviceId == undefined');
        return ;
    }
    const command = [commands[currentCommandIndex]];
	
	if(command.length==0){
		return
	}
	// 将数据转换为ArrayBuffer类型
	var buffer;
	buffer = common.toArrayBuffer(command.shift());
	// console.log(command,'command');
    uni.writeBLECharacteristicValue({
        deviceId: deviceId, // 替换为实际的设备 ID
        serviceId: writeServiceID, // 替换为实际的服务 ID
        characteristicId: writeID, // 替换为可写入的特征值 ID
        value: buffer,
        success() {
            // console.log('指令发送成功，等待设备响应');
        },
        fail(err) {
            console.error('指令发送失败', err);
        }
    });
    currentCommandIndex++;
}

function splitArrayIntoChunks(array, chunkSize) {
    const numChunks = Math.ceil(array.length / chunkSize);
    return Array.from({ length: numChunks }, (_, i) => {
        return array.slice(i * chunkSize, (i + 1) * chunkSize);
    });
}


// 处理分割后的数组
function makeArr(array) {
    const result = [];
    for (let i = 0; i < array.length; i ++) {
       
		let endPackage = 0x00
		if((i + 1) >= array.length){
			//当前是最后一次循环
			endPackage = 0x01
		}
		//协议号 30 包长度未固定array.length+8 转16进制  固件类型0x00 升级包大小(总包大小) 125396字节-》0x00,0x01,0xE9,0xD4
		let startArray = []
		const packageLen=parseInt((array[i].length+8).toString(16).toUpperCase(), 16)
		
		// const totalPackageSize=[0x00,0x00,0x01,0xE9,0xD4]
		const totalPackageSize=[0x00,0x00,0x01,0xE9,0xac]
		startArray.push(packageLen,...totalPackageSize)
		 //软件包id
		const ids=splitNumber(i)  // 0x00,0x01
		startArray.push(...ids)
		 //是否为最后一个包
		startArray.push(endPackage)
		 //软件数据包
		const formattedChunk = array[i].map(byte => `0x${byte.toString(16).padStart(2, '0')}`); // 转换为 0xXX 格式 
		startArray.push(...formattedChunk)
		// if(i==2){
		// 	console.log(startArray,'startArraystartArray');
		// }
		
		//crc检验
		const crcStr='0x'+crc8IEEE8023(startArray).toString(16).toUpperCase()
		const testCrc=parseInt(crcStr,16)
		startArray.push(crcStr)
		// if(i==2){
		// 	console.log(startArray,crcStr,testCrc,'crcStr');
		// }
		startArray.push(0xAA,0xAA)
		startArray.unshift(0x22,0x22,0x30)
        result.push(startArray);
    }
	// result.push([0x22,0x22,0x30,0x58,0x00,0x00,0x00,0xE9,0xD4,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x2C,0xAA,0xAA])
    return result;
}



function splitNumber(num) {
    // 将数字转换为字符串
    const numStr = num.toString();

    // 使用正则表达式分割字符串为两位一组
    const parts = numStr.match(/.{1,2}/g) || [];

    // 将字符串数组转换为数字数组
    let result = parts.map(part => parseInt(part, 10));

    // 如果数组长度为 1，前面补一个 0
    if (result.length === 1) {
        result = [0, ...result];
    }

    return result;
}


function dataRecursion(subPackage){
	subIndex += 1
	let endPackage = 0x00
	if(subPackage.groupedArray.length - 1 == subIndex){
		endPackage = 0x01
	}
	// let startArray = [0x22,0x22,0x30, 0x30,0x00, 0x58,0x00]
	let startArray = [0x00,0x58,0x00]
	//包长度 固件类型到前一位 0x00,0x58  0x00
	//crc  包长度到crc前一位
	//升级包大小
	 startArray = startArray.concat(decimalToHexBytes(subPackage.size,4))
	 //软件包id
	 startArray = startArray.concat(decimalToHexBytes(subIndex + 1,2))
	 //是否为最后一个包
	 startArray.push(endPackage)
	 //软件数据包
	startArray = startArray.concat(subPackage.groupedArray[subIndex])
	//crc检验
	const crcStr=crc8IEEE8023(startArray)
	startArray.push(crcStr)
	startArray.unshift(0x22,0x22,0x30)
	startArray = startArray.concat([0xAA,0xAA])
	// console.log(startArray)
	return [startArray]
}

function arrayBufferToHexWithPrefix(buffer,groupSize = 80) {
	 const uint8Array = new Uint8Array(buffer);
	  const groupedArray = [];
	  const size = uint8Array.length
	  // 遍历数据，每 groupSize 个字节为一组
	  for (let i = 0; i < size; i += groupSize) {
	    const group = Array.from(uint8Array.slice(i, i + groupSize)) // 获取当前分组
	      // .map(byte => '0x' + byte.toString(16).padStart(2, 0)); // 添加 0x 前缀
	    groupedArray.push(group); // 将分组添加到结果中
	  }
	
	  return {
		  size,
		  groupedArray
	  };
}

//进制转化
function decimalToHexBytes(decimal,bytes){
	const maxValue = Math.pow(2, 8 * bytes) - 1;
	 // 创建一个数组来存储字节
	    const byteArray = new Array(bytes);
	    // 将十进制数分解为字节
	    for (let i = 0; i < bytes; i++) {
	        // 每次取最低的8位（一个字节）
	        byteArray[bytes - 1 - i] = decimal & 0xff;
	        // 右移8位，处理下一个字节
	        decimal >>>= 8;
	    }
	    return byteArray;
}

module.exports = {
	readServiceID: readServiceID,
	readID: readID,
	writeServiceID: writeServiceID,
	writeID: writeID,
	MTU: MTU,
	acceptDevice: acceptDevice,
	isDevice: isDevice,
	alterConnect: alterConnect,
	readData: readData,
	stateUpdate: stateUpdate,
	turnOn: turnOn,
	turnOff: turnOff,
	isSingleBt: isSingleBt,
	haveBms: haveBms,
	switchFactory: switchFactory,
	otaUpgrade

};