import moment from 'moment';
const utils = {
  loading: false,
  //深度拷贝
  jsoncopy(obj) {
    if (!obj) {
      return null;
    }
    return JSON.parse(JSON.stringify(obj));
  },
  //检查对象是否为空
  oIsEmp(obj) {
    return Object.keys(obj).length === 0;
  },
  //深度拷贝
  deepClone(source) {
    const targetObj =
      Object.prototype.toString.call(source) === "[object Array]" ? [] : {}; // 判断复制的目标是数组还是对象
    for (const keys in source) {
      // 遍历目标
      if (source.hasOwnProperty(keys)) {
        //只拷贝自身属性，原型链上不考虑
        if (source[keys] && typeof source[keys] === "object") {
          // 如果值是对象，就递归一下
          targetObj[keys] =
            Object.prototype.toString.call(source[keys]) == "[object Array]"
              ? []
              : {};
          targetObj[keys] = utils.deepClone(source[keys]);
        } else {
          // 如果不是，就直接赋值
          targetObj[keys] = source[keys];
        }
      }
    }
    return targetObj;
  },
  /**
   *
   * @desc 防止重复执行 callback 中的代码
   * @param  {func} cb callback
   * @param  {int} time 设置多少时间后可以再次执行
   * @return
   */
  preventRepeat(cb, time) {
    if (typeof cb === "function") {
      try {
        if (this.loading) {
          return;
        } else if (this.loading === false) {
          this.loading = true;

          cb(this.loading);
          window.setTimeout(() => {
            this.loading = false;
          }, time);
        }
      } catch (err) {
        console.err(err);
        this.loading = false;
      }
    }
  },
  /**
   *
   * @desc 防止重复执行 callback 中的代码
   * @param  {func} cb(callback(func(resolve))) 回调中包含回调
   * @return
   */
  preventRepeatAsync(cb) {
    if (typeof cb === "function") {
      try {
        if (this.loading) {
          return;
        } else if (this.loading === false) {
          this.loading = true;
          const _this = this;

          function callback(func) {
            return new Promise(resolve => {
              func(resolve);
            });
          }

          async function asyncFun() {
            await cb(callback);
            _this.loading = false;
          }

          return asyncFun();
        }
      } catch (err) {
        console.error(err);
        this.loading = false;
      }
    }
  },
  /*
  * 防止重复提交 简化
  */
  preventRA(cb) {
    if (!cb) {
      throw new Error("请传入 callback");
      return;
    }
    this.preventRepeatAsync((callback) => callback((resolve) => {
      cb(resolve);
    }));
  },

  /**
   *
   * @desc 传入的数组指定位置交换顺序
   * @param  {int} start数组元素起始位置
   * @param  {int} end数组元素结束位置
   * @return {Array}
   */
  switchArr(arr, start, end) {
    const newArr = this.jsoncopy(arr);
    newArr[start] = [...newArr.splice(end, 1, newArr[start])[0]];
    return newArr;
  },

  /**
   *
   * @desc 在指定位置之后插入数组
   * @param  Array 待插入的数组
   * @param  index 指定位置
   * @param  obj 待插入数据
   * @return {Array}
   */
  insertArr(arr, index, obj) {
    const newArr = this.jsoncopy(arr);
    newArr.splice(index + 1, 0, obj);
    return newArr;
  },

  /**
   *
   * @desc 传入的数组 去重
   * @param  {Array} array 传入数组
   * @return {Array} 返回去掉重复项的数组
   */
  arrayPreventRepeat(array) {
    return Array.from(new Set(array));
  },

  /**
   *
   * @desc 传入的对象返回 数据类型
   * @return {string}   "String","Number","Array"
   */
  objType(obj) {
    return Object.prototype.toString.call(obj).slice(8, -1);
  },
  /**
   * @desc  转换星期
   */
  changeWeekData(int) {
    const week = {
      1: "周一",
      2: "周二",
      3: "周三",
      4: "周四",
      5: "周五",
      6: "周六",
      7: "周日",
    };
    return week[parseInt(int)];
  },
  /**
   * @desc  数字转汉字
   * @param int
   */
  changeIntData(int) {
    const obj = {
      1: "一",
      2: "二",
      3: "三",
      4: "四",
      5: "五",
      6: "六",
      7: "日",
    };
    return obj[parseInt(int)];
  },

  /**
   * @desc  格式化 html
   * @param string| HtmlElement  带html 元素的字符串
   * @return 取出其中的文字
   */
  formatHtml(str) {
    return str.replace(/<[^<>]+>/g, "");
  },


  /**
   * @desc  初始化数据，非空 转换
   *
   */
  initAjaxData(dataObj, model) {
    // 数据补齐
    const arrayObjClone = (dataObj, model) => {

      let newModel = utils.jsoncopy(model);
      const arrCopy = (dataObj, target) => {
        let copyData = target[0];
        for (let i = 1; i < dataObj.length; i++) {
          target.push(arrayObjClone(dataObj[i], copyData));
        }
        return target;
      };
      if (utils.objType(newModel) !== utils.objType(dataObj)) {
        return newModel;
      }
      if (Object.prototype.toString.call(dataObj) === "[object Array]") {
        newModel = arrCopy(dataObj, newModel);
      }
      if (Object.prototype.toString.call(dataObj) === "[object Object]") {
        for (const keys in dataObj) {
          // 遍历目标
          if (dataObj.hasOwnProperty(keys)) {
            //只拷贝自身属性，原型链上不考虑
            if (dataObj[keys] && utils.objType(dataObj[keys]) === "Array") {
              // 如果值是对象，就递归一下
              const data = arrCopy(dataObj[keys], newModel[keys]);
              newModel[keys] = data;
            }
          }
        }
      }

      return newModel;
    };

    //初始化数据，非空 转换
    const initAjaxCopy = (dataObj, model) => {

      // 判断复制的目标是数组还是对象
      const targetObj = Object.prototype.toString.call(model) === "[object Array]" ? [] : {};

      for (const keys in model) {
        // 遍历目标
        if (model.hasOwnProperty(keys)) {
          //只拷贝自身属性，原型链上不考虑
          if (model[keys] && typeof model[keys] === "object") {
            // 如果值是对象，就递归一下
            targetObj[keys] = Object.prototype.toString.call(model[keys]) == "[object Array]" ? [] : {};
            targetObj[keys] = initAjaxCopy(dataObj[keys], model[keys]);
          } else {
            // 如果不是空值，就直接赋值
            if (dataObj[keys]) {
              targetObj[keys] = dataObj[keys];
            } else {
              targetObj[keys] = model[keys];
            }
          }
        }
      }
      return targetObj;
    };

    const newModel = arrayObjClone(dataObj, model);
    const data = initAjaxCopy(dataObj, newModel);
    return data;
  },

  /**
   *
   * @desc   Array|obj 去除数组中重复的对象
   * @param  {Array} array 传入数组
   * @param {String} 去重的关键 key
   */
  removeDuplicateObj(array, key, callback) {
    let hash = {};
    let arr = utils.jsoncopy(array);
    arr = arr.reduce((acc, item) => {
      if (hash[item[key]]) {
        callback && callback(item[key]);
      } else {
        hash[item[key]] = true && acc.push(item);
      }
      return acc;
    }, []);
    return arr;
  },


  /**
   *
   * @desc   格式化时间
   * @param  {moment} moment时间对象
   * @param {String} 格式化后的时间
   */
  formatData(obj, f = "YYYY-MM-DD") {
    return moment(obj).format(f);
  },
  /**
   *
   * @desc   格式化时间
   * @param  {moment} moment时间对象
   * @param {String} 格式化后的时间
   */
  currentData(f = "YYYY-MM-DD") {
    return moment().format(f);
  },

  /************
   * @desc  检测IE浏览器，判断是否是IE浏览器或者谷歌浏览器不大于53
   */
  isIEBrowser() {
    // 浏览器检测脚本
    const chrome = navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)\./);
    if (chrome) {
      const chromeVersion = parseInt(chrome[2], 10);
      //chrome浏览器 这里会输出chrome版本
      if (chromeVersion <= 53) {
        return true;
      }
    } else {
      const ieVersion = this.detectIE();
      if (ieVersion !== false) {
        //ie浏览器 这里会输出ie版本，自己判断下
        return true;
      } else {
        //其他浏览器
      }
    }
  },
  detectIE() {
    const ua = window.navigator.userAgent;

    // Test values; Uncomment to check result …

    // IE 10
    // ua = 'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; Trident/6.0)';

    // IE 11
    // ua = 'Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko';

    // Edge 12 (Spartan)
    // ua = 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36 Edge/12.0';

    // Edge 13
    // ua = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2486.0 Safari/537.36 Edge/13.10586';

    const msie = ua.indexOf('MSIE ');
    if (msie > 0) {
      // IE 10 or older => return version number
      return parseInt(ua.substring(msie + 5, ua.indexOf('.', msie)), 10);
    }

    const trident = ua.indexOf('Trident/');
    if (trident > 0) {
      // IE 11 => return version number
      const rv = ua.indexOf('rv:');
      return parseInt(ua.substring(rv + 3, ua.indexOf('.', rv)), 10);
    }

    const edge = ua.indexOf('Edge/');
    if (edge > 0) {
      // Edge (IE 12+) => return version number
      return false;
    }

    // other browser
    return false;
  }

};


export default utils;



