/**
 * 防抖函数，目标函数在一段时间内未调用才能再次调用
 * @param {Function} func 目标函数
 * @param {number} wait 防抖时间
 * @param {boolean} immediate 是否立即调用，默认：true
 * @param {boolean} lastcall 结束后是否需要调用，默认：true
 * @param {boolean} leakcall 一定时间内也能调用，默认：false
 * @returns {Function}
 *
 * const logNum = debounce(() => console.log(1), 1000);
 * logNum();                         // => 1
 * logNum();                         // => 无打印
 * setTimeout(() => logNum(), 500);  // => 无打印
 * setTimeout(() => logNum(), 2000); // => 1
 */
function debounce(func, wait, immediate, lastcall, leakcall) {
  if (lastcall !== false) lastcall = true;
  if (immediate !== false) immediate = true;
  var previous = 0;
  var timer = null;
  return function () {
    var context = this;
    var args = arguments;
    var now = Date.now();

    var timeoutToCall = function timeoutToCall() {
      if (!leakcall) {
        clearTimeout(timer);
        timer = null;
      }

      if (!timer) {
        timer = setTimeout(function () {
          timer = null;
          func.apply(context, args);
        }, wait);
      }
    };

    if (now - previous > wait) {
      previous = now;

      if (immediate) {
        func.apply(context, args);
      } else if (lastcall) {
        timeoutToCall();
      }
    } else {
      previous = now;
      if (lastcall) timeoutToCall();
    }
  };
}

export default debounce;
