import * as t from "./tools"

const app = getApp();
const WXAPI = require('../request')
/*
import { HTTP } from "../server";
*/
/**
 * 蓝牙工具类
 * 封装小程序蓝牙流程方法
 * 处理事件通信
 */
class BLEHandler {
    constructor(blename, emitter) {
        this.blename = blename //厂家自定义的蓝牙设备名称
        this.emitter = emitter
        // if(manufactureId==201){
        //     this.readCharacteristicId = "0000FFF0-0000-1000-8000-00805F9B34FB"; //能从硬件返回的信息中自动提取
        //     this.writeCharacteristicId = "0000FFF2-0000-1000-8000-00805F9B34FB";   //能从硬件返回的信息中自动提取
        //     this.notifyCharacteristicId = "0000FFF1-0000-1000-8000-00805F9B34FB";  //能从硬件返回的信息中自动提取
        //     this.deviceId = ""; //蓝牙Mac地址
        //     this.serviceId = "0000FFF3-0000-1000-8000-00805F9B34FB";//具体的serviceId要自己根据硬件提供设置。
        // }else{
        this.readCharacteristicId = ""; //能从硬件返回的信息中自动提取
        this.writeCharacteristicId = "00002af1-0000-1000-8000-00805f9b34fb"; //能从硬件返回的信息中自动提取
        this.notifyCharacteristicId = "00002af0-0000-1000-8000-00805f9b34fb"; //能从硬件返回的信息中自动提取
        this.deviceId = ""; //蓝牙Mac地址
        this.serviceId = "000018f0-0000-1000-8000-00805f9b34fb"; //具体的serviceId要自己根据硬件提供设置。
        // }

        this.receivePacket = [];
        this.recPktLength = 0;
        this.recPktOffset = 0;
    }
    async openAdapter() {
        let [err, res] = await t._openAdapter.call(this);
        if (err != null) {
            this.emitter.emit("channel", {
                type: "connect",
                data: "未打开适配器"
            })
            return false;
        }
        return true
    }
    async startSearch() {
        let [err, res] = await t._startSearch.call(this);
        if (err != null) {
            return;
        }
        this.emitter.emit("channel", {
            type: "connect",
            data: "正在连接中..."
        })

    }
    async onBluetoothFound() {
        let [err, res] = await t._onBluetoothFound.call(this);
        if (err != null) {
            this.emitter.emit("channel", {
                type: "connect",
                data: "未找到设备"
            })
            return false;
        }
        return true
    }

    async getBluetoothDevices() {
        let [err, res] = await t._getBluetoothDevices.call(this);
        if (err != null) {
            this.emitter.emit("channel", {
                type: "connect",
                data: "未找到设备"
            })
            return false;
        }
        return true
    }


    async stopSearchBluetooth() {
        let [err, res] = await t._stopSearchBluetooth.call(this);
        if (err != null) {
            return;
        }
    }
    async connectBlue() {
        let [err, res] = await t._connectBlue.call(this);
        if (err != null) {
            return;
        }
    }

    async setBLEMTU() {
        let [err, res] = await t._setBLEMTU.call(this);
        if (err != null) {
            return;
        }
    }

    async getBLEServices() {
        let [err, res] = await t._getBLEServices.call(this);
        if (err != null) {
            return;
        }
    }
    async getCharacteristics() {
        let [err, res] = await t._getCharacteristics.call(this);
        if (err != null) {
            this.emitter.emit("channel", {
                type: "connect",
                data: "无法订阅特征值"
            })
            // 取消连接
            this.closeBLEConnection()
            this.closeBLEAdapter()
            wx.setStorageSync("bluestatus", "");
            return false;
        }
        this.emitter.emit("channel", {
            type: "connect",
            data: "蓝牙已连接"
        })
        wx.setStorageSync("bluestatus", "on");
        return true
    }
    async notifyBLECharacteristicValueChange() {
        let [err, res] = await t._notifyBLECharacteristicValueChange.call(this);
        if (err != null) {
            return;
        }
    }
    async closeBLEConnection() {
        let [err, res] = await t._closeBLEConnection.call(this);
        if (err != null) {
            return;
        }
    }
    async closeBLEAdapter() {
        let [err, res] = await t._closeBLEAdapter.call(this);
        if (err != null) {
            return;
        }
    }
    async sentOrder(cmd, payload,timestamp, callback) {
        let data = t._sentOrder(cmd, payload,timestamp)
        console.log("-- 发送数据:", data)
        let arrayBuffer = new Uint8Array(data).buffer;
        let [err, res] = await t._writeBLECharacteristicValue.call(this, arrayBuffer)
        if (err != null) {
            var data1 = {
                success: false,
                data: err
            }
            callback(data1)
            return false
        }
        var data1 = {
            success: true,
            data: res
        }
        callback(data1)
        console.log("数据发送成功！")
        return true

    }
    // 打开蓝牙适配器状态监听
    onBLEConnectionStateChange() {
        wx.onBLEConnectionStateChange(res => {
            // 该方法回调中可以用于处理连接意外断开等异常情况
            if (!res.connected) {
                this.closeBLEAdapter()
                wx.setStorageSync("bluestatus", "");
                this.emitter.emit("channel", {
                    type: "connect",
                    data: "蓝牙已断开"
                })
            }
        }, err => {
            console.log('err', err)
        })
    }

