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();

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) {
    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() == [0x09, 0xff, 0x01, 0x02].toString() && advertisData.slice(4, 10).toString() == mac.toString()) {
        return true;
    }

    return false;
} // function alterConnect(device, deviceId) {
//   return [sendCommand(0x01, [0xAB, 0xCD, 0xAB, 0xCD])]
// }

function readData(device, value, data) {
    var value = new Uint8Array(value);

    switch (value[0]) {
        case 0x44:
            //data.quantity = value[2]
            break;

        case 0x42:
            //data = FMBMS.BMSReply(value.slice(2, 2 + value[1]), data)
            packBmsData(device, value, data);
            break;
    }

    return data;
}

function packBmsData(device, value, data) {
    let macid = device.mac_id;
    let total_len = (value[1] << 8) | value[2];

    if (total_len < 50) {
        console.log('部分数据回应，丢弃');
        realWriteData(device, [[0xa2, 0x00, 0xa2]]);
        return false;
    }

    let bms_data = value.slice(5, -1);

    if (app.globalData.deviceBTBMSBuf[macid]) {
        // 已经有bms数据
        if (bms_data[0] == 0x4e && bms_data[1] == 0x57) {
            // 此时收到的头部为bms头，丢弃
            // 丢弃
            console.log('之前的数据:');
            console.log(app.globalData.deviceBTBMSBuf[macid].bms_origin_data);
            console.log('覆盖之前的数据');
            app.globalData.deviceBTBMSBuf[macid].bms_origin_data = bms_data;
            console.log('新的数据：');
        } else {
            app.globalData.deviceBTBMSBuf[macid].bms_origin_data = mergeUint8Array(app.globalData.deviceBTBMSBuf[macid].bms_origin_data, bms_data);
        }
    } else {
        // 没有收到过bms
        if (bms_data[0] != 0x4e || bms_data[1] != 0x57) {
            // 不是bms头部标识
            // 丢弃
            console.log('丢弃包');
            app.globalData.deviceBTBMSBuf[macid].bms_origin_data = null;
            realWriteData(device, [[0xa2, 0x00, 0xa2]]); //realWriteData(device, [[0xa2, 0x01, 0xa2]])

            return false;
        }

        app.globalData.deviceBTBMSBuf[macid] = {
            bms_origin_data: bms_data
        };
    }

    console.log('BMS 数据');
    console.log(app.globalData.deviceBTBMSBuf[macid].bms_origin_data);
    realWriteData(device, [[0xa2, 0x00, 0xa2]]);

    if (total_len == app.globalData.deviceBTBMSBuf[macid].bms_origin_data.length) {
        console.log('收到一个完整包');
        let bmsOriginData = app.globalData.deviceBTBMSBuf[macid].bms_origin_data;
        app.globalData.deviceBTBMSBuf[macid].bms_origin_data = null;
        FMBMS.BMSReply(bmsOriginData, data);
        return true;
    }

    return false;
}

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;
}

function getDeviceIdByMacid(macid) {
    let deviceid = '';

    for (let i = 0; i < macid.length; i++) {
        if (i != 0 && i % 2 == 0) deviceid += ':';
        deviceid += macid[i];
    }

    return deviceid;
}

function realWriteData(device, data, callback = () => {}, fail = () => {}) {
    if (data.length == 0) return;
    let deviceId = getDeviceIdByMacid(device.mac_id);
    const buffer = common.toArrayBuffer(data.shift());
    console.log(buffer);
    uni.writeBLECharacteristicValue({
        deviceId: deviceId,
        serviceId: writeServiceID,
        characteristicId: writeID,
        value: buffer,

        success(res) {
            console.log('分包回复成功');
            console.log(res);

            if (data.length == 0) {
                callback(res);
            } else {
                setTimeout(() => {
                    writeData(device, deviceId, data, callback, fail);
                }, 500);
            }
        },

        fail(res) {
            console.log('分包回复失败');
            console.log(res);
            fail(res);
        }
    });
}

function sendCommand(cmd, data = []) {
    //data = [cmd, data.length].concat(data)
    if (cmd == 0x02) {
        data = [cmd, (data.length & 0xff00) >> 8, data.length & 0x00ff, data.length, 0].concat(data);
    } else {
        data = [cmd, data.length].concat(data);
    }

    return common.completArrayCRC(data, data.length);
}

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 bmsChargingMOS(value) {
    return [sendCommand(0x02, FMBMS.bmsChargingMOS(value))];
}

