'use strict';

function CategoryScroller(options) {
    this._positions = [];
    this._drag = options.drag;
    this._dragFixed = options.dragFixed;
    this._scrollStep = 80;

    this._onScroll = this._onScroll.bind(this);
    this._onMenuItemClick = this._onMenuItemClick.bind(this);
    this._onMenuLeftScrollBtnClick = this._onMenuLeftScrollBtnClick.bind(this);
    this._onMenuRightScrollBtnClick = this._onMenuRightScrollBtnClick.bind(this);
    this._onMenuFixedLeftScrollBtnClick = this._onMenuFixedLeftScrollBtnClick.bind(this);
    this._onMenuFixedRightScrollBtnClick = this._onMenuFixedRightScrollBtnClick.bind(this);
}

CategoryScroller.prototype.init = function() {
    this._initImages();
    this._calculatePositions();
    this._scrollToUri();    
    this._addListeners();
}

CategoryScroller.prototype._addListeners = function() {
    window.addEventListener('scroll', this._onScroll);

    const menuLinks = document.querySelectorAll(".catalog-menu__item");
    menuLinks.forEach((element) => {
        element.addEventListener('click', this._onMenuItemClick);
    });

    const menuFixedLinks = document.querySelectorAll(".catalog-menu-fixed__item");
    menuFixedLinks.forEach((element) => {
        element.addEventListener('click', this._onMenuItemClick);
    });

    // кнопки прокрутки влево/вправо для обычного меню
    const scrollMenuLeftBtn = document.querySelector('.catalog-menu__scroll-btn.-left');
    scrollMenuLeftBtn.addEventListener('click', this._onMenuLeftScrollBtnClick);
    const scrollMenuRightBtn = document.querySelector('.catalog-menu__scroll-btn.-right');
    scrollMenuRightBtn.addEventListener('click', this._onMenuRightScrollBtnClick);

    // кнопки прокрутки влево/вправо для фиксированного меню
    const scrollMenuFixedLeftBtn = document.querySelector('.catalog-menu-fixed__scroll-btn.-left');
    scrollMenuFixedLeftBtn.addEventListener('click', this._onMenuFixedLeftScrollBtnClick);
    const scrollMenuFixedRightBtn = document.querySelector('.catalog-menu-fixed__scroll-btn.-right');
    scrollMenuFixedRightBtn.addEventListener('click', this._onMenuFixedRightScrollBtnClick);
}

CategoryScroller.prototype._scrollToMenuItem = function(alias) {
    // находим позицию левой стороны активного пункта меню и сдвигаем до него
    /*const menuItem = document.querySelector('.catalog-menu__item[data-alias="' + alias + '"]');
    const menuItemOffset = -1 * menuItem.offsetLeft;
    drag.moveSliderTo(menuItemOffset);*/

    //setTimeout(function() {
        const menuItemFixed = document.querySelector('.catalog-menu-fixed__item[data-alias="' + alias + '"]');
        const menuItemFixedOffset = -1 * menuItemFixed.offsetLeft;
        //console.log(this._getCoords(menuItemFixed));
        //console.log(document.querySelector('.catalog-menu-fixed__item[data-alias="' + alias + '"]').getBoundingClientRect());
        dragFixed.moveSliderTo(menuItemFixedOffset);
    //}, 2000)
}

CategoryScroller.prototype._scrollToUri = function() {
    if (window.location.pathname && window.location.pathname !== '/') {
        const alias = window.location.pathname.replace(/\/+/g, '');

        if (location) {
            const categoryBox = document.querySelector('.catalog__category[data-alias="' + alias + '"]');

            if (categoryBox !== null) {
              this._scrollToCategory(alias);

              var contextScrollObj = this;

              // timout нужен для того, чтобы в фиксированном меню прокручивалось до пункта
              // без него, меню фиксированного еще не существует к моменту прокрутки
              setTimeout(function() {
                contextScrollObj._scrollToMenuItem(alias);
              }, 2000);
            }
        }
    }
}

CategoryScroller.prototype._onMenuItemClick = function(e) {
    const alias = e.target.getAttribute('data-alias');

    // костыль: необходимо пересчитывать реальное положение блоков категорий (съезжают почему-то)
    this._calculatePositions();

    this._scrollToCategory(alias);
    this._scrollToMenuItem(alias);
}

CategoryScroller.prototype._onMenuLeftScrollBtnClick= function(e) {  
    drag.moveSliderTo(drag.target + this._scrollStep);
}

CategoryScroller.prototype._onMenuRightScrollBtnClick= function(e) {  
    drag.moveSliderTo(drag.target - this._scrollStep);
}

