/**
 * 深度克隆
 * Object deepClone
 * @param {Object} obj the object need clone
 */
function deepClone(obj) {
    if (typeof obj !== 'object' || obj === null) {
      return obj;
    }
  
    if (Array.isArray(obj)) {
      return obj.map((v) => {
        if (typeof v === 'object' && v !== null) {
          return deepClone(v);
        } else {
          return v;
        }
      });
    } else {
      const newObj = {};
  
      Object.keys(obj).forEach((v) => {
        if (typeof obj[v] === 'object' && obj[v] !== null) {
          newObj[v] = deepClone(obj[v]);
        } else {
          newObj[v] = obj[v];
        }
      });
  
      return newObj;
    }
  }
  
  /**
   * @param {Object} target -目标对象
   * @param {...Object} source -原对象 
   * @return {Object}
   */
  function assign(target, ...source) {
    const newObj = target;
    if (source.length > 1) {
      let newTarget = source[0];
      source.splice(0, 1);
      source = assign(newTarget, ...source);
    } else {
      source = source[0];
    }
    Object.keys(newObj).forEach((v) => {
      if (typeof newObj[v] === 'object' && newObj[v] !== null && typeof source[v] === 'object' && source[v] !== null) {
        newObj[v] = assign(newObj[v], source[v]);
        delete source[v];
      }
    });
    Object.keys(source).forEach((v) => {
      newObj[v] = source[v];
    });
    return newObj;
  }
  
  /**
   * 返回空
   * @returns {Object} -null
   */
  function noop() {
    return null;
  }
  
  /**
   * 判断属性是否是对象的私有属性 非原型链属性
   * @param {Object} obj -对象
   * @param {string} type -属性
   * @returns {Boolean}
   */
  function hasOwn(obj, type) {
    return Object.prototype.hasOwnProperty.call(obj, type);
  }
  
  /**
   * 判断变量是否未定义
   * @param  item
   * @returns {Boolean}
   */
  function isUndef(item) {
    return item === undefined || item === null;
  }
  
  /**
   * 判断变量是否定义
   * @param item
   * @returns {Boolean}
   */
  function isDef(item) {
    return !this.isUndefined(item);
  }
  
  /**
   * 判断是否是字符串
   * @param {any} item
   * @returns {Boolean}
   */
  function isStr(item) {
    return typeof item === 'string';
  }
  
  /**
   * 判断是否是数字
   * @param {any} item
   * @returns {Boolean}
   */
  function isNumber(item) {
    return typeof item === 'number';
  }
  
  /**
   * 判断是否是数组
   * @param {any} item
   * @returns {Boolean}
   */
  function isArray(item) {
    // 判断是否有 isArray方法 如果有绑定当前content 返回
    if (typeof Array.isArray === 'function') {
      return Array.isArray.bind(this)(item);
    }
    // pollfill
    return Object.prototype.toString.call(item) === '[object Array]';
  }
  
  /**
   * 判断是否是对象
   * @param {any} item
   * @returns {Boolean}
   */
  function isObj(obj) {
    return obj !== null && typeof obj === 'object';
  }
  
  /**
   * 判断是否是函数
   * @param {any} item
   * @returns {Boolean}
   */
  function isFunc(item) {
    return typeof item === 'function';
  }
  
  /**
   * 转数字
   * @param {any} val
   * @returns {(typeof val | number)} -返回的值
   */
  function toNumber(val) {
    let n = parseFloat(val);
    return isNaN(n) ? val : n;
  }
  
  function isEmpty(v) {
    if (typeof v == "undefined" || v == null) {
        return true
    }
    if (v == 0 || v == "") {
        return true
    }
    return /^\s+$/g.test(v)
  }
  
  function fenToYuan(cost) {
    if (cost == null || cost <= 0) {
      return 0.00
    }
  
    var res = parseInt((cost / 100) * 100) / 100
    return res.toFixed(2);
  }
  
  function diffArr(arr1, arr2) {
    return arr1.concat(arr2).filter(function (v) {
      return arr1.indexOf(v)===-1 || arr2 .indexOf(v)===-1
    })
  }
  
  /**
   * 计算距离，返回米
   */
  function getDistance(lat1, lng1, lat2, lng2) {
    var radLat1 = lat1 * Math.PI / 180.0;
    var radLat2 = lat2 * Math.PI / 180.0;
    var a = radLat1 - radLat2;
    var b = lng1 * Math.PI / 180.0 - lng2 * Math.PI / 180.0;
    var s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) + Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2)));
    s = s * 6378.137;
    s = Math.round(s * 10000) / 10;
    return s
  }
  
  function parseUrlParamToObj(str) {
    str = decodeURIComponent(str)
    // 创建目标对象
    let params = {}, 
    // 截取数据字符串
    data=str.slice(str.indexOf("?")),
    aParams = data.substr(1).split("&")
  
    for (let i = 0; i < aParams.length; i++) {
  　　   let aParam = aParams[i].split("=");
  　　   params[aParam[0]] = aParam[1]
    }
    return params;
  }
  
  /**
   * base module. - 公共基础方法模块
   * @module utils/base
   * @see module:utils/base
   */
  
  module.exports = {
    /** 深拷贝 */
    deepClone,
    noop,
    hasOwn,
    isUndef,
    isDef,
    isStr,
    isNumber,
    isArray,
    isObj,
    isFunc,
    toNumber,
    assign,
    isEmpty,
    fenToYuan,
    diffArr,
    getDistance,
    parseUrlParamToObj
  };
  