/**
 * demo:
 * arr = [{name: "zhang", value: 2}]
 * key = "name"
 * return {zhang: {name: "zhang", value: 2}}
 *
 * @param {Array} arr
 * @param {String} key
 * @param {String} valueKey 需求的字段，不传则返回整个item
 * @returns {Object}
 */
export function arrToMap(arr, key, valueKey) {
  return (arr || []).reduce((target, item) => {
    if (valueKey) {
      target[item[key]] = item[valueKey];
    } else {
      target[item[key]] = item;
    }
    return target;
  }, {});

  
}

/**
 * 同 arrToMap， 返回的数据结构为Map
 * @param {Array} arr
 * @param {String} key
 * @param {String} valueKey 需求的字段，不传则返回整个item
 * @returns {Map}
 */
export function arrToRealMap(arr, key, valueKey) {
  const map = new Map();
  (arr || []).forEach((item) => {
    if (valueKey) {
      map.set(item[key], item[valueKey]);
    } else {
      map.set(item[key], item);
    }
  });
  return map;
}

// 基础数据类型的深拷贝
export function baseDeepClone(target) {
  return JSON.parse(JSON.stringify(target));
}

/**
 * string 属性去前后空格
 * @param { Object } obj
 */
export function objTrim(obj = {}) {
  const _trim = (root) => {
    for (let attr in root) {
      let value = root[attr];
      if (typeof value === "string") {
        // string
        root[attr] = value.trim();
      } else if (value && typeof value === "object") {
        // array, object
        _trim(root[attr]);
      }
    }
  };
  _trim(obj);
  return obj;
}

/**
 * 排序
 */
export function sortBy(arr = [], sortKey = "sortNo", ascDesc = "asc") {
  if (ascDesc === "asc") (arr || []).sort((a, b) => a[sortKey] - b[sortKey]);
  else (arr || []).sort((a, b) => b[sortKey] - a[sortKey]);
}

/**
 * string 校准页码 处理只有一条数据删除时或批量全删除方舟bug
 * @param { Object } el 实例
 */
export function updateLastPage(el) {
  if (
    (el.tableData.length === 1 && el.currentPage != 1) ||
    (el.tableData.length === el.selectTableData.length && el.currentPage != 1)
  ) {
    const page = el.getCurrentPage();
    el.setCurrentPage(page - 1);
    return;
  }
  return;
}

/**
 * 根据value查询树结构label
 * @param { Array } treeList 树结构数据
 * @param { String, Number } value 对应value值
 */
export function formatLabel(treeList, value) {
  let label = "";
  const loop = (list) => {
    list.forEach((item) => {
      if (item.value === value) {
        label = item.label;
      }
      if (item.children) {
        loop(item.children);
      }
    });
  };
  loop(treeList);
  return label;
}

/**
 * 四舍五入, 与数学中的规则相同
 * toFixed是银行家舍入法,与数学中的规则不同
 * round是奇进偶舍,与数学中的规则不同
 * @param num_ 数字
 * @param decimals 位数
 * @param intReplenish 整数后面是否补零
 * @returns {string|string}
 */
export function ibfRound(num_, decimals = 2, intReplenish = false) {
  let num = num_ + "";
  if (!~num.indexOf(".")) {
    if (intReplenish && decimals > 0) {
      num += ".";
      for (let i = 0; i < decimals; i++) {
        num += "0";
      }
      return num;
    } else {
      return num_;
    }
  }
  let lis = num.split(".");
  let decimalPart = lis[1];
  if (decimalPart.length > decimals) {
    if (Number(decimalPart[decimals] >= 5)) {
      let result = advOne(lis[0] + "." + decimalPart.substring(0, decimals));
      return decimals === 0 ? result.replace(".", "") : result;
    } else {
      let result = lis[0] + "." + decimalPart.substring(0, decimals);
      return decimals === 0 ? result.replace(".", "") : result;
    }
  } else if (decimalPart.length === decimals) {
    return num;
  } else {
    let diff = decimals - decimalPart.length;
    let s = "";
    for (let i = 0; i < diff; i++) {
      s += "0";
    }
    return num + s;
  }
}
// 往前进一
function advOne(str) {
  let isIndex = -1;
  for (let i = str.length - 1; i >= 0; i--) {
    if (str[i] === ".") continue;
    if (Number(str[i]) !== 9) {
      isIndex = i;
      break;
    }
  }
  if (!~isIndex) {
    return "1" + str.replaceAll("9", "0");
  }
  let listReverse = [];
  let done = false;

  function loop(idx) {
    if (idx < 0) {
      return;
    }
    if (done) {
      listReverse.push(str[idx]);
    } else if (str[idx] === ".") {
      listReverse.push(".");
    } else if (Number(str[idx]) === 9) {
      listReverse.push("0");
    } else if (idx === isIndex) {
      listReverse.push(Number(str[idx]) + 1);
      done = true;
    }
    idx--;
    loop(idx);
  }

  loop(str.length - 1);
  return listReverse.reverse().join("");
}

/**
 * 格式化字典项/业务参数项编码
 * @param { String} code 字典项/业务参数项编码
 */
export function formatCode(code) {
  if (code?.includes("-")) {
    const codelist = code.split("-");
    return codelist[codelist.length - 1];
  } else {
    return code;
  }
}

export function _throttle(fn, wait = 500) {
  let last, now;
  return function () {
    now = Date.now();
    if (last && now - last < wait) {
      last = now;
    } else {
      last = now;
      fn.call(this, ...arguments);
    }
  };
}
/**
 * 判断空
 * */
