'use strict';

Object.defineProperty(exports, '__esModule', { value: true });

var number_number = require('../number/number.js');

function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) throw o; } } }; }
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
/**
 * 判断数组是否全部相等
 * @param {Array<number | string>} list - 数组
 * @returns {Boolean} 是否全部相等
 *
 * @example
 * isListAllEqual([0, 0, 0])
 *
 * // true
 *
 * isListAllEqual([0, 0, 2])
 *
 * // false
 */
function isListAllEqual() {
  var list = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
  if (!list.length) return true;
  var value = list[0];
  var _iterator = _createForOfIteratorHelper(list.slice(1)),
    _step;
  try {
    for (_iterator.s(); !(_step = _iterator.n()).done;) {
      var item = _step.value;
      if (item !== value) return false;
    }
  } catch (err) {
    _iterator.e(err);
  } finally {
    _iterator.f();
  }
  return true;
}
/**
 * 获取对象的value列表，并输出大对象形式
 * @param {Array<any>} data
 * @returns {Object} 处理后的对象
 *
 * @example
 *
 * const data = [
 * {
 *   Project: 'x',
 *   Request: 1,
 *   Score: 'a'
 * },
 * {
 *   Project: 'y',
 *   Request: 2,
 *   Score: 'b'
 * }]
 *
 * getKeyValuesMap(data)
 *
 * // 结果为:
 * {
 *   Project: ['x', 'y'],
 *   Request: [1, 2],
 *   Score: ['a', 'b'],
 * }
 *
 * // 也支持参数为带value属性的对象数组，如：
 *
 * const data = [
 * {
 *   Project: {
 *     value: 'x'
 *   }
 * },{
 *   Project: {
 *     value: 'y'
 *   }
 * }]
 *
 * // 结果为：
 * {
 *   Project: ['x', 'y']
 * }
 */
function getKeyValuesMap() {
  var data = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
  if (!data.length) return {};
  var keys = Object.keys(data[0]);
  var keyValueMap = {};
  data.forEach(function (item) {
    keys.forEach(function (key) {
      var _a;
      // 如果有value，就取value，否则直接取item[key]
      var value = ((_a = item[key]) === null || _a === void 0 ? void 0 : _a.value) || item[key];
      if (keyValueMap[key]) {
        keyValueMap[key].push(value);
      } else {
        keyValueMap[key] = [value];
      }
    });
  });
  return keyValueMap;
}
/**
 * 标记最大最小值
 * @private
 * @param {object} params 参数对象
 * @param {Array<number>} params.values 待处理的数组
 * @param {number} params.value 当前值
 * @param {Object} params.obj 迭代中的对象
 * @returns {Object} 处理后的对象
 */
function markMaxAndMinOfObj(_ref) {
  var values = _ref.values,
    value = _ref.value,
    obj = _ref.obj;
  var idx = values.indexOf(value);
  var lastIdx = values.indexOf(value);
  var newObj = Object.assign(Object.assign({}, obj), {
    idx: idx,
    lastIdx: lastIdx
  });
  if (!isListAllEqual(values)) {
    var len = values.length;
    var isMax = idx === 0;
    var isSecondMax = idx === 1;
    var isMin = idx === len - 1;
    var isSecondMin = idx === len - 2;
    newObj = Object.assign(Object.assign({}, newObj), {
      isMax: isMax,
      isMin: isMin,
      isSecondMax: isSecondMax,
      isSecondMin: isSecondMin
    });
  }
  return newObj;
}
/**
 * 获取相对上次的比例，会给输入的对象数组的每一项增加 ratio、previousValue 属性
 * @param {Array<Object>} data - 输入数据
 * @param {Object} preDataMap - 上次数据的map
 * @param {string} uniqKey - 唯一键
 *
 * @example
 * const data = [{
 *   Project: { value: 'mj-match', name: 'Project' },
 *   Request: {
 *     value: 854,
 *     name: 'Request',
 *     idx: 19,
 *     lastIdx: 19,
 *     isMax: false,
 *     isMin: false,
 *     isSecondMax: false,
 *     isSecondMin: true,
 *   },
 * }];
 *
 * const preDataMap = {
 *   'mj-match': {
 *     Project: 'mj-match',
 *     Request: 4,
 *     Score: 91.81,
 *     FirstLoadTime: 178,
 *     WholePageTime: 1035,
 *     ParseDomTime: 484,
 *     DNSLinkTime: 0,
 *     DOMTime: 414,
 *     TCP: 0,
 *     HTTP: 275,
 *     BackEnd: 60,
 *     CGIFailNum: 0,
 *     ErrorLogNum: 0,
 *     CGIRequestNum: 83,
 *   },
 * };
 *
 * getPreviousRatio(data, preDataMap);
 *
 * // data会变成：
 * [{
 *   Project: { value: 'mj-match', name: 'Project' },
 *   Request: {
 *     value: 854,
 *     name: 'Request',
 *     idx: 19,
 *     lastIdx: 19,
 *     isMax: false,
 *     isMin: false,
 *     isSecondMax: false,
 *     isSecondMin: true,
 *
 *     previousValue: 4, // 新增属性
 *     ratio: "+999+%" // 新增属性
 *   },
 * }];
 */
