const common = require('../common.js');
const parse = require('./blueParse/LSCabinet.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 app = getApp();
const MTU = 115;
var isStart = 0; //0 未开始 1 已开始 2进行中 3已完成
var timeOut = 0; //超时次数
var deviceData = {};
function acceptDevice(device) {
    return device.btid ? true : false;
}
function isSingleBt() {
    return true;
}
function isDevice(device, data) {
    const advertisData = new Uint8Array(data.advertisData);
    const mac = device.btid
        .split('')
        .map((p, i) => parseInt(p + device.btid[i + 1], 16))
        .filter((p, i) => i % 2 == 0);
    if (advertisData.slice(0, 4).toString() == [9, 255, 1, 2].toString() && advertisData.slice(4, 10).toString() == mac.toString()) {
        return true;
    }
    return false;
}
function sendCommand(cmd, data = []) {
    data = [cmd, data.length].concat(data);
    return common.completArrayCRC(data, data.length);
}

//换电指令
function sendExchangeCommand(data) {
    deviceData = data;
    app.globalData.deviceBTBMSBuf[data.mac_id] = {
        bms_origin_data: null
    };
    return [togetherCommand([1, 1], data)];
}

//租电指令
function sendHireCommand(data) {
    deviceData = data;
    app.globalData.deviceBTBMSBuf[data.mac_id] = {
        bms_origin_data: null
    };
    return [togetherCommand([2, 1], data)];
}

//还电指令
function sendBackCommand(data) {
    deviceData = data;
    app.globalData.deviceBTBMSBuf[data.mac_id] = {
        bms_origin_data: null
    };
    return [togetherCommand([3, 1], data)];
}

//确认指令 (序列号，密钥，消息头)
function sendConfirmCommand(value, serialNum) {
    app.globalData.deviceBTBMSBuf[deviceData.mac_id] = {
        bms_origin_data: null
    };
    return [confirmCommand(value, serialNum, deviceData.key)];
}

//取消确认指令
function sendCancelCommand(serialNum) {
    app.globalData.deviceBTBMSBuf[deviceData.mac_id] = {
        bms_origin_data: null
    };
    var body = [confirmCommand([4, 1], serialNum, deviceData.key)];
    return body;
}

//获取柜体信息
function sendGetCabinetInfoCommand(data) {
    isStart = 1;
    deviceData = data;
    app.globalData.deviceBTBMSBuf[data.mac_id] = {
        bms_origin_data: null
    };
    deviceData.serialNum = new Date().getTime().toString();
    return [confirmCommand([6, 1], deviceData.serialNum, deviceData.key)];
}

//开仓指令

// 鉴权
function alterConnect(device, deviceId) {
    return [sendCommand(1, [171, 205, 171, 205])];
}
function readData(device, value, data) {
    var value = new Uint8Array(value);
    console.log('接收到的指令');
    console.log(value);
    let macid = device.mac_id;
    if (value[value.length - 1] === 120 && value[0] === 122) {
        //单包封包直接结束
        var bms_data = value;
        app.globalData.deviceBTBMSBuf[macid].bms_origin_data = bms_data;
        var json = getCompleteData(bms_data);
        app.globalData.deviceBTBMSBuf[macid].bms_origin_data = null;
        return json;
    }
    if (value[value.length - 1] !== 120 && value[0] === 122) {
        //分包开头
        var bms_data = value;
        app.globalData.deviceBTBMSBuf[macid].bms_origin_data = bms_data;
    }
    if (value[value.length - 1] !== 120 && value[0] !== 122) {
        //分包中间过程封包
        var bms_data = mergeUint8Array(app.globalData.deviceBTBMSBuf[macid].bms_origin_data, value);
        app.globalData.deviceBTBMSBuf[macid].bms_origin_data = bms_data;
    }
    if (value[value.length - 1] === 120 && value[0] !== 122) {
        //分包结束
        var bms_data = mergeUint8Array(app.globalData.deviceBTBMSBuf[macid].bms_origin_data, value);
        app.globalData.deviceBTBMSBuf[macid].bms_origin_data = bms_data;
        var json = getCompleteData(bms_data);
        app.globalData.deviceBTBMSBuf[macid].bms_origin_data = null;
        return json;
    }
}
function getCompleteData(value) {
    var json = parse.realData(value);
    //响应进行确认数据
    if (json.response == 1) {
        app.globalData.reponseData = json;
    }
    //上次操作未确认 发送取消指令
    json = cancleConfirm(json);
    //汇报进行确认数据
    json = reportConfirm(json, value);
    //获取电柜信息
    json = getCabintInfo(json);
    return json;
}

//上次操作未确认 发送取消指令
function cancleConfirm(json) {
    if (json.response === 1) {
        app.globalData.reportData = json;
    }
    return json;
}

//汇报进行确认数据
function reportConfirm(json, value) {
    if (json.report == 1) {
        var reportData = {};
        reportData.serialNo = json.serialNo;
        reportData.state = json.state;
        reportData.msg = json.msg;
        reportData.report = 1;
        app.globalData.reportData = reportData;
        if (value[2] === 130) {
            parse.reportCabintHire(deviceData.dev_id, json.orderNo, json);
            sendConfirmCommandBlue([2, 2], json.serialNo);
        }
        if (value[2] === 129) {
            parse.reportCabintExchange(deviceData.dev_id, json);
            sendConfirmCommandBlue([1, 2], json.serialNo);
        }
        if (value[2] === 131) {
            parse.reportCabintReturn(deviceData.dev_id, json.orderNo, json);
            sendConfirmCommandBlue([3, 2], json.serialNo);
        }
    }
    return json;
}
function sendConfirmCommandBlue(value, serialNum) {
    const bluetooth = require('../bluetooth.js');
    if (bluetooth.isConnected(deviceData.mac_id)) {
        bluetooth.sendConfirmCommand(
            deviceData.mac_id,
            value,
            serialNum,
            function () {},
            function () {}
        );
    } else {
    }
}

//获取电柜信息 蓝牙超时三次请求操作
function getCabintInfo(json) {
    if (json.command === 134) {
        if (json.state === 10000) {
            isStart = 3;
        } else {
            if (isStart === 1) {
                setTimeout(function () {
                    if (isStart !== 3) {
                        isStart = 0;
                        if (timeOut < 3) {
                            //超时次数
                            timeOut++;
                            sendGetCabinetInfoCommand(deviceData);
                        } else {
                            json.state = 10002; //失败
                            timeOut = 0;
                        }
                    }
                }, 1500);
            }
            isStart = 2;
        }
    }
    return json;
}
function confirmCommand(data, serialNum, key) {
    //标志体
    var toBody = confirmBody(serialNum, key);
    //标志头
    var toHead = [122, toBody.length + 2].concat(data);
    //标志尾
    var toFoot = getMarkFoot(toBody, data);
    var body = toHead.concat(toBody).concat(toFoot);
    return body;
}
function togetherCommand(data, device) {
    console.log('设备信息');
    console.log(device);
    //标志体
    var toBody = [];
    //下发换电
    if (data[0] === 1 && data[1] === 1) {
        toBody = loadToMsgBody(device);
    }
    if (data[0] === 2 && data[1] === 1) {
        toBody = loadToMsgBody2(device);
    }
    if (data[0] === 3 && data[1] === 1) {
        toBody = loadToMsgBody3(device);
    }
    //标志头
    var toHead = [122, toBody.length + 2].concat(data);
    //标志尾
    var toFoot = getMarkFoot(toBody, data);
    var body = toHead.concat(toBody).concat(toFoot);
    console.log('下发的机柜指令--------------');
    console.log(body);
    return body;
}

//标志尾
function getMarkFoot(toBody, hexList) {
    var total = 0;
    for (var i = 0; toBody.length > i; i++) {
        total += toBody[i];
    }
    for (var i = 0; hexList.length > i; i++) {
        total += hexList[i];
    }
    total = toBody.length + 2 + total;
    var toFoot = [total & 255, 120];
    return toFoot;
}

//标志体-确认
function confirmBody(serialNum, key) {
    var serialLen = 0;
    var serialNo = 0;
    if (serialNum !== '0') {
        //序列号长度
        var serialLen = serialNum.length;
        //序列号
        var serialNo = common.getASCIICode(serialNum);
    }
    var keyList = keyHex(key); //密钥长度 密钥索引 密钥值
    var toBody;
    if (serialNum !== '0') {
        toBody = contactList([[serialLen], serialNo]).concat(keyList);
    } else {
        toBody = [serialLen].concat(keyList);
    }
    //拼接
    return toBody;
}

//换电标志体
function loadToMsgBody(device) {
    //空仓门编号
    var empityBoxNo = parseInt(device.empityBoxNo, 16);
    //满仓门编号
    var fullBoxNo = parseInt(device.fullBoxNo, 16);
    var boxNo = [empityBoxNo].concat([fullBoxNo]);
    //电池编号长度
    var batteryNoLen = device.battertNum.length;
    //电池编号
    var batteryNo = common.getASCIICode(device.battertNum);
    //订单号长度
    var orderNoLen = device.orderNo.length;
    //订单号
    var orderNo = common.getASCIICode(device.orderNo);
    //序列号长度
    var serialLen = device.serialNum.length;
    //序列号
    var serialNo = common.getASCIICode(device.serialNum);
    //得到密钥
    var keyList = keyHex(device.key);
    var toBody = contactList([boxNo, [batteryNoLen], batteryNo, [orderNoLen], orderNo, [serialLen], serialNo]).concat(keyList);
    return toBody;
}

//租电标志体
function loadToMsgBody2(device) {
    //空仓门编号
    var boxNo = parseInt(device.boxNo, 16);
    //序列号长度
    var serialLen = device.serialNum.length;
    //序列号
    var serialNo = common.getASCIICode(device.serialNum);
    //订单号长度
    var orderNoLen = device.orderNo.length;
    //订单号
    var orderNo = common.getASCIICode(device.orderNo);
    //得到密钥
    var keyList = keyHex(device.key);
    var toBody = contactList([[boxNo], [serialLen], serialNo, [orderNoLen], orderNo]).concat(keyList);
    return toBody;
}

//还电标志体
function loadToMsgBody3(device) {
    //还电仓门编号
    var boxNo = parseInt(device.boxNo, 16);
    //电池编号长度
    var batteryNoLen = device.battertNum.length;
    //电池编号
    var batteryNo = common.getASCIICode(device.battertNum);
    //序列号长度
    var serialLen = device.serialNum.length;
    //序列号
    var serialNo = common.getASCIICode(device.serialNum);
    //订单号长度
    var orderNoLen = device.orderNo.length;
    //订单号
    var orderNo = common.getASCIICode(device.orderNo);
    //得到密钥
    var keyList = keyHex(device.key);
    console.log(keyList);
    var toBody = contactList([[boxNo], [batteryNoLen], batteryNo, [serialLen], serialNo, [orderNoLen], orderNo]).concat(keyList);
    return toBody;
}

//生成密钥
function keyHex(key) {
    //密钥索引
    //var keyIndexHex = randomHexNumber()
    var keyIndexHex = '00000002';
    var keyIndex = hexToList(keyIndexHex);
    //密钥值
    var binaryKeyIndex = binaryArray(parseInt(keyIndexHex, 16));
    var keyValue = getEncryptionKey(binaryKeyIndex, key);
    var keyValueASCII = common.getASCIICode(keyValue);
    //秘钥验证数据长度
    var keyVerifyLen = 4 + keyValue.length; //密钥索引4字节+秘钥值长度
    return contactList([[keyVerifyLen], keyIndex, keyValueASCII]);
}

//获取32位2进制数据
function binaryArray(b) {
    var array = [];
    for (var i = 31; i >= 0; i--) {
        array[i] = b & 1;
        b = b >> 1;
    }
    return array;
}

//随机8位16进制

function hexToList(str) {
    var val = [];
    for (var i = 0; i < str.length / 2; i++) {
        val.push(parseInt(str.substring(0 + i * 2, 2 + i * 2), 16));
    }
    return val;
}
function getEncryptionKey(keyList, key) {
    var keyStr = '';
    for (var i = 0; keyList.length > i; i++) {
        if (keyList[i] === 1) {
            keyStr += key.charAt(keyList.length - i - 1);
        }
    }
    var keyStr = keyStr.split('').reverse().join('');
    return keyStr;
}
function contactList(list) {
    var contactList = [];
    for (var i = 0; list.length > i; i++) {
        contactList = contactList.concat(list[i]);
    }
    return contactList;
}
function mergeUint8Array(arr1, arr2) {
    let len1 = arr1 ? arr1.length : 0;
    let len2 = arr2.length;
    let arr = new Uint8Array(len1 + len2);
    for (let i = 0; i < len1; i++) {
        arr[i] = arr1[i];
    }
    for (let i = 0; i < len2; i++) {
        arr[len1 + i] = arr2[i];
    }
    return arr;
}
module.exports = {
    readServiceID: readServiceID,
    readID: readID,
    writeServiceID: writeServiceID,
    writeID: writeID,
    MTU: MTU,
    acceptDevice: acceptDevice,
    sendGetCabinetInfoCommand: sendGetCabinetInfoCommand,
    isDevice: isDevice,
    sendHireCommand: sendHireCommand,
    sendBackCommand: sendBackCommand,
    sendExchangeCommand: sendExchangeCommand,
    sendConfirmCommand: sendConfirmCommand,
    sendCancelCommand: sendCancelCommand,
    alterConnect: alterConnect,
    readData: readData,
    isSingleBt: isSingleBt
};
