const serviceId = "6E400001-B5A3-F393-E0A9-E50E24DCCA9E";
const readCharacteristic = "6E400003-B5A3-F393-E0A9-E50E24DCCA9E";
const writeCharacteristic = "6E400002-B5A3-F393-E0A9-E50E24DCCA9E";
const encodeKey = "aabbccdd20191210aabbccdd20191210";

const deviceId = "";
const deviceNum = "";
const pwdCode = "";
const pwdEncode = "";
const isConnect = false;

class D600{
  constructor(devNum,deviceId) {
    this.deviceNum = devNum;
    this.deviceId = deviceId;
    this.isConnect = false;
  }

  //获取连接状态
  getConnect(){
    return this.isConnect;
  }

  getPower(){
    return this.power;
  }

  //打开格子
  openLat(lat){
    console.log("openLat");
    var device_num = this.deviceNum;
    var hex = [];
    hex.push(parseInt('AA',16));
    hex.push(parseInt('02',16));
    for(var i in device_num){
      hex.push(parseInt(device_num[i],16));
    }
    hex.push(parseInt(Number(lat),16))
    wx.showLoading({
      title: '打开格子中',
    })
    this.writeBLECharacteristicValue(hex);
  }

  //打开缺货格子
  openNoStockLat(){
    var device_num = this.deviceNum;
    var hex = [];
    hex.push(parseInt('AA',16));
    hex.push(parseInt('03',16));
    for(var i in device_num){
      hex.push(parseInt(device_num[i],16));
    }
    wx.showLoading({
      title: '打开格子中',
    })
    this.writeBLECharacteristicValue(hex);
  }

  //读取电池电量
  readPower(){
    var device_num = this.deviceNum;
    var hex = [];
    hex.push(parseInt('AA',16));
    hex.push(parseInt('06',16));
    for(var i in device_num){
      hex.push(parseInt(device_num[i],16));
    }
    this.writeBLECharacteristicValue(hex);
  }

  //连接蓝牙设备
  createBLEConnection(){
    var that = this;
    var deviceId = this.deviceId;
    return new Promise(function(resolve,reject){
      wx.showLoading({
        title: '设备连接中',
        duration: 99999,
        mask: true
      })
      wx.createBLEConnection({
        deviceId: deviceId,
        success: function (createBLEConnection_res) {
            console.log("Create",createBLEConnection_res);
            wx.getBLEDeviceServices({
              deviceId: deviceId,
              success: function (getBLEDeviceServices_res) {
                console.log("Services",getBLEDeviceServices_res);
                wx.getBLEDeviceCharacteristics({
                  deviceId: deviceId,
                  serviceId: serviceId,
                  success: function (res) {
                    console.log(res);
                    wx.notifyBLECharacteristicValueChange({
                      deviceId: deviceId,
                      serviceId: serviceId,
                      characteristicId: readCharacteristic,
                      state: true,
                      success: function (res) {
                        console.log('使能成功', res);
                        wx.showToast({
                          icon: "success",
                          title: '连接成功',
                        })
                        that.onBLECharacteristicValueChange();
                        let pwd = that.getRandomString(16);
                        that.pwdCode = pwd;
                        that.isConnect = true;
                        var hex = [];
                        for(var i in pwd){
                          hex.push(pwd.charCodeAt(i))
                        }
                        hex.unshift(parseInt("01",16));
                        hex.unshift(parseInt("AE",16));
                        // that.writeBLECharacteristicValue(hex);
                        resolve(true);
                      },
                      fail: function (err) {
                        that.connectFail();
                        resolve(false);
                      }
                    })
                  },
                  fail: function (err) {
                    console.log(err, "获取该服务失败getBLEDeviceCharacteristics");
                    that.connectFail();
                    resolve(false);
                  }
                })
              },
              fail: function (err) {
                console.log(err, "蓝牙连接失败getBLEDeviceServices");
                that.connectFail();
                resolve(false);
              }
            })
        },
        fail: function (err) {
          console.log(err, "蓝牙连接失败createBLEConnection");
          that.connectFail();
          resolve(false);
        }
      })
    })
  }