    // 收到设备推送的notification
    onBLECharacteristicValueChange() {
        wx.onBLECharacteristicValueChange(res => {
            //let arrbf = new Uint8Array(res.value)
            //console.log(`收到硬件数据反馈！命令码为：${arrbf[2]}`)
            //if (this._checkData(arrbf)) {
            //}
            let arrbf = new Uint8Array(res.value)
            if (arrbf[0] == 0x89 && arrbf[1] == 0x89) {
                let dataLength = ((arrbf[10] << 8) & 0xff00) + (arrbf[11] & 0x00ff)
                this.recPktLength = 13 + dataLength
                this.receivePacket = new Uint8Array(this.recPktLength)
                this.recPktOffset = 0
                console.log("开始接收数据：length= " + arrbf.length + " data= " + arrbf)
                this.receivePacket.set(arrbf, this.recPktOffset)
                this.recPktOffset += arrbf.length;
                if (this.recPktOffset == this.recPktLength) {
                    this.getReceivePacket(this.receivePacket)
                }
            } else {
                console.log("继续接收数据：length= " + arrbf.length + " data= " + arrbf)
                this.receivePacket.set(arrbf, this.recPktOffset)
                this.recPktOffset += arrbf.length;
                if (this.recPktOffset == this.recPktLength) {
                    this.getReceivePacket(this.receivePacket)
                }
            }
        })
    }

    /*
    _uploadInfo(message) {
        console.log("-- 准备数据同步！", this._mapToArray(message))
        let bleorder = wx.getStorageSync("bleorder");
        let blecabinet = wx.getStorageSync("blecabinet")
        HTTP({
            url: "cabinet/uploadBlueData",
            methods: "post",
            data: {
                cabinetQrCode: blecabinet,
                order: bleorder,
                message: this._mapToArray(message)
            }
        }).then(res => {
            console.log("✔ 数据同步成功！")

        }, err => {
            console.log('✘ 数据同步失败', err)
        })
    }
	*/

    _mapToArray(arrbf) {
        let arr = []
        arrbf.map(item => {
            arr.push(item)
        })
        return arr
    }

    // 校验数据正确性
    _checkData(arrbf) {
        let packetLen = arrbf.length;
        console.log("接收数据：" + arrbf)

        // 校验帧头帧尾
        if (arrbf[0] != 0x89 || arrbf[1] != 0x89) {
            console.log('不是该设备返回的包')
            return false
        }
        if (packetLen < 14) {
            console.log("包长太短，不是该设备返回的包");
            return false;
        }

        let dataLength = ((arrbf[10] << 8) & 0xff00) + (arrbf[11] & 0x00ff);
        if (dataLength != (packetLen - 13)) {
            let calLen = packetLen - 13;
            console.log("✘ 数据长度错误: " + dataLength + " is not " + calLen);
            return false;
        }
        //校验包
        let check = arrbf[0];
        for (let i = 1; i < packetLen - 1; i++)
            check ^= arrbf[i];
        if (check != arrbf[packetLen - 1]) {
            console.log("crc校验错误，请重发." + check);
            return false;
        }
        console.log('✔ 数据校验成功，接收完整！')
        return true
    }
    getReceivePacket(arrbf) {
        let that = this
        let packetLen = arrbf.length;
        console.log("接收数据：" + arrbf)
        // 校验帧头帧尾
        if (arrbf[0] != 0x89 || arrbf[1] != 0x89) {
            console.log('不是该设备返回的包')
            return [0];
        }
        if (packetLen < 14) {
            console.log("包长太短，不是该设备返回的包");
            return [0];
        }

        let dataLength = ((arrbf[10] << 8) & 0xff00) + (arrbf[11] & 0x00ff);
        if (dataLength != (packetLen - 13)) {
            let calLen = packetLen - 13;
            console.log("✘ 数据长度错误: " + dataLength + " is not " + calLen);
            return [0];
        }
        //校验包
        let check = arrbf[0];
        for (let i = 1; i < packetLen - 1; i++)
            check ^= arrbf[i];
        if (check != arrbf[packetLen - 1]) {
            console.log("crc校验错误，请重发." + check);
            return [0];
        }

        //数据解密
        let key = arrbf[3];
        let data_offset = 12;

        let result = new Uint8Array(dataLength)
        for (let i = 0; i < dataLength; i++) {
            result[i] = arrbf[i + data_offset];
            result[i] = (result[i] ^ (key ^ i));
            result[i] += (dataLength - i) ^ key;
        }

        console.log('✔ 数据校验成功，接收完整！ packet= ' + arrbf)
        if (result[0] == 25 && result[result.length - 1] == 2) { //蓝牙录入指纹02,设备返回指纹ID
            app.globalData.fingerprintId = result[22]
        }
        if (result[0] == 25 && (result[result.length - 1] == 3 || result[result.length - 1] == 2 || result[result.length - 1] == 1)) { //蓝牙录入指纹01
            app.globalData.backdata = result[result.length - 1]
        }
        if (result[0] == 83 && result[1] == 1) {
            app.globalData.stop29 = true
        }
        if (result[0] == 49 && result[1] == 1) { //蓝牙开锁
            app.globalData.openlock = result[1]
        }
        console.log('解密明文 result= ' + result)
        // switch (arrbf[2]) {
        //     case 0x53:
        //     case 0x13:
        //     case 0x58:
        //         this.bleRspRecord(arrbf)
        //         break;

        // }
        return result;
    }
    bleRspRecord(val) {
        var array = []
        val.forEach(element => {
            array.push(element)
        });
        var data = {
            code: "ble/deviceReport",
            data: {
                value: array,
                deviceNum: app.globalData.deviceNum
            }
        }
        console.log(app.globalData.deviceNum,data)
        WXAPI.sendCommand(data).then(res => {

        })
    }

}
export default BLEHandler