var FacetSearch = function(successCallback) {
	function performFacetSearch(searchForm) {
		if (history.pushState) {
			performAjaxFacetSearch(searchForm);
		} else {
			searchForm.submit();
		}
	}

	$('[data-toggle="collapse"]').on('click', function(e) {
		e.preventDefault();
	});

	function decodeUrl(url) {
		url = decodeURIComponent(url);
		// Escape special characters to make things work with IE11
		url.replace(/[ ]/g, '%20')
			.replace(/[&]/g, '%26')
			.replace(/[€]/g, '%E2%82%AC')
			.replace(/[–]/g, '%E2%80%93')
			.replace(/[ä]/g, '%C3%A4')
			.replace(/[ö]/g, '%C3%B6');

		return url;
	}

	function performFacetSearchNavigation(newUrl) {
		newUrl = decodeUrl(newUrl);

		if (history.pushState) {
			performAjaxFacetSearchWithURL(newUrl, true);
		} else {
			window.location.href = newUrl;
		}
	}

	// help functions for filtering arrays for prioritize function
	function facetManufacturer(word) {
		return word.indexOf('manufacturer') > -1 || word.indexOf('accessoryManufacturer') > -1;
	}
	function facetPrice(word) {
		return word.indexOf('price') > -1;
	}
	function facetOthers(word) {
		return (
			word.indexOf('manufacturer') === -1 &&
			word.indexOf('price') === -1 &&
			word.indexOf('accessoryManufacturer') === -1
		);
	}

	function sortFacetSearchQuery(queryString) {
		// match first :sorting-option e.g. :relevance
		var sortingOption = queryString.match(/^:[^:]+/);
		// remove sorting-option from query
		var facetsWithoutSortingQuery = queryString.replace(/^:[^:]+/, '');
		// form query of facet values which includes string facetName:value
		facetValueArray = facetsWithoutSortingQuery.match(/[^:]+(\:[^:]+)?/g);

		// if there are actual facets, sort and prioritize the most important ones (manufacturer first, then price, then rest of facets, everything sorted alphabetically)
		if (facetValueArray) {
			manufacturerFacetsArray = facetValueArray.filter(facetManufacturer).sort();
			priceFacetsArray = facetValueArray.filter(facetPrice).sort();
			otherFacetsArray = facetValueArray.filter(facetOthers).sort();

			// combine all facets into one array
			var sortedOptionsArray = sortingOption.concat(
				manufacturerFacetsArray,
				priceFacetsArray,
				otherFacetsArray
			);

			// rejoin all sorted facet queries into one string and combine them with : before sending query to BE
			sortedQueryString = sortedOptionsArray.join(':');
			return sortedQueryString;
		} else {
			return queryString;
		}
	}

	function performAjaxFacetSearch(searchForm) {
		var searchUrl = window.location.href;
		searchUrl = Utils.updateQueryString('page', null, searchUrl);

		var searchQuery = searchForm.find('input[name*=\'q\']').val();

		// send searchQuery string for sorting function to always have facets in same order in url
		searchQuery = sortFacetSearchQuery(searchQuery);
		if (searchQuery) {
			var encodeSearchQuery = $.param({
				q: searchQuery
			}).substring(2);
			searchUrl = Utils.updateQueryString('q', encodeSearchQuery, searchUrl);
		}

		var searchSorting = searchForm.find('[name=\'sortValue\']').val();
		if (searchSorting) {
			var encodeSearchSorting = $.param({
				sort: searchSorting
			}).substring(5);
			searchUrl = Utils.updateQueryString('sort', encodeSearchSorting, searchUrl);
		}

		performAjaxFacetSearchWithURL(searchUrl, true);
	}

	function performAjaxFacetSearchWithURL(searchUrl, addStateToHistory) {
		searchUrl = decodeUrl(searchUrl);
		var searchUrlAjax = Utils.updateQueryString('loadAjaxData', 'true', searchUrl);
		$('#loading').trigger('sh.dna.loading.show');
		$.ajax({
			url: searchUrlAjax,
			dataType: 'html',
			cache: false,
			success: function(data) {
				var resultPage = $(data);
				if (successCallback) {
					successCallback(resultPage, addStateToHistory);
				}

				var resultTitle = resultPage
					.find('.page-title')
					.text()
					.trim();
				if (addStateToHistory) {
					history.pushState(null, resultTitle, searchUrl);
				}
			},
			error: function(xht, textStatus, ex) {
				$('#loading').trigger('sh.dna.loading.hide');
				window.location.href = window.location.href;
			}
		});
	}

	return {
		performFacetSearch: performFacetSearch,
		performFacetSearchNavigation: performFacetSearchNavigation,
		performAjaxFacetSearchWithURL: performAjaxFacetSearchWithURL
	};
};

var refreshLayout = function() {
	$('[data-mh]').matchHeight();
	$('.product-info').matchHeight();
	$('.product.prod_grid').matchHeight();
	$('html, body').animate(
		{
			scrollTop: ($('.productlisting').offset() || {}).top - 100
		},
		500
	);
	// trigger header & title updates
	$(document).trigger('updateProductListHeader');
};

var bindAngular = function() {
	var productListContainer = $('.prod-list-container, .prod_refine-sort');
	angular
		.element(productListContainer)
		.scope()
		.reinitAngularEvents(productListContainer);
};

var FacetContext = {};
(function(FacetContext, $) {
	var collapsedClass = 'collapsed';
	var expandClass = 'in';

	function collapse(element) {
		element.addClass(collapsedClass);
		$(element.attr('data-target')).removeClass(expandClass);
	}

	function expand(element) {
		element.removeClass(collapsedClass);
		$(element.attr('data-target')).addClass(expandClass);
	}

	FacetContext.storeState = function() {
		var state = {categories: []};
		var categoriesState = state.categories;
		var categories = $('.facetbox .category');
		categories.each(function(index, element) {
			var $elem = $(element);
			categoriesState.push({
				// use data-target as identifier as id contains spaces
				dataTarget: $elem.attr('data-target'),
				collapsed: $elem.hasClass(collapsedClass)
			});
		});

		return state;
	};

	FacetContext.restoreState = function(state) {
		var categoriesState = state.categories;
		$.each(categoriesState, function(i, categoryState) {
			// use data-target as identifier as id contains spaces
			var $category = $('[data-target=\' + categoryState.dataTarget + \']');
			var collapsed = $category.hasClass(collapsedClass);
			if (categoryState.collapsed && !collapsed) {
				collapse($category);
			} else if (!categoryState.collapsed && collapsed) {
				expand($category);
			}
		});
	};
})(FacetContext, jQuery);

var updatePage = function(resultPage) {
	var state = FacetContext.storeState();

	$('.nav_column').replaceWith(resultPage.find('.nav_column'));
	$('.prod_refine_top').replaceWith(resultPage.find('.prod_refine_top'));
	$('.prod_refine_bottom').replaceWith(resultPage.find('.prod_refine_bottom'));
	var productListContainer = $('.prod-list-container');
	productListContainer.replaceWith(resultPage.find('.prod-list-container'));

	FacetContext.restoreState(state);

	$('[data-toggle="collapse"]').on('click', function(e) {
		e.preventDefault();
	});
	// reinit sorting
	ACC.paginationsort.bindAll();
	refreshLayout();
	truncateProductSummary();
	bindAngular();
};

ACC.facetsearch = new FacetSearch(updatePage);