CategoryScroller.prototype._onMenuFixedLeftScrollBtnClick= function(e) {  
  console.log('2222');
  dragFixed.moveSliderTo(dragFixed.target + this._scrollStep);
}

CategoryScroller.prototype._onMenuFixedRightScrollBtnClick= function(e) {  
  dragFixed.moveSliderTo(dragFixed.target - this._scrollStep);
}

CategoryScroller.prototype._scrollToCategory = function(alias) {
    var scrollTop = 0;

    this._positions.forEach(element => {
        if (element.alias === alias) {
            scrollTop = element.top;
        }
    });

    const coef = 120; // равен разнице между высокой шапкой и фиксированной

    var categoryBlock = document.querySelector('.catalog__category[data-alias="' + alias + '"]');
    var categoryBlockRect = this._getCoords(categoryBlock);

    console.log('Real top: ', alias, categoryBlockRect.top);
    console.log('scroll To', alias, scrollTop, scrollTop - coef, this._positions);

    this._setCategoryActive(alias);    
    history.pushState(null, null, "/" + alias);

    window.scrollTo({top: scrollTop - coef, behavior: "smooth"  });
}

CategoryScroller.prototype._onScroll = function() {
    let scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
    const offsetCoef = window.innerHeight / 1.5; // середина окна
    scrollTop = scrollTop + offsetCoef;

    this._positions.forEach(element => {
        if (element.top < scrollTop && element.bottom > scrollTop) {
            const categoryBox = document.querySelector('.catalog__category[data-alias="' + element.alias + '"]');

            // делаем активным новый блок
            if (!categoryBox.classList.contains('-active')) {
                this._setCategoryActive(element.alias);

                history.pushState(null, null, "/" + element.alias);
                this._scrollToMenuItem(element.alias);
            }
        }
    });
}

CategoryScroller.prototype._initImages = function() {
    const elements = document.querySelectorAll('.catalog-item__image-container.-lazy');
      
    elements.forEach(element => {
        const r = element.getAttribute('data-aspect');
        element.style.paddingBottom = r * 100 + '%';
    });
}

CategoryScroller.prototype._setCategoryActive = function(alias) {
    // Удаляем активный класс у категорий
    const activeCategories = document.querySelectorAll('.catalog__category');

    activeCategories.forEach((element) => {
        element.classList.remove('-active');
    });

    // Удаляем активный класс у категорий у меню
    const activeCategoryFixedMenus = document.querySelectorAll('.catalog-menu-fixed__item.-active');
    activeCategoryFixedMenus.forEach((element) => {
        element.classList.remove('-active');
    });

    // Удаляем активный класс у категорий у меню
    const activeCategoryMenus = document.querySelectorAll('.catalog-menu__item.-active');
    activeCategoryMenus.forEach((element) => {
        element.classList.remove('-active');
    });
    
    document.querySelector('.catalog__category[data-alias="' + alias + '"]').classList.add('-active');
    document.querySelector('.catalog-menu__item[data-alias="' + alias + '"]').classList.add('-active');
    document.querySelector('.catalog-menu-fixed__item[data-alias="' + alias + '"]').classList.add('-active');
}

CategoryScroller.prototype._calculatePositions = function() {
    this._positions = [];
    const categoryBlocks = document.querySelectorAll('.catalog__category');

    categoryBlocks.forEach(element => {
        const rect = this._getCoords(element);
        const data = {
            'alias' : element.getAttribute('data-alias'),
            'top' : rect.top,
            'bottom' : rect.bottom,
        };
        this._positions.push(data);
    });

    console.log('positions.init', this._positions);
}

CategoryScroller.prototype._getCoords = function(elem) {
  var box = elem.getBoundingClientRect();

  var body = document.body;
  var docEl = document.documentElement;

  var scrollTop = window.pageYOffset || docEl.scrollTop || body.scrollTop;
  var scrollLeft = window.pageXOffset || docEl.scrollLeft || body.scrollLeft;

  var clientTop = docEl.clientTop || body.clientTop || 0;
  var clientLeft = docEl.clientLeft || body.clientLeft || 0;

  var top  = box.top +  scrollTop - clientTop;
  var left = box.left + scrollLeft - clientLeft;

  var bottom = Math.round(top) + box.height;

  return { top: Math.round(top), left: Math.round(left), bottom: bottom };
}

