// ArrayBuffer转16进度字符串示例
import {formatZero, isObject, sliceChunk} from "@/utils/util";
import * as ASCIIUtils from "@/uni_modules/wrs-js-modbusCRCHex/js_sdk/wrs-ASCIIUtils";

export const ab2hex = (buffer, join = '') => {
  const hexArr = Array.prototype.map.call(
    new Uint8Array(buffer),
    function (bit) {
      return ('00' + bit.toString(16)).slice(-2).toUpperCase()
    }
  )
  return hexArr.join(join)
}


export const orderToStr = (head, payload = []) => {
  payload = payload.join('')
  let l = formatZero(((payload.length / 2).toString(16)).toUpperCase(), 2)
  return `${head}${l}${payload}`
}

/**
 * 获取命令码
 * @param str
 * @param sNum
 * @param eNum
 * @returns {*}
 */
export const getOrderCode = (str, sNum = 2, eNum = 4) => {
  return str.slice(2, 4)
}


/**
 * 分割指令
 * @param str      指令
 * @param endNum   校验位开始位置
 * @returns {{data: *[], hex: (*|string)}}
 */
export const stringToSplit = (str, endNum) => {
  let data = [];
  let hex = ''
  hex = str.slice(-4) // 校验码
  if (endNum) str = str.slice(0, -endNum)
  let num = 0
  for (let i = 0; i < (str.length / 2); i++) {
    let item = str.slice(num, num + 2);
    data.push(item)
    num += 2
  }
  return {data, hex}
}


// 16进制转buffer
export const stringToArrayBuffer = (str, type = 1) => {
  if (!str) {
    return new ArrayBuffer(0);
  }
  let result = null
  switch (type) {
    case 2:
      result = new ArrayBuffer(str.length * 2);
      const view = new Uint8Array(result);
      for (let i = 0; i < str.length; i++) {
        view[i] = str.charCodeAt(i);
      }
      break
    case 3:
      result = new Uint8Array(str).buffer
      break

    default:
      result = new ArrayBuffer(str.length / 2);
      let dataView = new DataView(result)
      let ind = 0;
      for (let i = 0, len = str.length; i < len; i += 2) {
        let code = parseInt(str.substr(i, 2), 16)
        dataView.setUint8(ind, code)
        ind++
      }
      break
  }
  return result;
}


/**
 * 命令转成数组
 * @param str
 * @param arr(number)       按指定长度切割 转换16进
 * @param arr(array)        按指定长度切割 不转换16进制[ type: 1 不转换10进制；   long：长度  ]
 * @param arr(array)        按指定长度切割 转换为2进制[ type: 2 转为2进制；   long：长度 ， places：补0长度  ]
 * @param arr(array)        字串从指定位数开始按指定长度分割成数组，不转换进制[ type: 3 按指定长分割   long：长度  ]
 * @param arr(array)        字串从指定位数开始按指定长度分割成数组，不转换进制[ type: 4 ASCii转10进   long：长度  ]
 * @param mode
 * @returns {*[]}
 */
export const orderToData = (str, arr, mode = 1) => {
  let data = {};
  let num = 0;
  for (let i = 0; i < arr.length; i++) {
    let itemArr = arr[i]
    if (typeof itemArr == 'number') {
      itemArr = {l: itemArr}
    }
    let itOp = {
      k: itemArr.k || i,
      t: itemArr.t || 0,
      l: itemArr.l || 2,
      c: itemArr.c || [],
      d: itemArr.d || '',
      fun: itemArr.fun || null,
    }
    let item = '';
    let save = !0
    switch (itOp.t) {
      case 1:
        item = str.slice(num, num + itOp.l);
        if (itOp.c && isObject(itOp.c)) {
          if (itOp.c.s) {
            data[itOp.c.k] = item.slice(...itOp.c.s)
            if ((data[itOp.c.k] == '' || data[itOp.c.k] == null) && itOp.c.d) data[itOp.c.k] = itOp.c.d || ''
          }
        }
        break;
      case 2:
        save = !1
        let itemStr = str.slice(num, num + itOp.l);
        if (itOp.c) {
          itemStr = formatZero(parseInt(itemStr, 16).toString(2), 8)
          itOp.c.forEach((it) => {
            data[it.k] = parseInt(itemStr.slice(...it.s), 2)
          })
        }
        break;
      case 3:
        let content = str.slice(num)
        item = sliceChunk(content, itOp.l)
        itOp.l = content.length
        break;
      case 4:
        item = str.slice(num, num + itOp.l);
        item = parseInt(ASCIIUtils.decodeUtf8(item))
        if (itOp.fun) item = itOp.fun(item)
        break;
      default:
        item = str.slice(num, num + itOp.l);
        item = hexToDataHandle(item, mode, itOp.d)
        if (itOp.fun) item = itOp.fun(item)
        break;
    }
    if (save) data[itOp.k] = item
    num += itOp.l
  }
  return data
}

/**
 * 数据转成16进(低位)
 * @param str
 * @param len
 * @returns {string}
 */
export const dataToHexHandle = (str, len = 2) => {
  str = formatZero(str.toString(16), len)
  let result = [];
  for (let i = 0; i < str.length;) {
    result.push(str.slice(i, i + 2))
    i += 2
  }
  return result.reverse().join('')
}


/**
 * 16进(低位)转成10进数据
 * @param str
 * @param type
 * @param def
 * @returns {string}
 */
export const hexToDataHandle = (str, type = 1, def = '') => {
  let result = [];
  let strLength = str.length
  if (strLength > 2) {
    for (let i = 0; i < strLength;) {
      result.push(str.slice(i, i + 2))
      i += 2
    }
  } else {
    result.push(str)
  }
  if (type == 1) {
    result = result.reverse()
  }
  let a = parseInt(result.join(''), 16)
  return !isNaN(a) ? a : def;
}
