/**
 * Get the first item that pass the test
 * by second argument function
 *
 * @param {Array} list
 * @param {Function} f
 * @return {*}
 */
export function find (list, f) {
  return list.filter(f)[0]
}

/**
 * Deep copy the given object considering circular structure.
 * This function caches all nested objects and its copies.
 * If it detects circular structure, use cached copy to avoid infinite loop.
 *
 * @param {*} obj
 * @param {Array<Object>} cache
 * @return {*}
 */
export function deepCopy (obj, cache = []) {
  // just return if obj is immutable value
  if (obj === null || typeof obj !== 'object') {
    return obj
  }

  // if obj is hit, it is in circular structure
  const hit = find(cache, c => c.original === obj)
  if (hit) {
    return hit.copy
  }

  const copy = Array.isArray(obj) ? [] : {}
  // put the copy into cache at first
  // because we want to refer it in recursive deepCopy
  cache.push({
    original: obj,
    copy
  })

  Object.keys(obj).forEach(key => {
    copy[key] = deepCopy(obj[key], cache)
  })

  return copy
}

/**
 * forEach for object
 */
export function forEachValue (obj, fn) {
  Object.keys(obj).forEach(key => fn(obj[key], key))
}

export function isObject (obj) {
  return obj !== null && typeof obj === 'object'
}

export function isPromise (val) {
  return val && typeof val.then === 'function'
}

export function assert (condition, msg) {
  if (!condition) throw new Error(`[vuex] ${msg}`)
}

export function isNull(a){
  return a === "" || a === null || a === undefined
}

// 扁平arr
export function flatArray(arr) {
  return arr.reduce((result, item) => {
    return result.concat(Array.isArray(item) ? flatArray(item) : item);
  }, []);
}

// 树形转线性：
export function treeConvertList(root) {
  const list = [] ;
  if (root) {
    const Root = JSON.parse(JSON.stringify(root));
    const queue = [];
    queue.push(Root);
    while (queue.length) {
      const node = queue.shift();
      if (node.children && node.children.length) {
        queue.push(...node.children);
      }
      delete node.children;
      if (node.parentId !== null && node.parentId !== undefined) {
        list.push(node);
      }
    }
  }
  return list;
}

/*
* 日期对象格式化
* */
export function formateTime(date,fmt){

  if(typeof(date)=='string'){
    return
  }

  var o = {
    "M+": date.getMonth() + 1, //月份
    "d+": date.getDate(), //日
    "h+": date.getHours(), //小时
    "m+": date.getMinutes(), //分
    "s+": date.getSeconds(), //秒
    "q+": Math.floor((date.getMonth() + 3) / 3), //季度
    "S": date.getMilliseconds() //毫秒
  };
  if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (date.getFullYear() + "").substr(4 - RegExp.$1.length));
  for (var k in o)
    if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
  return fmt;
}



/*
* 获取随机字符串
* */
const randStr = () => Math.random().toString(36).substr(2);
/*
* 判断随机字符串长度是否符合，不符合则重新获取
* */
const supplyFunc = (str, len) => {
  if(str.length > len) return str.substr(0, len);
  if(str.length < len) return supplyFunc(str + randStr(), len);
  return str;
}
/*
* 获取指定长度15的随机字符串
* */
export function randomStr() {
  return supplyFunc(randStr(), 15)
};

/*
* 线性数据转化为树。树组件转格式
* defaultProps定义原始数组内对象格式
* targetProps为输出格式
* */
export function toTree(data, parent_id, defaultProps,targetProps) {
  if(!defaultProps){
    defaultProps={
      id: 'id',
      parent_id: 'pid',
      label: 'name'
    }
  }
  if(!targetProps){
    targetProps={
      children: 'children',
      label: 'name',
      id: 'id',
      originalData: 'data'
    }
  }
  let tree = [];
  let temp;
  for (let i = 0; i < data.length; i++) {
    let dataI=data[i]
    if (dataI[defaultProps.parent_id] === parent_id) {
      let obj = {};
      obj[targetProps.originalData]=dataI
      obj[targetProps.label]=dataI[defaultProps.label]
      obj[targetProps.id]=dataI[defaultProps.id]
      temp = toTree(data,dataI[defaultProps.id],defaultProps,targetProps);
      if (temp.length > 0) {
        obj[targetProps.children] = temp;
      }
      tree.push(obj);
    }
  }
  return tree;
}
/*
* 获取指定日期的相对某一天
* */