/*function Drag(options) {

	this._event = {
		X: 0,
    Y: 0,
    cursorDown: false,
		initialX: 0, // The X position of the cursor on start.
		initialY: 0, // The Y position of cursor on start.
		originalEvent: null
  };

  this.initialized = false;
  this.curDown = false; // True if cursor is down.
  this.numListeners = 0;
  this.listeners = [];
  this.listener = options.listener || window;
  this.multiplier = options.multiplier || 1;

  // Detect interaction type.
  this.hasMouseEvent = 'onmousedown' in document;
  this.hasTouchEvent = 'ontouchstart' in document;
	this.hasTouchWinEvent = navigator.msMaxTouchPoints && navigator.msMaxTouchPoints > 1;
  this.hasPointerEvent = !!window.navigator.msPointerEnabled;
  this.isTouch = this.hasTouchEvent || this.hasTouchWinEvent || this.hasPointerEvent;
  this.msTouchAction = null;

  // Context binding.
  this._onDragStart = this._onDragStart.bind(this);
  this._onDrag = this._onDrag.bind(this);
  this._onDragEnd = this._onDragEnd.bind(this);
  this._onMouseLeave = this._onMouseLeave.bind(this);
  this._notify = this._notify.bind(this);

}

Drag.prototype.on = function(f) {
  if(!this.initialized) this._addListeners();
  this.listeners.push(f);
  this.numListeners = this.listeners.length;
};

Drag.prototype.off = function(f) {
  this.listeners.splice(f, 1);
  this.numListeners = this.listeners.length;
  if(this.numListeners <= 0) this._removeListeners();
};

Drag.prototype._notify = function(e) {
  var _e = (this.isTouch && e.targetTouches) ? e.targetTouches[0] : e;

  this._event.X = (_e.pageX - this._event.initialX) * this.multiplier;
  this._event.Y = (_e.pageY - this._event.initialY) * this.multiplier;
  this._event.originalEvent = e;
  this._event.cursorDown = this.curDown;

  this._event.initialX = _e.pageX;
  this._event.initialY = _e.pageY;

  for(var i = 0; i < this.numListeners; i++) {
    this.listeners[i](this._event);
  }
};

// Event Listeners.
Drag.prototype._onDrag = function(e) {
  if(this.curDown){
    e.preventDefault();
    this._notify(e);
  }
};

Drag.prototype._onDragStart = function(e) {
  var _e = (this.isTouch && e.targetTouches) ? e.targetTouches[0] : e;
  this._event.initialX = _e.pageX;
  this._event.initialY = _e.pageY;

  this.curDown = true;
  //this._notify(e);
};

Drag.prototype._onDragEnd = function(e) {
  this.curDown = false;
  //this._notify(e);
};

Drag.prototype._onMouseLeave = function(e) {
  this._onDragEnd(e);
};

Drag.prototype._addListeners = function() {

  if (this.hasMouseEvent) {
    this.listener.addEventListener('mouseleave', this._onMouseLeave);
    this.listener.addEventListener('mouseup', this._onDragEnd);
    this.listener.addEventListener('mousedown', this._onDragStart);
    this.listener.addEventListener('mousemove', this._onDrag);
  }

  if (this.hasTouchEvent) {
    this.listener.addEventListener('touchmove', this._onDrag);
    this.listener.addEventListener('touchend', this._onDragEnd);
    this.listener.addEventListener('touchstart', this._onDragStart);
  }

  if (this.hasPointerEvent && this.hasTouchWinEvent) {
    this.msTouchAction = this.listener.style.msTouchAction;
    this.listener.style.msTouchAction = "none";

    this.listener.addEventListener('MSPointerMove', this._onDrag);
    this.listener.addEventListener('MSPointerUp', this._onDragEnd);
    this.listener.addEventListener('MSPointerDown', this._onDragStart);
  }

};

Drag.prototype._removeListeners = function() {

  if (this.hasMouseEvent) {
    this.listener.removeEventListener('mouseleave', this._onMouseLeave);
    this.listener.removeEventListener('mouseup', this._onDragEnd);
    this.listener.removeEventListener('mousedown', this._onDragStart);
    this.listener.removeEventListener('mousemove', this._onDrag);
  }

  if (this.hasTouchEvent) {
    this.listener.removeEventListener('touchmove', this._onDrag);
    this.listener.removeEventListener('touchend', this._onDragEnd);
    this.listener.removeEventListener('touchstart', this._onDragStart);
  }

  if (this.hasPointerEvent && this.hasTouchWinEvent) {
    if (this.msTouchAction) this.listener.style.msTouchAction = this.msTouchAction;

    this.listener.removeEventListener('MSPointerMove', this._onDrag);
    this.listener.removeEventListener('MSPointerUp', this._onDragEnd);
    this.listener.removeEventListener('MSPointerDown', this._onDragStart);
  }

};

//module.exports = Drag;
*/