Source: components/filter/filter-tree/filter-option-element/filter-apply-button.js

import jQ from 'jquery';

import BaseComponent from "../../../base-component";
import Labels from "../../../../helpers/labels";
import Class from "../../../../helpers/class";
import FilterOptionEnum from '../../../../enum/filter-option-enum';
import FilterTreeEnum from '../../../../enum/filter-tree-enum';
import Settings from '../../../../helpers/settings';
import FilterApi from '../../../../api/filter-api';
import Globals from "../../../../helpers/globals";

/**
 * Apply button for filter tree
 * Performs API request on click
 * @extends BaseComponent
 */
class FilterApplyButton extends BaseComponent {
	/**
	 * Creates new FilterAppleButton
	 * @param {FilterTreeEnum} filterTreeType - 'vertical' or 'horizontal'
	 * @param {ApplyType} applyType - clear type 'apply-option-values', 'apply-all'
	 */
	constructor(filterTreeType, applyType) {
		super();
		this.filterTreeType = filterTreeType ? filterTreeType : FilterTreeEnum.FilterTreeType.HORIZONTAL;
		this.applyType = applyType ? applyType : FilterApplyButton.ApplyType.APPLY_OPTION_VALUES;
	}

	init() {
		this.label = (this.filterTreeType == FilterTreeEnum.FilterTreeType.HORIZONTAL)
		&& Settings.getSettingValue('general.requestInstantly') ?
			Labels.close : Labels.apply;
	}

	/**
	 * Get the apply button types enum
	 */
	static get ApplyType() {
		return {
			APPLY_OPTION_VALUES: 'apply-option-values',
			APPLY_ALL: 'apply-all'
		}
	}

	getTemplate() {
		if (this.applyType == FilterApplyButton.ApplyType.APPLY_ALL) {
			return `
				<button class="{{class.button}} {{class.applyAllButton}}">{{label.applyAll}}</button>
			`;
		} else {
			return `
				<button class="{{class.button}} {{class.applyButton}}">{{label.apply}}</button>
			`;
		}
	}

	compileTemplate() {
		return this.getTemplate()
			.replace(/{{label.apply}}/g, this.label)
			.replace(/{{label.applyAll}}/g, Labels.applyAll)
			.replace(/{{class.button}}/g, Class.button)
			.replace(/{{class.applyButton}}/g, Class.applyButton)
			.replace(/{{class.applyAllButton}}/g, Class.applyAllButton);
	}

	isRender() {
		var isCollection = this.parent.filterType == FilterOptionEnum.FilterType.COLLECTION;
		//var isSingleMultiLevelTag = this.parent.displayType == FilterOptionEnum.DisplayType.MULTI_LEVEL_TAG && this.parent.selectType == FilterOptionEnum.SelectType.SINGLE;
		return !isCollection;
	}

	render() {
		if (!this.$element) {
			this.$element = jQ(this.compileTemplate());
		}
	}

	isBindEvents() { return !this.isBoundEvent; }

	bindEvents() {
		if (this.$element) {
			this.$element.on('click', this.onClick.bind(this));
		}		
	}

	/**
	 * On click the apply button.
	 * Check the filter option to see which filter option item is selected
	 * Set params for filter API and call API.
	 */
	onClick(event) {
		if (event) {
			event.preventDefault();
		}

		if (this.applyType == FilterApplyButton.ApplyType.APPLY_ALL) {
			this.onApplyAll();
		} else {
			// Close the tab on horizontal
			// Parent is FilterOption
			if (this.filterTreeType == FilterTreeEnum.FilterTreeType.HORIZONTAL) {
				if (!Settings.getSettingValue('general.keepTabOpenState') && this.parent.collapse) {
					this.parent.collapse.onToggleHorizontal();
				}
				if (Settings.getSettingValue('general.requestInstantly')) {
					return;
				}
			}
			this.onApplyOptionValues();
		}
	}

	onApplyOptionValues() {
		// Perform API request
		var selectedFilterItems = [];
		var filterOptionId = this.parent.filterOptionId;
		var filterItems = this.parent.filterItems;
		if (this.parent.displayType == FilterOptionEnum.DisplayType.MULTI_LEVEL_TAG) {
			filterItems = this.parent.allNestedFilterItems;
		}

		filterItems.forEach((filterItem) => {
			if (filterItem.isSelected) {
				selectedFilterItems.push(filterItem.value);
			}
		})

		FilterApi.setParam(filterOptionId, selectedFilterItems);
		FilterApi.setParam(filterOptionId + '_and_condition', this.parent.useAndCondition && selectedFilterItems.length > 0 ? true : null);
		FilterApi.setParam(filterOptionId + '_show_exact_rating', this.parent.showExactRating && selectedFilterItems.length > 0 ? true : null);
		FilterApi.setParam(filterOptionId + '_exclude_from_value', this.parent.excludePriceFromValue && selectedFilterItems.length > 0 ? true : null);
		FilterApi.setParam('page', 1);

		var eventType = 'filter';
		var eventInfo = {
			filterOptionId: filterOptionId,
			filterOptionValue: selectedFilterItems
		}

		FilterApi.applyFilter(eventType, eventInfo);
	}

	onApplyAll() {
		// Close the tab on horizontal
		// Parent is FilterTree
		if (this.filterTreeType == FilterTreeEnum.FilterTreeType.HORIZONTAL) {
			if (this.parent.filterOptions) {
				this.parent.filterOptions.forEach(filterOption => {
					if (filterOption.collapse && !filterOption.collapse.isCollapsed) {
						filterOption.collapse.onToggleHorizontal();
					}
				})
			}
			if (Settings.getSettingValue('general.requestInstantly')) {
				return;
			}
		}

		// Perform API request
		if (this.parent.filterOptions) {
			this.parent.filterOptions.forEach(filterOption => {
				var selectedFilterItems = [];
				var filterOptionId = filterOption.filterOptionId;
				var filterItems = filterOption.displayType == FilterOptionEnum.DisplayType.MULTI_LEVEL_TAG ? filterOption.allNestedFilterItems : filterOption.filterItems;

				filterItems.forEach((filterItem) => {
					if (filterItem.isSelected) {
						selectedFilterItems.push(filterItem.value);
					}
				})
				FilterApi.setParam(filterOptionId, selectedFilterItems);
				FilterApi.setParam(filterOptionId + '_and_condition', filterOption.useAndCondition && selectedFilterItems.length > 0 ? true : null);
				FilterApi.setParam(filterOptionId + '_show_exact_rating', filterOption.showExactRating && selectedFilterItems.length > 0 ? true : null);
				FilterApi.setParam(filterOptionId + '_exclude_from_value', filterOption.excludePriceFromValue && selectedFilterItems.length > 0 ? true : null);
			})
		}
		FilterApi.setParam('page', 1);

		var eventType = 'filter';
		FilterApi.applyFilter(eventType);
	}
}

export default FilterApplyButton;