  // 获取返回值
  onBLECharacteristicValueChange() {
    var that = this;
    wx.onBLECharacteristicValueChange(function (res) {
      var turn_back = that.buf2hex(res.value);
      console.log("接收=》"+turn_back);
      turn_back = that.hexEncode(turn_back);
      switch(turn_back[0]){
        case "AE":
        case "ae":
          switch(Number(turn_back[1])){
            case 2://接收到设备加密后的密文，App自己重新加密/解密认证，这是为重新对发出去的明文重新加密
              var CryptoJS = require('./cryptojs-master/cryptojs.js').Crypto;
              var pwdCode = that.pwdCode;
              var pwdEncode = "";
              for(var i=2;i<turn_back.length;i++){
                pwdEncode += turn_back[i].toUpperCase();
              }
              var key = that.hexEncode(encodeKey);
              var new_key = [];
              for(let i in key){
                new_key.push(parseInt(key[i],16));
              }
              var mode = new CryptoJS.mode.ECB(CryptoJS.pad.pkcs7);
              var bytes = CryptoJS.AES.encrypt(pwdCode, new_key, {
                asBpytes: true,
                mode: mode
              });
              var encryptResult = wx.base64ToArrayBuffer(bytes);
              encryptResult = that.buf2hex(encryptResult);
              encryptResult = encryptResult.substr(0,32).toUpperCase();
              //App自己加密密文与设备返回密文相同则为成功
              if(pwdEncode == encryptResult){
                console.log("第一遍认证成功");
              }else{
                //TODO：断开蓝牙连接
              }
              break;
            case 3://接收到设备测试指令，App加密后返回设备进行认证
              var CryptoJS = require('./cryptojs-master/cryptojs.js').Crypto;
              var pwdEncode = "";
              for(var i=2;i<turn_back.length;i++){
                pwdEncode += turn_back[i].toUpperCase();
              }
              pwdEncode = that.hexEncode(pwdEncode);
              for(var i in pwdEncode){
                pwdEncode[i] = parseInt(pwdEncode[i],16);
              }
              var key = that.hexEncode(encodeKey);
              var new_key = [];
              for(let i in key){
                new_key.push(parseInt(key[i],16));
              }
              var mode = new CryptoJS.mode.ECB(CryptoJS.pad.pkcs7);
              var bytes = CryptoJS.AES.encrypt(pwdEncode, new_key, {
                asBpytes: true,
                mode: mode
              });
              var encryptResult = wx.base64ToArrayBuffer(bytes);
              encryptResult = that.buf2hex(encryptResult);
              encryptResult = encryptResult.substr(0,32).toUpperCase();
              encryptResult = that.hexEncode(encryptResult);
              console.log(encryptResult);
              var hex = [];
              for(var i in encryptResult){
                hex.push(parseInt(encryptResult[i],16))
              }
              hex.unshift(parseInt("04",16));
              hex.unshift(parseInt("AE",16));
              that.writeBLECharacteristicValue(hex);//返回App加密后的指令
          }
          break;
        case "BB":
        case "bb":
          switch(turn_back[1]){
            case '02'://开启格子反馈
              wx.hideLoading({
                success: (res) => {
                  wx.showToast({
                    title: '开启成功',
                  })
                },
              })
              break;
            case '03':
              setTimeout(function(){
                wx.hideLoading({
                  success: (res) => {
                    wx.showToast({
                      title: '执行完毕',
                    })
                  },
                })
              },3000);
              break;
            case '06'://电量返回
              var power = turn_back[Number(turn_back.length-1)];
              power = Number(power)/10;
              that.power = power;
              break;
          }
          break;
      }
    }, function (err) {
      console.log(err)
    })
  }

  // 发送指令API
  writeBLECharacteristicValue(hex){
    var that = this;
    var deviceId = this.deviceId;
    var buffer = new ArrayBuffer(Number(hex.length));
    console.log(deviceId);
    console.log(serviceId);
    console.log(writeCharacteristic);
    if(hex){
      for(var i in hex){
        new DataView(buffer).setInt8(Number(i),hex[i]);
      }
    }else{
      console.log("未输入指令");
      return;
    }
    console.log("发送=》"+that.buf2hex(buffer));
    wx.writeBLECharacteristicValue({
      deviceId: deviceId,
      serviceId: serviceId,
      characteristicId: writeCharacteristic,
      value: buffer,
      success: function (res) {
        console.log("发送指令成功")
      },
      fail: function (err) {
        console.log("指令发送失败", err)
      }
    })
  }

  //停止搜索设备
  stopBluetoothDevicesDiscovery() {
    wx.stopBluetoothDevicesDiscovery({
      success: function (res) {
        console.log("停止搜索设备" + JSON.stringify(res.errMsg))
      }
    })
  }

  //连接失败
  connectFail(){
    wx.hideLoading({
      success: (res) => {
        wx.showToast({
          title: '连接失败',
          icon: "none"
        })
      },
    })
    return false;
  }

  //关闭蓝牙适配器
  closeBluetoothAdapter() {
    var that = this;
    wx.closeBluetoothAdapter({
      success(res) {
        that.isConnect = false;
        console.log("断开蓝牙模块", res);
      }
    })
  }

  //关闭蓝牙连接
  closeBLEConnection() {
    var that = this;
    var deviceId = this.deviceId;
    wx.closeBLEConnection({
      deviceId: deviceId,
      success(res) {
        console.log("断开蓝牙连接", res);
        that.isConnect = false;
        wx.showToast({
          title: '已断开连接',
          icon:"none"
        })
      }
    })
  }

  buf2hex(buffer) {
    return Array.prototype.map.call(new Uint8Array(buffer), x => ('00' + x.toString(16)).slice(-2)).join('');
  }

  //16进制转字符串
  hex2str(hex) {
    var rawStr = hex.substr(0, 2).toLowerCase() === "0x" ? hex.substr(2) : hex;
    var len = rawStr.length;
    if (len % 2 !== 0) {
      console.log("Illegal Format ASCII Code!");
      return "";
    }
    var curCharCode;
    var resultStr = [];
    for (var i = 0; i < len; i = i + 2) {
      curCharCode = parseInt(rawStr.substr(i, 2), 16);
      resultStr.push(String.fromCharCode(curCharCode));
    }
    return resultStr.join("");
  }

  // 字符串转16进制
  str2hex(str) {
    if (str === "") {
      return "";
    }
    var arr = [];
    // arr.push("0x");
    for (var i = 0; i < str.length; i++) {
      arr.push(str.charCodeAt(i).toString(16));
    }
    return arr.join('');
  }

  //格式化hex
  hexEncode(hex){
    let hex_arr = [];
    for(let i=0;i<hex.length;i+=2){
      hex_arr.push(hex.substr(i,2).toUpperCase());
    }
    return hex_arr;
  }

  //生成随机字符串
  getRandomString(len){
    len = len || 16;
    var $chars = 'qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM1234567890';
    var maxPos = $chars.length;
    var pwd = '';
    for (let i = 0; i < len; i++) {
        pwd += $chars.charAt(Math.floor(Math.random() * maxPos));
    }
    return pwd;
  }
}

module.exports = D600;