import Mixin from "@ember/object/mixin";
import discourseDebounce from "discourse-common/lib/debounce";

// Small buffer so that very tiny scrolls don't trigger mobile header switch
const MOBILE_SCROLL_TOLERANCE = 5;

export default Mixin.create({
  _lastScroll: null,
  _bottomHit: 0,

  calculateDirection(offset) {
    // Difference between this scroll and the one before it.
    const delta = Math.floor(offset - this._lastScroll);

    // This is a tiny scroll, so we ignore it.
    if (delta <= MOBILE_SCROLL_TOLERANCE && delta >= -MOBILE_SCROLL_TOLERANCE) {
      return;
    }

    // don't calculate when resetting offset (i.e. going to /latest or to next topic in suggested list)
    if (offset === 0) {
      return;
    }

    const prevDirection = this.mobileScrollDirection;
    const currDirection = delta > 0 ? "down" : null;

    const distanceToBottom = Math.floor(
      $("body").height() - offset - $(window).height()
    );

    // Handle Safari top overscroll first
    if (offset < 0) {
      this.set("mobileScrollDirection", null);
    } else if (currDirection !== prevDirection && distanceToBottom > 0) {
      this.set("mobileScrollDirection", currDirection);
    }

    // We store this to compare against it the next time the user scrolls
    this._lastScroll = Math.floor(offset);

    // Not at the bottom yet
    if (distanceToBottom > 0) {
      this._bottomHit = 0;
      return;
    }

    // If the user reaches the very bottom of the topic, we only want to reset
    // this scroll direction after a second scrolldown. This is a nicer event
    // similar to what Safari and Chrome do.
    discourseDebounce(
      this,
      function () {
        this._bottomHit = 1;
      },
      1000
    );

    if (this._bottomHit === 1) {
      this.set("mobileScrollDirection", null);
    }
  },
});