export function empty(v) {
  switch (typeof v) {
    case "undefined":
      return true;
    case "string":
      if (v.trim().length == 0) return true;
      break;
    case "boolean":
      if (!v) return true;
      break;
    case "number":
      if (0 === v) return false;
      break;
    case "object":
      if (null === v) return true;
      if (undefined !== v.length && v.length == 0) return true;
      for (var k in v) {
        return false;
      }
      return true;
  }
  return false;
}

/**
 * 转换人员
 * @param { list }  人员数组对象
 * @param { idString }  人员名称长字符串
 * @param { nameString }  人员id长字符串
 * @param { list.id }  人员数组对象 代表id的字段名
 * @param { list.name }  人员数组对象 代表name的字段名
 *
 * */
export function formatUserList({
  idString = "",
  nameString = "",
  list = [],
  id = "fd_username",
  name = "fd_display_name",
}) {
  if (list && list.length > 0) {
    var userId = "";
    var userName = "";
    list.forEach((element) => {
      userId += `${element[id]},`;
      userName += `${element[name]},`;
    });
    userId = userId.slice(0, userId.length - 1);
    userName = userName.slice(0, userName.length - 1);
    return {
      userId,
      userName,
      userList: [],
    };
  } else if (idString && nameString) {
    var idList = idString.split(",");
    var nameList = nameString.split(",");
    const userList = [];
    idList.forEach((element, i) => {
      nameList.forEach((item, index) => {
        if (index === i) {
          userList.push({
            fd_username: element,
            fd_display_name: item,
          });
        }
      });
    });
    return {
      userList,
      userId: "",
      userName: "",
    };
  } else {
    return {
      userList: [],
      userId: "",
      userName: "",
    };
  }
}

// 判断是否是对象
export function isObject(value) {
  // * 判断是否是一个对象
  const valueType = typeof value;
  // * 注意：null也是一个对象
  return value !== null && (valueType == "object" || valueType == "function");
}

// 复杂数据深拷贝
export function complexDeepClone(originValue) {
  // * 1. 判断是否是一个Set类型
  if (originValue instanceof Set) {
    let set = new Set();
    originValue.forEach((key) => {
      set.add(complexDeepClone(key));
    });
    return set;
  }

  // * 2. 判断是否是一个Map类型
  if (originValue instanceof Map) {
    let map = new Map();
    originValue.forEach((key, value) => {
      originValue.set(complexDeepClone(key), complexDeepClone(value));
    });
    return map;
  }

  // *3. 判断如果是Symbol的value，那么创建一个新的Symbol
  if (typeof originValue == "symbol") return Symbol(originValue.description);

  // * 4..判断如果是函数类型，那么直接使用同一个函数
  if (typeof originValue == "function") return originValue;

  // 判断传入的originValue 是否是一个对象
  // * 5. 如果不是一个对象，直接将值返回
  if (!isObject(originValue)) return originValue;

  // * 6.判断对象是否为数组还是对象，如果为数组，初始为[]，否则为{}
  const newObject = Array.isArray(originValue) ? [] : {};
  for (const key in originValue) {
    newObject[key] = complexDeepClone(originValue[key]);
  }

  // * 对Symbol的key进行特殊处理
  const symbolKeys = Object.getOwnPropertySymbols(originValue);
  for (const sKey of symbolKeys) {
    newObject[sKey] = complexDeepClone(originValue[sKey]);
  }
  return newObject;
}

// 树转平铺
export function setTreeFormatList(arr) {
  let data = JSON.parse(JSON.stringify(arr)); // 对传入的参数进行深拷贝
  let newData = []; // 创建空数组用来接收操作后的新数组
  const hasChildren = (item) => {
    // 递归遍历，把包含children的选项拿出来，push到之前新建的空数组内
    (item.children || (item.children = [])).map((v) => {
      hasChildren(v);
    });
    delete item.children; // 删除原children属性，可选项
    newData.push(item);
  };
  data.map((v) => hasChildren(v));
  return newData;
}

// 初始化数组长度为n的记录
export function genTimesArray(times, callback) {
  let arr = [];
  for (let i = 0; i < times; i++) {
    arr.push(callback(i));
  }
  return arr;
}

// 浅拷贝属性，但排除自定的字段
export function excludeAttr(target, attrKeys) {
  if (!target) return {};
  const obj = {};
  Object.keys(target).forEach((attrKey) => {
    if (!attrKeys.includes(attrKey)) {
      obj[attrKey] = target[attrKey];
    }
  });
  return obj;
}

// 浅拷贝属性，复制特定字段
export function copyAttr(target, attrKeys) {
  if (!target) return {};
  const obj = {};
  (attrKeys || []).forEach((attrKey) => {
    obj[attrKey] = target[attrKey];
  });
  return obj;
}

/**
 * 安全访问目标，若是函数则调用，否则直接转boolean
 * @param {Function|Boolean} target
 * @param {*} payload
 */
export function safeCallFuncBool(target, payload) {
  if (typeof target === "function") {
    return target(payload);
  }
  return !!target;
}

/**
 * 转换校验结果为Promise
 * @param {Function} validate
 * @param {Boolean} isCallbackMode 校验方法是否为回调模式，否则为直接返回true/false模式
 * @returns
 */
export function resolveValidate(validate, isCallbackMode = true) {
  return new Promise((resolve, reject) => {
    const done = (valid) => {
      if (valid) return resolve();
      reject();
    };
    if (!validate) return reject();
    if (isCallbackMode) {
      validate(done);
    } else {
      done(validate());
    }
  });
}

// 金额千分位显示
export function getThousandsValue(value) {
  if (!value) return 0;
  return Number(value).toLocaleString("en-us");
}
