import raf from 'rc-util/lib/raf'; // eslint-disable-next-line @typescript-eslint/no-explicit-any

export function isWindow(obj) {
  return obj !== null && obj !== undefined && obj === obj.window;
}
export function getScroll(target, top) {
  var _a;

  if (typeof window === 'undefined') {
    return 0;
  }

  var method = top ? 'scrollTop' : 'scrollLeft';
  var result = 0;

  if (isWindow(target)) {
    result = target[top ? 'pageYOffset' : 'pageXOffset'];
  } else if (target instanceof Document) {
    result = target.documentElement[method];
  } else if (target) {
    result = target[method];
  }

  if (target && !isWindow(target) && typeof result !== 'number') {
    result = (_a = (target.ownerDocument || target).documentElement) === null || _a === void 0 ? void 0 : _a[method];
  }

  return result;
}

function easeInOutCubic(t, b, c, d) {
  var cc = c - b;
  t /= d / 2;

  if (t < 1) {
    return cc / 2 * t * t * t + b;
  } // eslint-disable-next-line no-return-assign


  return cc / 2 * ((t -= 2) * t * t + 2) + b;
}

export function scrollTo(y, options) {
  if (options === void 0) {
    options = {};
  }

  var _a = options.getContainer,
      getContainer = _a === void 0 ? function () {
    return window;
  } : _a,
      callback = options.callback,
      _b = options.duration,
      duration = _b === void 0 ? 450 : _b;
  var container = getContainer();
  var scrollTop = getScroll(container, true);
  var startTime = Date.now();

  var frameFunc = function frameFunc() {
    var timestamp = Date.now();
    var time = timestamp - startTime;
    var nextScrollTop = easeInOutCubic(time > duration ? duration : time, scrollTop, y, duration);

    if (isWindow(container)) {
      container.scrollTo(window.pageXOffset, nextScrollTop);
    } else if (container instanceof HTMLDocument || container.constructor.name === 'HTMLDocument') {
      container.documentElement.scrollTop = nextScrollTop;
    } else {
      container.scrollTop = nextScrollTop;
    }

    if (time < duration) {
      raf(frameFunc);
    } else if (typeof callback === 'function') {
      callback();
    }
  };

  raf(frameFunc);
}

