import $ from 'jquery';
import { GetYoDigits } from './foundation.core.utils';
import { Plugin } from './foundation.core.plugin';

/**
 * SmoothScroll module.
 * @module foundation.smoothScroll
 */
class SmoothScroll extends Plugin {
  /**
   * Creates a new instance of SmoothScroll.
   * @class
   * @name SmoothScroll
   * @fires SmoothScroll#init
   * @param {Object} element - jQuery object to add the trigger to.
   * @param {Object} options - Overrides to the default plugin settings.
   */
    _setup(element, options) {
        this.$element = element;
        this.options = $.extend({}, SmoothScroll.defaults, this.$element.data(), options);
        this.className = 'SmoothScroll'; // ie9 back compat

        this._init();
    }

    /**
     * Initialize the SmoothScroll plugin
     * @private
     */
    _init() {
        const id = this.$element[0].id || GetYoDigits(6, 'smooth-scroll');
        this.$element.attr({ id });

        this._events();
    }

    /**
     * Initializes events for SmoothScroll.
     * @private
     */
    _events() {
        this._linkClickListener = this._handleLinkClick.bind(this);
        this.$element.on('click.zf.smoothScroll', this._linkClickListener);
        this.$element.on('click.zf.smoothScroll', 'a[href^="#"]', this._linkClickListener);
    }

    /**
     * Handle the given event to smoothly scroll to the anchor pointed by the event target.
     * @param {*} e - event
     * @function
     * @private
     */
    _handleLinkClick(e) {
        // Follow the link if it does not point to an anchor.
        if (!$(e.currentTarget).is('a[href^="#"]')) return;

        const arrival = e.currentTarget.getAttribute('href');

        this._inTransition = true;

        SmoothScroll.scrollToLoc(arrival, this.options, () => {
            this._inTransition = false;
        });

        e.preventDefault();
    };

    /**
     * Function to scroll to a given location on the page.
     * @param {String} loc - A properly formatted jQuery id selector. Example: '#foo'
     * @param {Object} options - The options to use.
     * @param {Function} callback - The callback function.
     * @static
     * @function
     */
    static scrollToLoc(loc, options = SmoothScroll.defaults, callback) {
        const $loc = $(loc);

        // Do nothing if target does not exist to prevent errors
        if (!$loc.length) return false;

        var scrollPos = Math.round($loc.offset().top - options.threshold / 2 - options.offset);

        $('html, body').stop(true).animate(
            { scrollTop: scrollPos },
            options.animationDuration,
            options.animationEasing,
            () => {
                if (typeof callback === 'function'){
                    callback();
                }
            }
        );
    }

    /**
     * Destroys the SmoothScroll instance.
     * @function
     */
    _destroy() {
        this.$element.off('click.zf.smoothScroll', this._linkClickListener)
        this.$element.off('click.zf.smoothScroll', 'a[href^="#"]', this._linkClickListener);
    }
}

/**
 * Default settings for plugin.
 */
SmoothScroll.defaults = {
  /**
   * Amount of time, in ms, the animated scrolling should take between locations.
   * @option
   * @type {number}
   * @default 500
   */
  animationDuration: 500,
  /**
   * Animation style to use when scrolling between locations. Can be `'swing'` or `'linear'`.
   * @option
   * @type {string}
   * @default 'linear'
   * @see {@link https://api.jquery.com/animate|Jquery animate}
   */
  animationEasing: 'linear',
  /**
   * Number of pixels to use as a marker for location changes.
   * @option
   * @type {number}
   * @default 50
   */
  threshold: 50,
  /**
   * Number of pixels to offset the scroll of the page on item click if using a sticky nav bar.
   * @option
   * @type {number}
   * @default 0
   */
  offset: 0
}

export {SmoothScroll}
