export function loadJs (url = '') {
  if (!url) return
  if (!loadJs.cache) loadJs.cache = {}
  if (loadJs.cache[url]) return Promise.resolve()
  return new Promise((resolve, reject) => {
    _loadjs(
      url,
      () => {
        loadJs.cache[url] = 'cached'
        resolve()
      },
      () => {
        console.error(`${url} 加载失败`)
        reject(new Error(`${url} 加载失败`))
      }
    )
  })

  function _loadjs (url, fn, fail) {
    var script = document.createElement('script')
    script.src = url
    script.async = true
    script.onload = fn
    script.onerror = fail
    ;(document.body || document.head).appendChild(script)
  }
}

var FINGER_PRINT_URL = 'https://cdn.staticfile.org/fingerprintjs2/1.8.0/fingerprint2.min.js'
var STORAGE_KEY = 'YMMFP'

export function getFingerPrint () {
  if (!getFingerPrint.promise) {
    getFingerPrint.promise = new Promise((resolve) => {
      var fingerPrint = localStorage.getItem(STORAGE_KEY)
      if (fingerPrint) return resolve(fingerPrint)
      loadJs(FINGER_PRINT_URL).then(() => {
        if (!window.Fingerprint2) resolve('unknown')
        window.Fingerprint2 && new window.Fingerprint2().get((res) => {
          localStorage.setItem(STORAGE_KEY, res)
          resolve(res)
        })
      })
    })
  }
  return getFingerPrint.promise
}


/**
 * 将秒数转为时间格式
 *
 * @format
 * @param data {number} 时间戳
 * @param format {string} 时间格式[完整格式：yyyy-MM-dd HH:mm:ss，默认yyyy-MM-dd]
 * @param implementText {string} 缺省文字
 */
export function timeFormat(data, format, implementText) {
  if (data === null || data === '' || data === undefined) {
    return implementText || '';
  }
  format = format || 'yyyy-MM-dd';
  let week = [
    '星期日',
    '星期一',
    '星期二',
    '星期三',
    '星期四',
    '星期五',
    '星期六'
  ];
  let date = new Date(data);
  let o = {
    'M+': date.getMonth() + 1,
    'd+': date.getDate(),
    'h+': date.getHours() % 12,
    'H+': date.getHours(),
    'm+': date.getMinutes(),
    's+': date.getSeconds(),
    'q+': Math.floor((date.getMonth() + 3) / 3),
    'S+': date.getMilliseconds(),
    'W+': week[date.getDay()]
  };
  if (/(y+)/.test(format))
    format = format.replace(
      RegExp.$1,
      (date.getFullYear() + '').substr(4 - RegExp.$1.length)
    );
  for (let k in o)
    if (new RegExp('(' + k + ')').test(format))
      format = format.replace(
        RegExp.$1,
        RegExp.$1.length === 1 ? o[k] : ('00' + o[k]).substr(('' + o[k]).length)
      );
  return format;
}
 
/**
 * 将字符串时间转换为时间戳
 * @param {string} date
 */
export function getDateTime(date) {
  let timestamp = '';
  if (date) {
    date = date.substring(0, 19);
    date = date.replace(/-/g, '/'); //必须把日期'-'转为'/'
    timestamp = new Date(date).getTime();
  }
  return timestamp;
}
/**
 * 获取年-月-日
 * @data {Any} 时间戳
 */
export function getDates(data) {
  let timeObj = {};
  data = new Date(data);
  let y = data.getFullYear();
  let m =
    data.getMonth() + 1 < 10
      ? '0' + (data.getMonth() + 1)
      : data.getMonth() + 1;
  let d = data.getDate() < 10 ? '0' + data.getDate() : data.getDate();
  let w = data.getDay();
  switch (w) {
    case 1:
      w = '星期一';
      break;
    case 2:
      w = '星期二';
      break;
    case 3:
      w = '星期三';
      break;
    case 4:
      w = '星期四';
      break;
    case 5:
      w = '星期五';
      break;
    case 6:
      w = '星期六';
      break;
    case 7:
      w = '星期日';
      break;
  }
  let h = data.getHours() < 10 ? '0' + data.getHours() : data.getHours();
  let mi = data.getMinutes() < 10 ? '0' + data.getMinutes() : data.getMinutes();
  let s = data.getSeconds() < 10 ? '0' + data.getSeconds() : data.getSeconds();
  timeObj = {
    year: y + '',
    month: m + '',
    day: d + '',
    week: w + '',
    hour: h + '',
    minute: mi + '',
    second: s + ''
  };
  return timeObj;
}
/**
 * 异常处理
 * @param {boolean} condition
 * @param {string} msg
 */
export function assert(condition, msg) {
  if (!condition) throw new Error(`[Apior] ${msg}`);
}
 
/**
 * URL编码;
 * @param {参数} param
 */
export function toParams(param) {
  let result = '';
  for (let name in param) {
    if (typeof param[name] != 'function') {
      if (param[name] === null) {
        result += '&' + name + '=';
      } else {
        result += '&' + name + '=' + encodeURI(param[name]);
      }
    }
  }
  return result.substring(1);
}
/**
 * 防抖函数
 * @param fn 高频函数
 * @param wait 等待时间
 * @returns {Function}
 */
export function debounce(fn, wait) {
  let context = this,
    args = arguments,
    timer = null;
  return function() {
    context = this;
    args = arguments;
    clearTimeout(timer);
    timer = setTimeout(function() {
      fn.apply(context, args);
    }, wait || 250);
  };
}

/**
 * 节流函数, 用于将多次执行变为每隔一段时间执行
 * @param fn 事件触发的操作
 * @param delay 间隔多少毫秒需要触发一次事件
 */
export function throttle(fn, delay) {
  let timer = null;
  return function () {
    let context = this;
    let args = arguments;
    if (!timer) {
      timer = setTimeout(function () {
        fn.apply(context, args);
        clearTimeout(timer);
      }, delay);
    }
  };
}
 
/**
 * 对象深拷贝
 * @param  obj 对象
 * @description 如果此方法不适用可以使用loadsh的cloneDeep
 */
export function deepCopy(obj) {
  if(obj === null) return null
  if(obj === undefined) return undefined
  if(obj.constructor === Date) return new Date(+obj) 
  if(obj.constructor === RegExp) return new RegExp(obj) 
  let newObj = obj.constructor === Array ? [] : {};
  if (
    Object.prototype.toString.call(obj) !== '[object Object]' &&
    Object.prototype.toString.call(obj) !== '[object Array]'
  ) {
    return obj;
  }else {
    for (let i in obj) {
      newObj[i] = typeof obj[i] === 'object' ? this.deepCopy(obj[i]) : obj[i];
    }
  }
  return newObj;
}


/**
 * 取出对象中制定属性返回新对象
 * @obj {Object} 数据对象的KEY
 * @keys {Array} 数据对象的KEY
 */
export function certainProperty(obj, keys) {
  return keys.reduce((result, key) => {
    if (obj.hasOwnProperty(key)) {
      result[key] = obj[key];
    }
    return result;
  }, {});
}

export default {
  loadJs,
  getFingerPrint,
  timeFormat,
  getDateTime,
  getDates,
  assert,
  toParams,
  debounce,
  throttle,
  deepCopy,
  certainProperty
}