const deepmerge = require("deepmerge");

/**
 * 判断对象类型
 * @param {*} obj 对象
 */
function objTypeOf(obj) {
  const toString = Object.prototype.toString;
  const map = {
    "[object Boolean]": "boolean",
    "[object Number]": "number",
    "[object String]": "string",
    "[object Function]": "function",
    "[object Array]": "array",
    "[object Date]": "date",
    "[object RegExp]": "regExp",
    "[object Undefined]": "undefined",
    "[object Null]": "null",
    "[object Object]": "object"
  };
  return map[toString.call(obj)];
}

/**
 * 深拷贝
 * @param {Object/Array} data 需要拷贝的数据
 */
function deepCopy(data, options) {
  const defObj = objTypeOf(data) === "array" ? [] : {};
  return deepmerge(defObj, data, options || {});
}

/**
 * 将目标对象中有的属性值与源对象中的属性值合并
 * @param {Object} target 目标对象
 * @param {Object} sources 源对象
 */
function objAssign(target, sources) {
  let targ = { ...target };
  for (let k in targ) {
    targ[k] = Object.prototype.hasOwnProperty.call(sources, k)
      ? sources[k]
      : targ[k];
  }
  return targ;
}

/**
 * 文件流下载
 * @param {Object} option 文件下载设置
 */
function download(option) {
  let defOpt = {
    type: "get",
    url: "",
    data: "",
    fileName: "",
    header: ""
  };
  let opt = objAssign(defOpt, option);

  return new Promise((resolve, reject) => {
    let xhr = new XMLHttpRequest();
    xhr.open(opt.type.toUpperCase(), opt.url, true);
    xhr.responseType = "blob";

    // header set
    if (opt.header && objTypeOf(opt.header) === "object") {
      for (let key in opt.header) {
        xhr.setRequestHeader(key, opt.header[key]);
      }
    }

    xhr.onload = function() {
      if (this.readyState === 4 && this.status === 200) {
        var blob = this.response;
        let pdfUrl = "";
        let uRl = window.URL || window.webkitURL;
        if (uRl && uRl.createObjectURL) {
          pdfUrl = uRl.createObjectURL(blob);
        } else {
          reject("浏览器不兼容！");
        }
        let a = document.createElement("a");
        a.download = opt.fileName;
        a.href = pdfUrl;
        document.body.appendChild(a);
        a.click();
        a.parentNode.removeChild(a);
        resolve();
      } else {
        reject(this);
      }
    };

    if (opt.type.toUpperCase() === "POST") {
      xhr.send(opt.data);
    } else {
      xhr.send();
    }
  });
}

/**
 * 构建图表btn
 * @param {Function} h createElement
 * @param {Array} actions 操作分类数组
 */
function tableAction(h, actions) {
  return actions.map(item => {
    let attr = {
      props: {
        type: item.type || "primary",
        size: "small",
        disabled: !!item.disabled
      },
      style: {
        marginRight: "5px"
      },
      on: {
        click: () => {
          item.action();
        }
      }
    };
    return h("Button", attr, item.name);
  });
}

/**
 * 获取随机code,默认获取16位
 * @param {Number} len 推荐8的倍数
 *
 */
function randomCode(len = 16) {
  if (len <= 0) return;
  let steps = Math.ceil(len / 8);
  let stepNums = [];
  for (let i = 0; i < steps; i++) {
    let ranNum = Math.random()
      .toString(32)
      .slice(-8);
    stepNums.push(ranNum);
  }

  return stepNums.join("");
}

/**
 * 序列化参数
 * @param {Object} params 参数对象
 */
function qsParams(params) {
  return Object.entries(params)
    .map(([key, val]) => `${key}=${val}`)
    .join("&");
}

/**
 *
 * @param {String} format 时间格式
 * @param {Date} date 需要格式化的时间对象
 */
function formatDate(format = "YYYY-MM-DD HH:mm:ss", date = new Date()) {
  if (objTypeOf(date) !== "date") return;
  const options = {
    "Y+": date.getFullYear(),
    "M+": date.getMonth() + 1,
    "D+": date.getDate(),
    "H+": date.getHours(),
    "m+": date.getMinutes(),
    "s+": date.getSeconds()
  };
  Object.entries(options).map(([key, val]) => {
    if (new RegExp("(" + key + ")").test(format)) {
      const zeros = key === "Y+" ? "0000" : "00";
      const value = (zeros + val).substr(("" + val).length);
      format = format.replace(RegExp.$1, value);
    }
  });
  return format;
}

/**
 * 获取本地日期，格式YYYY-M-D
 */
function getLocalDate() {
  return formatDate("YYYY-MM-DD");
}

/**
 * 清除html标签
 * @param {String} str html字符串
 */
function removeHtmlTag(str) {
  return str.replace(/<[^>]+>/g, "");
}

export {
  objTypeOf,
  deepCopy,
  objAssign,
  download,
  tableAction,
  randomCode,
  qsParams,
  formatDate,
  removeHtmlTag,
  getLocalDate
};
