/**
 * card.js
 * show and hide backside information
 *
 */

import ElementHelpers from '../helpers/element-helpers';

/**
 * Declare constants
 */
const attributeBase = 'data-rs-card';


export class Card {

	constructor(element) {
		this.element = element;
		this.initVariables();
		this.addEventHandlers();
	}

	/**
	 * Declare attribute constants
	 */
	get attributes() {
		return {
			showBackSideCard: `${attributeBase}-show-backside`,
			hideBackSideCard: `${attributeBase}-hide-backside`,
			selectAllCards: `li[${attributeBase}]`
		}
	}

	/**
	 * Declare classes
	 */
	get classes() {
		return {
			backsideActive: 'cards__item--backside-active',
			animate: 'cards__item--animate'
		}
	}

	/**
	 * Initialise variables
	 */
	initVariables() {
		this.showBackSideCard = ElementHelpers.getElementByAttributeWithinElement(this.element, this.attributes.showBackSideCard);
		this.hideBackSideCard = ElementHelpers.getElementByAttributeWithinElement(this.element, this.attributes.hideBackSideCard);
		this.listParent = this.element.closest('ul');
		this.selectAllCards = this.listParent.querySelectorAll(this.attributes.selectAllCards);
	}

	/**
	 * Add event handlers
	 */
	addEventHandlers() {
		this.showBackSideCard && this.showBackSideCard.addEventListener('click', () => {
			this.setCardHeights(true);
		});
		this.hideBackSideCard && this.hideBackSideCard.addEventListener('click', () => {
			this.setCardHeights();
		});
		window.addEventListener('resize', () => {
			this.resizeCards();
		});
	}

	/**
	 * Check if slick slider is active and parent DIV exists
	 * @param element - element containing the card
	 */
	slickSliderActive(element) {
		return element.hasAttribute('data-rs-carousel-card') && element.parentElement.tagName === 'DIV';
	}

	removeAnimationAndHeight() {
		this.element.classList.remove(this.classes.animate);
		this.element.style.removeProperty('height');
	}

	/**
	 * set fixed heights for the backside-card to keep all card-heights  in sync
	 * @param show - boolean
	 */
	setCardHeights(show) {
		if (show) {
			const rect = this.element.getBoundingClientRect();
			this.selectAllCards.forEach(card => {
				//overwrite 'height:100%' set for slick-slider, otherwise different heights appear when backside is shown
				this.slickSliderActive(card) ? card.parentElement.style.height = `${rect.height}px` : '';
				if (card !== this.element && card.classList.contains(this.classes.backsideActive)) {
					card.classList.remove(this.classes.backsideActive);
					card.classList.add(this.classes.animate);
					setTimeout(() => card.classList.remove(this.classes.animate), 100);
				}
			});
			this.element.style.height = `${rect.height}px`;
			this.element.classList.add(this.classes.backsideActive);
		} else {
			this.selectAllCards.forEach(card => {
				this.slickSliderActive(card) ? card.parentElement.style.removeProperty('height') : '';
			});
			this.element.classList.remove(this.classes.backsideActive);
			this.element.classList.add(this.classes.animate);
			setTimeout(this.removeAnimationAndHeight.bind(this), 100);
		}
	}

	resizeCards() {
		this.selectAllCards.forEach(card => {
			this.slickSliderActive(card) ? card.parentElement.style.removeProperty('height') : '';
		});
		this.element.classList.remove(this.classes.backsideActive);
	}

	/**
	 * Get selector
	 */
	static getSelector() {
		return `[${attributeBase}]`;
	}
}
