/**
 * import dependencies
 */
import ElementHelpers from '../helpers/element-helpers';
import smoothscroll from 'smoothscroll-polyfill';


/**
 * Declare global vars
 */
const attributeBase = 'data-rs-tab-bar';

export class TabBar {

	constructor(element) {
		smoothscroll.polyfill();
		this.element = element;
		this.items = ElementHelpers.getElementsByAttributeWithinElement(this.element, this.attributes.item);
		this.setVariables();
		this.setFadeElements();
		this.addEventListeners();
		this.toggleFadeElements();
		this.scrollToActive();
	}

	/**
	 * Declare class constants
	 */
	get classes() {
		return {
			fadeElement: 'fade-element',
			fadeElementRight: 'fade-element--right',
			fadeElementLeft: 'fade-element--left',
			icon: 'icon',
			iconLeft: 'icon__left',
			iconRight: 'icon__right',
			hide: 'hide',
			active: 'active'

		}
	}

	/**
	 * Declare attribute constants
	 */
	get attributes() {
		return {
			item: `${attributeBase}-item`,
			iconLeft: `${attributeBase}-icon-left`,
			iconRight: `${attributeBase}-icon-right`,
			fadeElementLeft: `${attributeBase}-fade-element-left`,
			fadeElementRight: `${attributeBase}-fade-element-right`

		}
	}

	/**
	 * Declare HTML variables
	 * SVG chrevron templates
	 */
	setVariables() {
		this.chevronRight = `<svg viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
  				<path d="M7,2 C7.256,2 7.512,2.098 7.707,2.293 L14.707,9.293 C15.098,9.684 15.098,10.316 14.707,10.707 L7.707,17.707 C7.316,18.098 6.684,18.098 6.293,17.707 C5.902,17.316 5.902,16.684 6.293,16.293 L12.586,10 L6.293,3.707 C5.902,3.316 5.902,2.684 6.293,2.293 C6.488,2.098 6.744,2 7,2"/>
				</svg>`;
		this.chevronLeft = `<svg viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
  				<path d="M13,18 C12.744,18 12.488,17.902 12.293,17.707 L5.293,10.707 C4.902,10.316 4.902,9.684 5.293,9.293 L12.293,2.293 C12.684,1.902 13.316,1.902 13.707,2.293 C14.098,2.684 14.098,3.316 13.707,3.707 L7.414,10 L13.707,16.293 C14.098,16.684 14.098,17.316 13.707,17.707 C13.512,17.902 13.256,18 13,18"/>
				</svg>`;
		this.fadeLeft = `<div class="${this.classes.fadeElement} ${this.classes.fadeElementLeft} ${this.classes.hide}" ${this.attributes.fadeElementLeft}><div ${this.attributes.iconLeft} class="${this.classes.icon} ${this.classes.iconLeft}">${this.chevronLeft}</div></div>`;
		this.fadeRight = `<div class="${this.classes.fadeElement} ${this.classes.fadeElementRight} ${this.classes.hide}" ${this.attributes.fadeElementRight}><div ${this.attributes.iconRight} class="${this.classes.icon} ${this.classes.iconRight}">${this.chevronRight}</div></div>`;

	}

	/**
	 * insert fade elements at start and end of list items
	 */
	setFadeElements() {
		this.items.forEach((item, index, array) => {
			if (index === 1) {
				item.insertAdjacentHTML('beforebegin', this.fadeLeft);
			}
			if (index === array.length - 1) {
				item.insertAdjacentHTML('afterend', this.fadeRight);
			}
		});
	}

	/**
	 * add event listeners to all Tab-bar elements
	 */
	addEventListeners() {
		this.iconLeft = ElementHelpers.getElementByAttributeWithinElement(this.element, this.attributes.iconLeft);
		this.iconRight = ElementHelpers.getElementByAttributeWithinElement(this.element, this.attributes.iconRight);

		// scroll left on click
		this.iconLeft.addEventListener('click', () => {
			this.element.scrollBy({left: -(this.element.clientWidth / 2), behavior: 'smooth'})
		});
		// scroll right on click
		this.iconRight.addEventListener('click', () => {
			this.element.scrollBy({left: (this.element.clientWidth / 2), behavior: 'smooth'})
		});
		//reset position fadeElement/chevron on scroll
		this.element.addEventListener('scroll', () => {
			this.toggleFadeElements();
		});
		//reset position fadeElement/chevron on resize
		window.addEventListener('resize', () => {
			this.toggleFadeElements();
			this.scrollToActive();
		});
		//loop items and add click event to call setActiveClass function
		this.items.forEach(item => {
			item.addEventListener('click', (event) => {
				event.preventDefault;
				this.setActiveClass(event);
			});
		});
	}

	/**
	 * Set or remove active state on list item
	 */
	setActiveClass(event) {
		this.items.forEach(item => {
			item.classList.remove(this.classes.active);
		});
		event.currentTarget.classList.add(this.classes.active);
		this.scrollToActive();
	}

	/**
	 * on init and resize, scroll to active item
	 */
	scrollToActive() {
		this.activeElement = ElementHelpers.getElementByClassWithinElement(this.element, this.classes.active);
		const rectTabBar = this.element.getBoundingClientRect();
		const rectActiveTab = this.activeElement.getBoundingClientRect();
		const viewportWidth = window.innerWidth;
		const inScreenSize = viewportWidth - (rectTabBar.left * 2);
		if ((rectActiveTab.left + (this.activeElement.clientWidth) > inScreenSize)) {
			this.element.scrollBy({behavior: 'smooth', left: (rectActiveTab.left - (rectTabBar.left * 2))});
		} else if (rectActiveTab.left < (this.activeElement.clientWidth + 50)) {
			this.element.scrollBy({behavior: 'smooth', left: (rectActiveTab.left - (inScreenSize / 2))});
		}
	}


	/**
	 * Hide or show the Fade elements and position them
	 */
	toggleFadeElements() {
		this.fadeElementRight = ElementHelpers.getElementByAttributeWithinElement(this.element, this.attributes.fadeElementRight);
		this.fadeElementLeft = ElementHelpers.getElementByAttributeWithinElement(this.element, this.attributes.fadeElementLeft);
		//calculate maximum scroll left
		let maxScrollLeft = this.element.scrollWidth - this.element.clientWidth;
		//calculate the position for the chevrons
		this.screenCenter = window.innerWidth / 2;
		this.tabBarWidth = this.element.clientWidth;
		this.positionLeft = this.screenCenter - (this.tabBarWidth / 2);
		this.positionRight = this.screenCenter + (this.tabBarWidth / 2);
		// hide/show fade element right
		if (this.element.scrollLeft > maxScrollLeft - 20) {
			this.fadeElementRight.classList.add(this.classes.hide);
		} else {
			this.fadeElementRight.classList.remove(this.classes.hide);
			// minus 25px for the right-fadeElement width
			this.fadeElementRight.style.left = `${this.positionRight - 25}px`;
		}
		// hide/show fade element left
		if (this.element.scrollLeft > 10) {
			this.fadeElementLeft.classList.remove(this.classes.hide);
			// minus 25px for the left-fadeElement width
			this.fadeElementLeft.style.left = `${this.positionLeft - 25}px`;
		} else {
			this.fadeElementLeft.classList.add(this.classes.hide);
		}
	}

	/**
	 * Get selector
	 */
	static getSelector() {
		return '[' + attributeBase + ']';
	}
}
