import format from 'date-fns/format';
import cnLocale from 'date-fns/locale/zh_cn';
import parse from 'date-fns/parse';
import { clone } from 'ramda';

// string -> date
const s2m = (input) => input ? parse(input) : '';
const s2d = (input) => input ? parse(input) : '';
const ymd = (input) => input ? format(parse(input), 'YYYY-MM-DD', { locale: cnLocale }) : '';
const dtm = (input) => input ? format(parse(input), 'YYYY-MM-DD HH:mm:ss', { locale: cnLocale }) : '';

const s2t = (input) => input ? format(parse(input), 'YYYY-MM-DDTHH:mm:ss', { locale: cnLocale }) : '';

/**
 * Get a random floating point number between `min` and `max`.
 *
 * @param {number} min - min number
 * @param {number} max - max number
 * @return {float} a random floating point number
 */
const getRandom = (min, max) => {
  return Math.random() * (max - min) + min;
};

/**
 * Get a random integer between `min` and `max`.
 *
 * @param {number} min - min number
 * @param {number} max - max number
 * @return {int} a random integer
 */
const getRandomInt = (min, max) => {
  return Math.floor(Math.random() * (max - min + 1) + min);
};

/**
 * 数组内查询
 * @param   {array}      array
 * @param   {String}    id
 * @param   {String}    keyAlias
 * @return  {Array}
 */
const queryArray = (array, key, keyAlias = 'key') => {
  if (!(array instanceof Array)) {
    return null;
  }
  const item = array.filter((_) => _[keyAlias] === key);
  if (item.length) {
    return item[0];
  }
  return null;
};

/**
 * 数组格式转树状结构
 * @param   {array}     array
 * @param   {String}    id
 * @param   {String}    pid
 * @param   {String}    children
 * @return  {Array}
 */
const arrayToTree = (array, id = 'id', pid = 'pid', children = 'children') => {

  const data = clone(array);
  const result = [];
  const hash = {};
  data.forEach((item, index) => {
    hash[data[index][id]] = data[index];
  });

  data.forEach((item) => {
    const hashVP = hash[item[pid]];
    if (hashVP) {
      !hashVP[children] && (hashVP[children] = []);
      hashVP[children].push(item);
    } else {
      result.push(item);
    }
  });
  return result;
};

/**
 * Convert amount to RMB
 * @param   {float}    num
 * @return  {String}
 */
const moneyToRMB = (num: number | string) => {
  if (typeof num !== 'number') {
    return '无效数值';
  }
  let strPrefix = '';
  if (num < 0) {
    strPrefix = '(欠)人民币';
  }
  num = Math.abs(num);
  if (num >= 1000000000000) {
    return '[超出最大数值]';
  }
  let strOutput = '';
  let strUnit = '仟佰拾亿仟佰拾万仟佰拾圆角分';
  const strCapDgt = '零壹贰叁肆伍陆柒捌玖';
  let temp = num + '';
  temp += '00';
  const intPos = temp.indexOf('.');
  if (intPos >= 0) {
    temp = temp.substring(0, intPos) + temp.substr(intPos + 1, 2);
  }
  strUnit = strUnit.substr(strUnit.length - temp.length);
  for (let i = 0; i < temp.length; i++) {
    strOutput += strCapDgt.substr(temp.substr(i, 1), 1) + strUnit.substr(i, 1);
  }
  return strPrefix + strOutput
    .replace(/零角零分$/, '整')
    .replace(/零[仟佰拾]/g, '零')
    .replace(/零{2,}/g, '零')
    .replace(/零([亿|万])/g, '$1')
    .replace(/零+圆/, '圆')
    .replace(/亿零{0,3}万/, '亿')
    .replace(/^圆/, '零圆');
};

const toUppercaseDigit = (num) => {
  if (isNaN(num)) {
    return '无效数值！';
  }
  let strPrefix = '';
  if (num < 0) {
    strPrefix = '(欠)人民币';
  }
  num = Math.abs(num);
  if (num >= 1000000000000) {
    return '[超出最大数值]';
  }
  let strOutput = '';
  let strUnit = '仟佰拾亿仟佰拾万仟佰拾圆角分';
  const strCapDgt = '零壹贰叁肆伍陆柒捌玖';
  num += '00';
  const intPos = num.indexOf('.');
  if (intPos >= 0) {
    num = num.substring(0, intPos) + num.substr(intPos + 1, 2);
  }
  strUnit = strUnit.substr(strUnit.length - num.length);
  for (let i = 0; i < num.length; i++) {
    strOutput += strCapDgt.substr(num.substr(i, 1), 1) + strUnit.substr(i, 1);
  }
  return strPrefix + strOutput.replace(/零角零分$/, '整').replace(/零[仟佰拾]/g, '零').replace(/零{2,}/g, '零').replace(/零([亿|万])/g, '$1').replace(/零+圆/, '圆').replace(/亿零{0,3}万/, '亿').replace(/^圆/, '零圆');
};

/**
 * Convert queryString to object
 * @param   {String}    qs
 * @return  {Object}
 */
const queryStringToJSON = (qs) => {
  const pairs = qs.slice(1).split('&');

  const result = {};
  pairs.forEach((pair) => {
    pair = pair.split('=');
    result[pair[0]] = decodeURIComponent(pair[1] || '');
  });

  return JSON.parse(JSON.stringify(result));
};

const validAmtFormat = (n) => {
  let amt = 0;

  if (n === null || n === undefined) {
    return false;
  }

  if (typeof n === 'string') {
    if (!(/^-?\d*(\.\d+)?$/.test(n))) {  // check float
      return false;
    } else {
      amt = parseFloat(n);
    }
  } else {
    amt = n;
  }

  const patt = /^\s*-?\d+(\.\d{1,2})?\s*$/;

  if (!patt.test(amt)) {  // check tow decimal
    return false;
  }
  return true;
};

const limitDecimals = (value) => {
  const reg = /^(\-)*(\d+)\.(\d\d).*$/;
  if (typeof value === 'string') {
    return !isNaN(Number(value)) ? value.replace(reg, '$1$2.$3') : '';
  } else if (typeof value === 'number') {
    return !isNaN(value) ? String(value).replace(reg, '$1$2.$3') : '';
  } else {
    return '';
  }
};

const updateTree = (tree, keyToFind, valueToFind, keyToUpdate, valueToUpdate) => {
  // console.log(tree, keyToFind, valueToFind, keyToUpdate, valueToUpdate)
  // console.log(tree[keyToFind], valueToFind)
  tree.forEach((t) => {
    if (t[keyToFind] === valueToFind) {
      t[keyToUpdate] = valueToUpdate;
    }
    if (t.children && t.children.length) {
      return updateTree(t.children, keyToFind, valueToFind, keyToUpdate, valueToUpdate);
    } else {
      return t;
    }
  });
  return tree;
};

export default {
  s2m,
  s2d,
  ymd,
  dtm,
  updateTree,
  toUppercaseDigit,
  getRandom,
  getRandomInt,
  queryArray,
  arrayToTree,
  moneyToRMB,
  queryStringToJSON,
  validAmtFormat,
  limitDecimals,
};