function bmsDischargeMOS(value) {
    return [sendCommand(0x02, FMBMS.bmsDischargeMOS(value))];
}

function bmsInfo(device, deviceId, info) {
    let power = info.voltage * info.current * 0.001;
    if (power < 0) power = power * -1;
    return {
        state: {
            voltage: info.voltageList ? info.voltageList : [],
            temp: info.temp ? [info.temp] : [],
            voltageAll: info.voltage ? info.voltage : 0,
            current: info.current ? info.current : 0,
            soc: info.soc ? info.soc : 0,
            maxVoltage: info.maxVoltage,
            minVoltage: info.minVoltage,
            maxTemp: info.temp,
            minTemp: info.temp,
            chargeState: info.chargeState,
            socAH: info.soc * 0.01 * info.capacity,
            count: info.count,
            tempCount: info.tempCount,
            cycle: info.cycle,
            equilibrium: info.equilibrium,
            chargingMOS: info.chargeProtectState,
            dischargeMOS: info.dischargeProtectState,
            averageVoltage: info.sumVoltage / info.count,
            voltagDifference: info.maxVoltage - info.minVoltage,
            power: power,
            capacity: info.capacity,
            firmware: info.firmware,
            dischargeMOSOnOff: info.dischargeProtectState,
            chargingMOSOnOff: info.chargeProtectState
        },
        btsets: [
            {
                class: '高低温保护阀值',
                name: 'AU10',
                vars: [
                    {
                        label: '低温保护阀值',
                        name: 'AU100',
                        type: 'number',
                        value: ''
                    },
                    {
                        label: '高温保护阀值',
                        name: 'AU101',
                        type: 'number',
                        value: ''
                    }
                ]
            },
            {
                class: '充放电保护电压',
                name: 'AU12',
                vars: [
                    {
                        label: '充电保护电压',
                        name: 'AU120',
                        type: 'number',
                        value: ''
                    },
                    {
                        label: '放电保护电压',
                        name: 'AU121',
                        type: 'number',
                        value: ''
                    }
                ]
            },
            {
                class: '充放电保护开关',
                name: 'AU13',
                vars: [
                    {
                        label: '充电保护',
                        name: 'AU130',
                        type: 'radio',
                        option: [
                            {
                                label: '关闭',
                                value: '0'
                            },
                            {
                                label: '开启',
                                value: '1'
                            }
                        ],
                        value: ''
                    },
                    {
                        label: '放电保护',
                        name: 'AU131',
                        type: 'radio',
                        option: [
                            {
                                label: '关闭',
                                value: '0'
                            },
                            {
                                label: '开启',
                                value: '1'
                            }
                        ],
                        value: ''
                    }
                ]
            },
            {
                class: '充放电保护恢复电压',
                name: 'AU14',
                vars: [
                    {
                        label: '充电保护恢复电压',
                        name: 'AU140',
                        type: 'number',
                        value: ''
                    },
                    {
                        label: '放电保护恢复电压',
                        name: 'AU141',
                        type: 'number',
                        value: ''
                    }
                ]
            },
            {
                class: '高低温保护恢复值',
                name: 'AU15',
                vars: [
                    {
                        label: '低温保护恢复值',
                        name: 'AU150',
                        type: 'number',
                        value: ''
                    },
                    {
                        label: '高温保护恢复值',
                        name: 'AU151',
                        type: 'number',
                        value: ''
                    }
                ]
            },
            {
                class: '电池循环次数',
                name: 'AU16',
                vars: [
                    {
                        label: '循环次数',
                        name: 'AU160',
                        type: 'number',
                        value: ''
                    }
                ]
            },
            {
                class: 'BMS自动保护开关',
                name: 'AU17',
                vars: [
                    {
                        label: '自动保护',
                        name: 'AU170',
                        type: 'radio',
                        option: [
                            {
                                label: '关闭',
                                value: '0'
                            },
                            {
                                label: '开启',
                                value: '1'
                            }
                        ],
                        value: ''
                    }
                ]
            }
        ]
    };
}

function bmsSet(device, deviceId, name, vars) {
    return false;
}

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,
    bmsInfo: bmsInfo,
    bmsSet: bmsSet,
    isSingleBt: isSingleBt,
    haveBms: haveBms,
    bmsChargingMOS: bmsChargingMOS,
    bmsDischargeMOS: bmsDischargeMOS
};
