'use strict';

define('tagFilter', ['hooks', 'alerts', 'bootstrap'], function (hooks, alerts, bootstrap) {
	const tagFilter = {};

	tagFilter.init = function (el, options) {
		if (!el || !el.length) {
			return;
		}
		options = options || {};
		options.template = 'partials/tags/filter-dropdown-left';

		hooks.fire('action:tag.filter.options', { el: el, options: options });

		const searchEl = el.find('[component="tag/filter/search"]');

		options.selectedTags = options.selectedTags || ajaxify.data.selectedTags || [];

		let tagList = null;

		let selectedTags = [];
		let initialTags = [];
		if (Array.isArray(options.selectedTags)) {
			selectedTags = options.selectedTags.map(String);
		} else if (Array.isArray(ajaxify.data.selectedTags)) {
			selectedTags = ajaxify.data.selectedTags.map(String);
		}
		initialTags = selectedTags.slice();

		const toggleSearchVisibilty = searchEl.parent('[component="tag/filter"]').length &&
			app.user.privileges['search:tags'];

		el.on('show.bs.dropdown', function () {
			if (toggleSearchVisibilty) {
				el.find('.dropdown-toggle').css({ visibility: 'hidden' });
				searchEl.removeClass('hidden');
				searchEl.css({
					'z-index': el.find('.dropdown-toggle').css('z-index') + 1,
				});
			}

			function doSearch() {
				const val = searchEl.find('input').val();
				if (val.length > 1 || (!val && !tagList)) {
					loadList(val, function (tags) {
						tagList = tagList || tags;
						renderList(tags);
					});
				} else if (!val && tagList) {
					renderList(tagList);
				}
			}

			searchEl.on('click', function (ev) {
				ev.preventDefault();
				ev.stopPropagation();
			});
			searchEl.find('input').val('').on('keyup', utils.debounce(doSearch, 300));
			doSearch();
		});

		el.on('shown.bs.dropdown', function () {
			if (!['xs', 'sm'].includes(utils.findBootstrapEnvironment())) {
				searchEl.find('input').focus();
			}
		});

		el.on('hidden.bs.dropdown', function () {
			if (toggleSearchVisibilty) {
				el.find('.dropdown-toggle').css({ visibility: 'inherit' });
				searchEl.addClass('hidden');
			}

			searchEl.off('click');
			searchEl.find('input').off('keyup');


			let changed = initialTags.length !== selectedTags.length;
			initialTags.forEach(function (tag, index) {
				if (tag !== selectedTags[index]) {
					changed = true;
				}
			});
			initialTags = selectedTags.slice();
			if (changed) {
				if (options.updateButton) {
					options.updateButton({ el, changed: changed, selectedTags: selectedTags.slice() });
				} else if (options.updateButton !== false) {
					updateFilterButton(el, selectedTags);
				}
			}
			if (options.onHidden) {
				options.onHidden({ changed: changed, selectedTags: selectedTags.slice() });
				return;
			}
			if (changed) {
				let url = window.location.pathname;
				const currentParams = utils.params();
				if (selectedTags.length) {
					currentParams.tag = selectedTags.length ? selectedTags : undefined;
				} else {
					delete currentParams.tag;
				}
				delete currentParams.page;
				if (Object.keys(currentParams).length) {
					url += '?' + decodeURIComponent($.param(currentParams));
				}
				ajaxify.go(url);
			}
		});

		el.on('click', '[component="tag/filter/list"] [data-tag]', function () {
			const listEl = el.find('[component="tag/filter/list"]');
			const tagEl = $(this);
			const link = tagEl.find('a').attr('href');
			if (link && link !== '#' && link.length) {
				return;
			}
			const tag = tagEl.attr('data-tag');
			const icon = tagEl.find('[component="tag/select/icon"]');

			if (tag !== '') {
				if (selectedTags.includes(tag)) {
					selectedTags.splice(selectedTags.indexOf(tag), 1);
				} else {
					selectedTags.push(tag);
				}
				selectedTags.sort(function (a, b) {
					return a - b;
				});
				icon.toggleClass('invisible');
			} else {
				el.find('[component="tag/select/icon"]').addClass('invisible');
				selectedTags = [];
			}

			listEl.find('[data-tag=""] i').toggleClass('invisible', !!selectedTags.length);
			options.selectedTags = selectedTags;
			if (options.onSelect) {
				options.onSelect({ tag: tag, selectedTags: selectedTags.slice() });
			}
			return false;
		});

		function loadList(query, callback) {
			let cids = null;
			if (ajaxify.data.template.category) {
				cids = [ajaxify.data.cid];
			// selectedCids is avaiable on /recent, /unread, /popular etc.
			} else if (Array.isArray(ajaxify.data.selectedCids) && ajaxify.data.selectedCids.length) {
				cids = ajaxify.data.selectedCids;
			}
			socket.emit('topics.tagFilterSearch', {
				query: query,
				cids: cids,
			}, function (err, data) {
				if (err) {
					return alerts.error(err);
				}
				callback(data);
			});
		}

		function renderList(tags) {
			const selectedTags = options.selectedTags;
			tags.forEach(function (tag) {
				tag.selected = selectedTags.includes(tag.valueEscaped);
			});

			app.parseAndTranslate(options.template, {
				tagItems: tags.slice(0, 200),
				selectedTag: ajaxify.data.selectedTag,
			}, function (html) {
				el.find('[component="tag/filter/list"]')
					.html(html.find('[component="tag/filter/list"]').html());

				const bsDropdown = bootstrap.Dropdown.getInstance(el.find('.dropdown-toggle').get(0));
				if (bsDropdown) {
					bsDropdown.update();
				}
			});
		}
	};

	function updateFilterButton(el, selectedTags) {
		if (selectedTags.length > 0) {
			renderButton({
				label: selectedTags.join(', '),
			});
		} else {
			renderButton();
		}
		function renderButton(selectedTag) {
			app.parseAndTranslate('partials/tags/filter-dropdown-content', {
				selectedTag: selectedTag,
			}, function (html) {
				el.find('button').replaceWith($('<div/>').html(html).find('button'));
			});
		}
	}

	return tagFilter;
});
