const app = getApp()

Page({
  data: {
    UUID:"6E400001-B5A3-F393-E0A9-E50E24DCCA9E",
    deviceId:"",
    devMac:"",
    deviceNum:"0000000000",
    serviceId:"6E400001-B5A3-F393-E0A9-E50E24DCCA9E",
    readCharacteristic:"6E400003-B5A3-F393-E0A9-E50E24DCCA9E",
    writeCharacteristic:"6E400002-B5A3-F393-E0A9-E50E24DCCA9E",
    timer:0,
    pwdCode:"",
    pwdEncode:"",
    encodeKey:"aabbccdd20191210aabbccdd20191210",
    deviceList:[],
    listDisplay:"block",
    listType:"listActive",
    openBoxShow:"none",
    isConnect:0,
    viewData:{
      dev_mac:"",
      dev_num:"",
      dev_power:"",
      dev_lat:"",
      dev_stock:"",
      lat_1_code:"",
      lat_2_code:"",
      lat_3_code:"",
      lat_4_code:"",
      manager_code:"",
      stock_code:"",
      charge_time:""
    },
    deviceInfo:[]
  },
  onLoad: function (options) {
    this.openBluetoothAdapter();
  },
  onUnload: function(){
    clearInterval(this.data.timer);
    this.stopBluetoothDevicesDiscovery();
    this.closeBLEConnection();
    this.closeBluetoothAdapter();
  },
  /**
   * 筛选设备列表
   */
  selectDevice:function(){
    var that = this;
    var listType = that.data.listType;
    if(listType == "listActive"){
      listType = "";
    }else{
      listType = "listActive"
    }
    that.setData({
      listType:listType
    })
  },
  //连接蓝牙
  connectDevice(e){
    var that = this;
    var deviceId = e.currentTarget.dataset.id;
    var deviceList = that.data.deviceList;
    if(deviceId != "" && typeof(deviceId) != "undefined"){
      for(var i in deviceList){
        if(deviceList[i].deviceId == deviceId){
          that.setData({
            btInfo:deviceList[i],
          })
          break;
        }
      }
      that.setData({
        deviceId:deviceId,
      })
      that.createBLEConnection(deviceId);
    }
  },
  //设置设备编号
  setDevNum:function(code){
    var that = this;
    let hex = [];
    hex.push(parseInt('AA',16));
    hex.push(parseInt('01',16));
    console.log(typeof(Number(code)));
    if(code.length != 10 && typeof(Number(code)) != "number"){
      wx.showToast({
        icon:"none",
        title:"格式错误"
      })
      return;
    }
    for(var i in code){
      hex.push(code.charCodeAt(i));
    }
    that.writeBLECharacteristicValue(hex);
  },
  //打开格子
  openLat:function(e){
    console.log(e);
    var that = this;
    var device_num = that.data.deviceNum;
    var lat = e.currentTarget.dataset.lat;
    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))
    that.writeBLECharacteristicValue(hex);
  },
  //打开缺货格子
  openNoStockLat(){
    var that = this;
    var device_num = that.data.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));
    }
    that.writeBLECharacteristicValue(hex);
  },
  //打开全部格子
  openAllLat(){
    var that = this;
    var device_num = that.data.deviceNum;
    var hex = [];
    hex.push(parseInt('AA',16));
    hex.push(parseInt('04',16));
    for(var i in device_num){
      hex.push(parseInt(device_num[i],16));
    }
    that.writeBLECharacteristicValue(hex);
  },
  //读取设备库存
  readDeviceStock(){
    var that = this;
    var device_num = that.data.deviceNum;
    var hex = [];
    hex.push(parseInt('AA',16));
    hex.push(parseInt('05',16));
    for(var i in device_num){
      hex.push(parseInt(device_num[i],16));
    }
    that.writeBLECharacteristicValue(hex);
  },
  //读取电池电量
  readPower(){
    var that = this;
    var device_num = that.data.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));
    }
    that.writeBLECharacteristicValue(hex);
  },
  //读取货道数量
  readLatNum(){
    var that = this;
    var device_num = that.data.deviceNum;
    var hex = [];
    hex.push(parseInt('AA',16));
    hex.push(parseInt('07',16));
    for(var i in device_num){
      hex.push(parseInt(device_num[i],16));
    }
    that.writeBLECharacteristicValue(hex);
  },
  //设置充电时长
  setChargeTime(time){
    var that = this;
    var device_num = that.data.deviceNum;
    var hex = [];
    hex.push(parseInt('AA',16));
    hex.push(parseInt('08',16));
    var time_hex = time.toString(16).padStart(4,'0');
    console.log(time_hex);
    hex.push(parseInt(time_hex.substr(0,2),16));
    hex.push(parseInt(time_hex.substr(2,2),16));
    for(var i in device_num){
      hex.push(parseInt(device_num[i],16));
    }
    that.writeBLECharacteristicValue(hex);
  },
  //配置取货码
  setSetGoodsCode:function(port,code){
    var that = this;
    var device_num = that.data.deviceNum;
    var hex = [];
    hex.push(parseInt('AA',16));
    hex.push(parseInt('09',16));
    hex.push(parseInt(port,16));
    for(var i=0;i<4;i++){
      hex.push(parseInt(code.substr(Number(i*2),2),16));
    }
    for(var i in device_num){
      hex.push(parseInt(device_num[i],16));
    }
    wx.showLoading({
      title: '写入中',
    })
    that.writeBLECharacteristicValue(hex);
  },
  //配置补货员
  setSetManagerCode:function(socketCode,managerCode){
    var that = this;
    var device_num = that.data.deviceNum;
    var hex = [];
    hex.push(parseInt('AA',16));
    hex.push(parseInt('0A',16));
    for(var i=0;i<4;i++){
      hex.push(parseInt(socketCode.substr(Number(i*2),2),16));
    }
    for(var i=0;i<4;i++){
      hex.push(parseInt(managerCode.substr(Number(i*2),2),16));
    }
    for(var i in device_num){
      hex.push(parseInt(device_num[i],16));
    }
    that.writeBLECharacteristicValue(hex);
  },
  // 初始化蓝牙适配器
  openBluetoothAdapter() {
    var that = this;
    that.closeBluetoothAdapter();
    that.closeBLEConnection();
    wx.openBluetoothAdapter({
      success: function (res) {
        console.log("初始化蓝牙适配器成功");
        that.startBluetoothDevicesDiscovery();
      },
      fail: function (err) {
        wx.showModal({
          title: '温馨提示',
          content: '请先打开手机蓝牙，再点击确定重新连接',
          cancelText:"已开蓝牙",
          confirmText: "重新连接",
          success (res) {
            if (res.confirm) {
              that.openBluetoothAdapter();
            } else if (res.cancel) {
              console.log('用户点击取消');
              that.openBluetoothAdapter();
            }
          }
        })
        console.log(err, "初始化蓝牙适配器失败");
      }
    })
  },
  // 开始搜索蓝牙设备
  startBluetoothDevicesDiscovery() {
    var that = this;
    wx.startBluetoothDevicesDiscovery({
      success: function (res) {
        console.log("蓝牙搜索中...");
        wx.showLoading({
          title: '设备搜索中',
        })
        setTimeout(function(){
          wx.hideLoading()
        },2000);
        that.getBluetoothDevices();
        var timer = setInterval(() => {
          that.getBluetoothDevices();
        },2000);
        that.setData({
          timer:timer
        })
      }
    })
  },
  //获取已发现的蓝牙设备列表
  getBluetoothDevices() {
    var that = this;
    wx.getBluetoothDevices({
      success: function (res) {
        var list = [];
        res.devices.forEach(item => {
          if(typeof(item.advertisServiceUUIDs) != "undefined" && item.advertisServiceUUIDs[0] == that.data.UUID){
            // clearInterval(that.data.timer);
            // that.stopBluetoothDevicesDiscovery();
            // that.createBLEConnection(item.deviceId);
            list.push(item);
          }
        });
        that.setData({
          deviceList:list
        })
      }
    })
  },
  //停止搜索设备
  stopBluetoothDevicesDiscovery() {
    wx.stopBluetoothDevicesDiscovery({
      success: function (res) {
        console.log("停止搜索设备" + JSON.stringify(res.errMsg))
      }
    })
  },
  connectFail(){
    wx.hideLoading({
      success: (res) => {
        wx.showToast({
          title: '连接失败',
          icon: "none"
        })
      },
    })
  },
  //创建蓝牙连接
  createBLEConnection(deviceId) {
    console.log(deviceId);
    var that = this;
    var device_list = that.data.deviceList;
    var item = null;
    for(var i in device_list){
      if(deviceId == device_list[i].deviceId){
        item = device_list[i];
        break;
      }
    }
    if(!item){
      wx.showToast({
        icon:"none",
        title: '找不到设备信息',
      })
      return;
    }else{
      var mac = that.buf2hex(item.advertisData);
      console.log(mac);
      that.setData({
        devMac:mac,
        deviceNum:item.localName
      })
    }
    wx.showLoading({
      title: '设备连接中',
      duration: 99999,
      mask: true
    })
    wx.createBLEConnection({
      deviceId: deviceId,
      success: function () {
          that.setData({
            "deviceId":deviceId
          })
          wx.getBLEDeviceServices({
            deviceId: deviceId,
            success: function () {
              that.getBLEDeviceCharacteristics()
            },
            fail: function (err) {
              that.connectFail();
              console.log(err, "蓝牙连接失败getBLEDeviceServices");
            }
          })
      },
      fail: function (err) {
        that.connectFail();
        console.log(err, "蓝牙连接失败createBLEConnection");
      }
    })
  },
  // 获取该服务的特征值
  getBLEDeviceCharacteristics() {
    var that = this;
    wx.getBLEDeviceCharacteristics({
      deviceId: that.data.deviceId,
      serviceId: that.data.serviceId,
      success: function (res) {
        console.log(res);
        that.notifyBLECharacteristicValueChange(that.data.deviceId, that.data.serviceId, that.data.readCharacteristic);
      },
      fail: function (err) {
        that.connectFail();
        console.log(err, "获取该服务失败getBLEDeviceCharacteristics");
      }
    })
  },
  // 监听蓝牙返回值
  notifyBLECharacteristicValueChange(deviceId, serviceId, characteristicId) {
    var that = this;
    wx.notifyBLECharacteristicValueChange({
      deviceId: deviceId,
      serviceId: serviceId,
      characteristicId: characteristicId,
      state: true,
      success: function (res) {
        console.log('使能成功', res);
        wx.showToast({
          icon: "success",
          title: '连接成功',
        })
        that.onBLECharacteristicValueChange();
        let pwd = that.getRandomString(16);
        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);
        var mac = that.data.devMac;
        var view_data = that.data.viewData;
        mac = that.hexEncode(mac);
        mac = mac.splice(2,6);
        view_data['dev_mac'] = mac.join(":");
        view_data['dev_num'] = that.data.deviceNum
        that.setData({
          pwdCode:pwd,
          isConnect:1,
          viewData:view_data,
          openBoxShow:"block"
        })
      },
      fail: function (err) {
        that.connectFail();
      }
    })
  },
  // 获取返回值
  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('../../utils/cryptojs-master/cryptojs.js').Crypto;
              debugger
              var pwdCode = that.data.pwdCode;
              var pwdEncode = "";
              for(var i=2;i<turn_back.length;i++){
                pwdEncode += turn_back[i].toUpperCase();
              }
              var key = that.hexEncode(that.data.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('../../utils/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(that.data.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":
          var view_data = that.data.viewData;
          switch(turn_back[1]){
            case '01'://设置编号
              wx.showToast({
                title: '写入成功',
              })
              var num = "";
              for(var i=2;i<turn_back.length;i++){
                num += turn_back[i];
              }
              var dev_num = that.hex2str(num);
              view_data['dev_num'] = dev_num;
              that.setData({
                viewData:view_data
              })
              var mac = that.data.devMac;
              mac = that.hexEncode(that.data.devMac);
              mac = mac.splice(2,6).join(":");
              wx.request({
                url: app.globalData.serverInfo.gateWayUrl,
                method:'POST',
                data:{
                  'api_name':'update_device_mac',
                  'dev_id': that.data.deviceInfo.dev_id,
                  'dev_mac': mac,
                  'login_manager_id':1
                },
                success:function(ret){
                  console.log(ret);
                  setTimeout(function(){
                    if(Number(ret.data.state) == 1){
                      wx.showToast({
                        title: '上报成功',
                      })
                    }else{
                      wx.showToast({
                        title: '上报失败',
                      })
                    }
                  },500)
                }
              })
              break;
            case '05'://读取设备库存
              var data = turn_back[Number(turn_back.length-1)];
              data = parseInt(data,16);
              data = data.toString(2).padStart(8,'0');
              view_data['dev_stock'] = data;
              break;
            case '06'://电量返回
              var power = turn_back[Number(turn_back.length-1)];
              power = parseInt(power,16)/10+"V";
              view_data['dev_power'] = power;
              break;
            case "07"://格子数
              if(Number(turn_back.length) == 13){
                var lat_num = turn_back[Number(turn_back.length-1)];
                lat_num = parseInt(lat_num,16);
                view_data['dev_lat'] = lat_num;
              }
              break;
            case "09"://配置取货码
              wx.hideLoading();
              wx.showToast({
                title: '写入成功',
              })
              break;
            case "0A"://配置取货码
              wx.hideLoading();
              wx.showToast({
                title: '写入成功',
              })
              break;
          }
          that.setData({
            viewData:view_data
          })
          break;
      }
    }, function (err) {
      console.log(err)
    })
  },
  // 发送指令API
  writeBLECharacteristicValue(hex){
    var that = this;
    var buffer = new ArrayBuffer(Number(hex.length));
    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: that.data.deviceId,
      serviceId: that.data.serviceId,
      characteristicId: that.data.writeCharacteristic,
      value: buffer,
      success: function (res) {
        console.log("发送指令成功")
      },
      fail: function (err) {
        console.log("指令发送失败", err)
      }
    })
  },
  closeBluetoothAdapter() {
    wx.closeBluetoothAdapter({
      success(res) {
        console.log("断开蓝牙模块", res);
      }
    })
  },
  closeBLEConnection() {
    var that = this;
    wx.closeBLEConnection({
      deviceId: that.data.deviceId,
      success(res) {
        console.log("断开蓝牙连接", res);
        that.setData({
          isConnect:0,
          openBoxShow:"none"
        })
        wx.showToast({
          title: '已断开连接',
          icon:"none"
        })
      }
    })
  },
  buf2hex: function (buffer) { // buffer is an ArrayBuffer
    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('');
  },
  buf2hex: function (buffer) { // buffer is an ArrayBuffer
    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('');
  },
  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,chars = 'qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM1234567890') {
    len = len || 16;
    var maxPos = chars.length;
    var pwd = '';
    for (let i = 0; i < len; i++) {
        pwd += chars.charAt(Math.floor(Math.random() * maxPos));
    }
    return pwd;
  },
  formSubmit(e){
    console.log(e);
    var that = this;
    var type = e.detail.target.dataset.type;
    var data = e.detail.value;
    switch(type){
      case "dev_num":
        that.setDevNum(data.dev_num);
        break;
      case "lat_1_code":
        that.setSetGoodsCode(1,data.lat_1_code);
        break;
      case "lat_2_code":
        that.setSetGoodsCode(1,data.lat_2_code);
        break;
      case "lat_3_code":
        that.setSetGoodsCode(1,data.lat_3_code);
        break;
      case "lat_4_code":
        that.setSetGoodsCode(1,data.lat_4_code);
        break;
      case "manager_code":
      case "stock_code":
        that.setSetManagerCode(data.stock_code,data.manager_code);
        break;
      case "charge":
        that.setChargeTime(Number(data.charge_time));
        break;
      case "codes":
        var that = this;
        var times = 0;
        var timer;
        timer = setInterval(function(){
          switch(times){
            case 0:
              that.setSetGoodsCode(1,data['lat_1_code']);
              break;
            case 1:
              that.setSetGoodsCode(2,data['lat_2_code']);
              break;
            case 2:
              that.setSetGoodsCode(3,data['lat_3_code']);
              break;
            case 3:
              that.setSetGoodsCode(4,data['lat_4_code']);
              break;
            case 4:
              that.setSetManagerCode(data['stock_code'],data['manager_code']);
              break;
          }
          times++
        },300);
        break;
    }
  },
  //自动生成密码
  generatePass(){
    var that = this;
    var chars = "1234";
    var view_data = that.data.viewData;
    var code = [];
    for(var i=0;i<6;i++){
      code.push(that.getRandomString(8,chars));
    }
    view_data['lat_1_code'] = code[0];
    view_data['lat_2_code'] = code[1];
    view_data['lat_3_code'] = code[2];
    view_data['lat_4_code'] = code[3];
    view_data['manager_code'] = code[4];
    view_data['stock_code'] = code[5];
    wx.showToast({
      title: '生成成功',
    })
    that.setData({
      viewData:view_data
    })
  },
  /**
   * 扫描设备二维码
   */
  scanQrCode(){
    var that = this;
    wx.scanCode({
      scanType:"qrCode",
      success (res) {
        var scan_url = res.result;
        var thisDevNo = scan_url.replace(app.globalData.serverInfo.qrReplaceUrl, '');
        if(thisDevNo != "" ){
          wx.showLoading({
            title: '查询中',
          })
          wx.request({
            url: app.globalData.serverInfo.gateWayUrl,
            method:'POST',
            data:{
              'api_name':'find_device',
              'dev_no': thisDevNo
            },
            success:function(ret){
              wx.hideLoading();
              if(Number(ret.data.state) === 1){
                var view_data = that.data.viewData;
                var open_box_show = that.data.openBoxShow;
                if(open_box_show != "block"){
                  var device_list = that.data.deviceList;
                  var flag = false;
                  for(var i in device_list){
                    if(device_list[i].localName == thisDevNo){
                      flag = true;
                      wx.showModal({
                        title:"温馨提示",
                        content:"是否连接该设备？",
                        success (res) {
                          if (res.confirm) {
                            that.createBLEConnection(device_list[i].deviceId);
                          } else if (res.cancel) {
                          }
                        }
                      })
                      break;
                    }
                  }
                  if(!flag){
                    wx.showToast({
                      icon:"none",
                      "title":"设备不在附近"
                    })
                  }
                }else{
                  view_data['dev_num'] = thisDevNo;
                }
                that.setData({
                  deviceInfo:ret.data.data,
                  viewData:view_data
                })
              }else{
                wx.showToast({
                  icon:"none",
                  title: '设备信息不存在',
                })
              }
            }
          })
        }
      }
    })
  }
})