function getPreviousRatio() {
  var data = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
  var preDataMap = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  var uniqKey = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'Project';
  data.forEach(function (item) {
    Object.keys(item).forEach(function (key) {
      var _a, _b;
      var obj = item[key];
      if (typeof (obj === null || obj === void 0 ? void 0 : obj.value) === 'number') {
        var uniqVal = (_a = item[uniqKey]) === null || _a === void 0 ? void 0 : _a.value;
        var preValue = (_b = preDataMap === null || preDataMap === void 0 ? void 0 : preDataMap[uniqVal]) === null || _b === void 0 ? void 0 : _b[key];
        if (preValue === undefined) {
          obj.ratio = '';
        } else {
          obj.ratio = number_number.getUnitPreviousRatio(obj.value, preValue);
          obj.previousValue = preValue;
        }
      }
    });
  });
}
/**
 * 给对象数组的每一项，添加isMax、isMin、、isSecondMax、isSecondMin、idx、lastIdx等属性
 * @param {Array<object>} data 原始数据
 * @param {Array<string>} reverseScoreKeys - 逆序的key列表
 * @returns {Object} 处理后的数据
 *
 * @example
 * const data = [{
 *   ProjectName: { name: 'ProjectName', value: '麻将赛事' },
 *   PagePv: { name: 'PagePv', value: 2877 },
 * }, {
 *   ProjectName: { name: 'ProjectName', value: '斗地主赛事' },
 *   PagePv: { name: 'PagePv', value: 7 },
 * },
 * // ...
 * ];
 *
 * getMaxAndMinIdx(data, [])
 *
 * // =>
 *   [{
 *     ProjectName: { name: 'ProjectName', value: '麻将赛事' },
 *     PagePv: {
 *       name: 'PagePv',
 *       value: 2877,
 *       idx: 6,
 *       lastIdx: 6,
 *       isMax: false,
 *       isMin: false,
 *       isSecondMax: false,
 *       isSecondMin: false,
 *     },
 *   }];
 *
 */
function getMaxAndMinIdx() {
  var data = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
  var reverseScoreKeys = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
  if (!data.length) return [];
  var keys = Object.keys(data[0]);
  var keyValueMap = getKeyValuesMap(data);
  var parsedData = data.map(function (item) {
    var temp = Object.assign({}, item);
    keys.forEach(function (key) {
      var values = keyValueMap[key];
      var itemInfo = item[key] || {};
      if (values && typeof itemInfo.value === 'number') {
        if (reverseScoreKeys.indexOf(key) > -1) {
          values.sort(function (a, b) {
            if (a > b) return 1;
            if (a < b) return -1;
            return 0;
          });
        } else {
          values.sort(function (a, b) {
            if (a > b) return -1;
            if (a < b) return 1;
            return 0;
          });
        }
        temp[key] = markMaxAndMinOfObj({
          values: values,
          value: itemInfo.value,
          obj: temp[key]
        });
      }
    });
    return temp;
  });
  return parsedData;
}
/**
 * 拉平之前数据
 * @param {Array<Object>} preDataList 之前的数据，作为对照
 * @param {string} key 主键
 * @returns {Object} preDataMap
 *
 * @example
 * const data = [{
 *   ProjectName: { name: 'ProjectName', value: '研发平台' },
 *   PagePv: { name: 'PagePv', value: 152 },
 *   PageUv: { name: 'PageUv', value: 7 },
 *   Score: { name: 'Score', value: 93.92 },
 *   PageDuration: { name: 'PageDuration', value: 1281.58 },
 *   PageError: { name: 'PageError', value: 2 },
 * }];
 *
 * flattenPreData(data, 'ProjectName');
 *
 * // 输出
 * {
 *   研发平台: {
 *     ProjectName: '研发平台',
 *     PagePv: 152,
 *     PageUv: 7,
 *     Score: 93.92,
 *     PageDuration: 1281.58,
 *     PageError: 2,
 *   },
 * };
 */
function flattenPreData(preDataList, key) {
  var preDataMap = preDataList.reduce(function (acc, item) {
    var _a;
    acc[((_a = item[key]) === null || _a === void 0 ? void 0 : _a.value) || 'DEFAULT_KEY'] = Object.values(item).reduce(function (ac, it) {
      ac[it.name] = it.value;
      return ac;
    }, {});
    return acc;
  }, {});
  return preDataMap;
}
/**
 * 对比两个对象列表
 * @param {Array<object>} list 现在数据
 * @param {Array<object>} preList 参照数据
 * @param {string} key 唯一key名称
 * @returns {Array<object>} 对比结果，增加为list的每一项增加previousValue和ratio属性
 * @example
 * const list = [
 *   {
 *     ProjectName: { name: 'ProjectName', value: '脚手架' },
 *     PagePv: { name: 'PagePv', value: 544343 },
 *     PageUv: { name: 'PageUv', value: 225275 },
 *   }
 * ]
 *
 * const preList = [
 *   {
 *     ProjectName: { name: 'ProjectName', value: '脚手架' },
 *     PagePv: { name: 'PagePv', value: 123123 },
 *     PageUv: { name: 'PageUv', value: 33333 },
 *   }
 * ]
 *
 * compareTwoList(list, preList, 'ProjectName')
 *
 * console.log(list)
 *
 * [
 *   {
 *     ProjectName: { name: 'ProjectName', value: '脚手架' },
 *     PagePv: {
 *       name: 'PagePv',
 *       value: 544343,
 *       ratio: '+342.1%',
 *       previousValue: 123123
 *     },
 *     PageUv: {
 *       name: 'PageUv',
 *       value: 225275,
 *       ratio: '+575.8%',
 *       previousValue: 33333
 *     }
 *   }
 * ]
 */
function compareTwoList(list, preList, key) {
  var preDataMap = flattenPreData(preList, key);
  getPreviousRatio(list, preDataMap, key);
  return list;
}

exports.compareTwoList = compareTwoList;
exports.flattenPreData = flattenPreData;
exports.getKeyValuesMap = getKeyValuesMap;
exports.getMaxAndMinIdx = getMaxAndMinIdx;
exports.getPreviousRatio = getPreviousRatio;
exports.isListAllEqual = isListAllEqual;
