import utils from '@/utils/utils.js'

var FormMath = {}

FormMath.toNumber = function(x) {
  if (x === null || x === undefined || x === '')
    return ''
  if (typeof x == 'string') {
    x = x.replace(/,/g, '')
  }
  var match = x.toString().match(/([$|￥])\d+\.?\d*/)
  if (match) {
    x = x.replace(match[1], '')
  }
  return Number(x)
}

/**
 * 返回x的绝对值
 * @param  {[type]} x [description]
 * @return {[type]}   [description]
 */
FormMath.abs = function(x) {
  return Math.abs(x)
}

/**
 * 把x四舍五入为最接近的整数
 * @param  {[type]} x [description]
 * @return {[type]}   [description]
 */
FormMath.round = function(x) {
  return Math.round(x)
}

/**
 * 对x进行上舍入，返回等于或者大于x,并且与x最接近的整数
 * @param  {[type]} x [description]
 * @return {[type]}   [description]
 */
FormMath.ceil = function(x) {
  return Math.ceil(x)
}

/**
 * 对x进行下舍入，返回小于或者等于x，并且与x最接近的整数
 * @param  {[type]} x [description]
 * @return {[type]}   [description]
 */
FormMath.floor = function(x) {
  return Math.floor(x)
}

/**
 * 返回集合ary中最大的数
 * @param  {[type]} ary [description]
 * @return {[type]}     [description]
 */
FormMath.max = function(ary) {
  var tmp,
    x = 0,
    size = ary.length
  for (var i = 0; i < size; i++) {
    x = FormMath.toNumber(ary[i])
    if (isNaN(x)) continue
    if (tmp === undefined) {
      tmp = x
    } else {
      if (x > tmp)
        tmp = x
    }
  }
  tmp = FormMath.toNumber(tmp)
  return tmp
}

/**
 * 返回集合ary中最小的数
 * @param  {[type]} ary [description]
 * @return {[type]}     [description]
 */
FormMath.min = function(ary) {
  var tmp,
    x = 0,
    size = ary.length
  for (var i = 0; i < size; i++) {
    x = FormMath.toNumber(ary[i])
    if (isNaN(x)) continue
    if (tmp === undefined) {
      tmp = x
    } else {
      if (x < tmp)
        tmp = x
    }
  }
  tmp = FormMath.toNumber(tmp)
  return tmp
}

/**
 * 返回x的平方根
 * @param  {[type]} x [description]
 * @return {[type]}   [description]
 */
FormMath.sqrt = function(x) {
  return Math.sqrt(x)
}

/**
 * 获取ary的平均值
 * @param  {[type]} ary [description]
 * @return {[type]}     [description]
 */
FormMath.average = function(ary) {
  var tmp,
    x = 0,
    size = ary.length
  for (var i = 0; i < size; i++) {
    x = FormMath.toNumber(ary[i])
    if (isNaN(x)) continue
    if (tmp === undefined) {
      tmp = x
    } else {
      tmp += x
    }
  }
  tmp = FormMath.toNumber(tmp / size)
  return tmp
}

/**
 * 求ary的和
 * @param  {[type]} ary [description]
 * @return {[type]}     [description]
 */
FormMath.sum = function(ary) {
  var tmp,
    x = 0,
    size = ary.length
  for (var i = 0; i < size; i++) {
    x = FormMath.toNumber(ary[i])
    if (isNaN(x)) continue
    if (tmp === undefined) {
      tmp = x
    } else {
      tmp += x
    }
  }
  tmp = FormMath.toNumber(tmp)
  return tmp
}

/**
 * 返回保留小数点后b位的x的四舍五入值
 * @param  {[type]} x [description]
 * @param  {[type]} b [description]
 * @return {[type]}   [description]
 */
FormMath.tofixed = function(x, b) {
  var tmp = FormMath.toNumber(x)
  b = FormMath.toNumber(b)
  if (isNaN(tmp) || isNaN(b)) return x
  return tmp.toFixed(b)
}

/**
 * 将数字转换为人民币大写
 * @param  {[type]} x [description]
 * @return {[type]}   [description]
 */
FormMath.convertCurrency = function(x) {
  var tmp = FormMath.toNumber(x)
  if (isNaN(tmp)) return x
  //TODO 转换为人民币大写
  return utils.convertCurrency(tmp)
}

// 解析表达式中的字段
FormMath.parseFuncexpField = (statFun) => {
  var myregexp = /\(([data.main|data.sub|item].*?)\)/g
  var match = myregexp.exec(statFun)
  var arrs = []
  while (match != null) {
    var str = match[1]
    var has = false
    for (var i = 0, v; v = arrs[i++];) {
      if (v == str) has = true
    }
    if (!has) arrs.push(str)
    match = myregexp.exec(statFun)
  }
  return arrs
}

// 计算子表中的行运算
FormMath.calcSubExpValue = function(exp, scope, prefix, index) {
  if (!exp || !scope || !prefix) return 0
  var reg = /\{.*?\(([data.main|data.sub|item].*?)\)\}/g
  exp = exp.replace(reg, function() {
    var name = arguments[1],
      value = 0
    if (name.split('.').length != 2) {
      throw `子表运算中${name}必须为item.xxx格式的表达式`
    }
    var val = utils.getValueByPath(scope, `${prefix}[${index}].${name.split('.')[1]}`)
    val = FormMath.toNumber(val)
    if (!isNaN(val) && '' != val) value = val
    return value
  })
  if (exp.substring(0, 16) != 'FormMath.tofixed') {
    return FormMath.isValue(FormMath.tofixed(eval(`(${exp})`), 0))
  }
  return FormMath.isValue(eval(`(${exp})`))
}

// 计算表达式中的值
FormMath.calcExpValue = function(exp, scope) {
  if (!exp) return 0
  var reg = /\{.*?\(([data.main|data.sub|item].*?)\)\}/g
  exp = exp.replace(reg, function() {
    var name = arguments[1],
      value = 0
    if (scope) {
      //子表统计计算情况，多行数据
      if (name.split('.').length > 3) {
        var valArray = []
        var subMsg = name.split('.')
        var fieldName = subMsg[3]
        subMsg.splice(subMsg.length - 1, 1)
        var subTableSrc = subMsg.join('.')
        var rows = utils.getValueByPath(scope, subTableSrc)
        for (var i = 0, row; row = rows[i++];) {
          if (row[fieldName]) {
            valArray.push(row[fieldName])
          }
        }
        value = valArray.join(',')
      } else {
        var val = utils.getValueByPath(scope, name)
        val = FormMath.toNumber(val)
        if (!isNaN(val) && '' != val) value = val
      }
    }
    if (!value) {
      value = 0
    }
    return value
  })
  if (exp.substring(0, 16) != 'FormMath.tofixed') {
    return FormMath.isValue(FormMath.tofixed(eval(`(${exp})`), 0))
  }
  return FormMath.isValue(eval(`(${exp})`))
}

FormMath.isValue = function(value) {
  if (!value) {
    return ''
  } else if (value == 'Infinity') {
    return ''
  } else {
    return value
  }
}
window.FormMath = FormMath
export default FormMath