export function GetDateStr(current,AddDayCount) {
  let dd = new Date(current);
  dd.setDate(dd.getDate()+AddDayCount);//获取AddDayCount天后的日期
  let y = dd.getFullYear();
  let m = (dd.getMonth()+1)<10?"0"+(dd.getMonth()+1):(dd.getMonth()+1);//获取当前月份的日期，不足10补0
  let d = dd.getDate()<10?"0"+dd.getDate():dd.getDate();//获取当前几号，不足10补0
  return y+"-"+m+"-"+d;
}

/*
* 获取某一个月最后一天
* */
 export function getLastMonthDay(current){
  let dd = new Date(current);
  let year=dd.getFullYear();
  let month=dd.getMonth()+1
  let day = new Date(year,month,0);
  let lastdate = day.getDate() //获取当月最后一天日期
  return year + '-' + month + '-' + (lastdate > 9 ? lastdate : ('0' + lastdate))
}

/**
 *获取几个月前的输入日期
 *{param:DateTime} date 输入日期(YYYY-MM-DD)
 *{param:number } monthNum 月数
 */
export function GetPreMonthDay(current, monthNum) {
  let dd = new Date(current);
  let year=dd.getFullYear();
  let month=dd.getMonth()+1
  let day = dd.getDay()
  var days = new Date(year, month, 0).getDate(); //获取当前日期中月的天数

  var year2 = year;
  var month2 = parseInt(month) - monthNum;
  if (month2 <= 0) {
    var absM = Math.abs(month2);
    year2 = parseInt(year2) - Math.ceil(absM / 12 == 0 ? 1 : parseInt(absM) / 12);
    month2 = 12 - (absM % 12);
  }
  var day2 = day;
  var days2 = new Date(year2, month2, 0);
  days2 = days2.getDate();
  if (day2 > days2) {
    day2 = days2;
  }
  if (month2 < 10) {
    month2 = '0' + month2;
  }
  var t2 = year2 + '-' + month2 + '-' + day2;
  return t2;
}
/**
 *获取下一个月的输入日期
 *{param:DateTime} date 输入日期(YYYY-MM-DD)
 *{param:number } monthNum 月数
 */
export function GetNextMonthDay(current, monthNum) {
  let dd = new Date(current);
  let year=dd.getFullYear();
  let month=dd.getMonth()+1
  let day = dd.getDay()
  var days = new Date(year, month, 0).getDate(); //获取当前日期中月的天数

  var year2 = year;
  var month2 = parseInt(month) + parseInt(monthNum);
  if (month2 > 12) {
    year2 = parseInt(year2) + parseInt((parseInt(month2) / 12 == 0 ? 1 : parseInt(month2) / 12));
    month2 = parseInt(month2) % 12;
  }
  var day2 = day;
  var days2 = new Date(year2, month2, 0);
  days2 = days2.getDate();
  if (day2 > days2) {
    day2 = days2;
  }
  if (month2 < 10) {
    month2 = '0' + month2;
  }

  var t2 = year2 + '-' + month2 + '-' + day2;
  return t2;
}
export function familyTree(arr, pcode) {
  var temp = [];
  var forFn = function(arr, pcode) {
    for (var i = 0; i < arr.length; i++) {
      var item = arr[i];
      if (item.menuCode == pcode) {
        temp.push(item);
        forFn(arr, item.pcode);
      }
    }
  };
  forFn(arr, pcode);
  return temp;
}

export function numberFormateThousand(value){

  if (!value) return value

  let val=parseFloat(value)

  if(!val) return value

  let arr=value.split(".")

  var re =/(-?\d+)(\d{3})/
  while(re.test(arr[0])){
    arr[0] =arr[0].replace(re,"$1,$2")
  }

  value=arr.join(".")
  return value
}

function urlEncode(param, key, encode) {
  if (param==null) return '';
  var paramStr = '';
  var t = typeof (param);
  if (t == 'string' || t == 'number' || t == 'boolean') {
    paramStr += '&' + key + '='  + ((encode==null||encode) ? encodeURIComponent(param) : param);
  } else {
    for (var i in param) {
      var k = key == null ? i : key + (param instanceof Array ? '[' + i + ']' : '.' + i)
      paramStr += urlEncode(param[i], k, encode)
    }
  }
  return paramStr;

}

export function objToUrlEncode(param, key, encode) {
  let params=urlEncode(param, key, encode)
  params=params.length>0?params.slice(1):''
  return params
}
