/* @since CommunityAlly 1.0.5 */
/* global CommunityAllyLoader */

window.bp = window.bp || {};

( function( bp, $ ) {
	window.communityally_serialize_value_in_container = function($container) {
		var values = [];
		$container.find('input[type="hidden"],input[type="text"],input[type="search"],textarea').each(function(index, elem) {
			var $elem = $(elem),
				attr = $elem.attr('name');
			if (typeof attr !== typeof undefined && attr !== false) {
				values.push({ name : attr, value : $elem.val() });
			}
		});
		$container.find('input[type="radio"]:checked').each(function(index, elem) {
			var $elem = $(elem),
				attr = $elem.attr('name');
			if (typeof attr !== typeof undefined && attr !== false) {
				values.push({ name : attr, value : $elem.attr('value') });
			}
		});
		$container.find('input[type="checkbox"]:checked').each(function(index, elem) {
			var $elem = $(elem),
				attr = $elem.attr('name');
			if (typeof attr !== typeof undefined && attr !== false) {
				values.push({ name : attr, value : $elem.attr('value') });
			}
		});
		$container.find('select').each(function(index, elem) {
			var $elem = $(elem),
				attr = $elem.attr('name');
			if (typeof attr !== typeof undefined && attr !== false) {
				values.push({ name : attr, value : $elem.children(':selected').val() });
			}
		});
		return values;
	};
	$(document).ready(function($) {
		// <editor-fold defaultstate="collapsed" desc="data-dependency logic">
		function evaluate_dependency(collection, value, match_function, mismatch_function) {
			for (var index = 0; index < collection.length; ++index) {
				var $elem = $(collection[index]),
					dependency_value = $elem.attr('communityally-data-dependency-value'),
					dependency_value_not = $elem.attr('communityally-data-dependency-value-not'),
					key, matched = false;
				if (typeof dependency_value !== typeof undefined && dependency_value !== false) {
					dependency_value = dependency_value.split('|');
					matched = false;
					for (key in dependency_value) {
						if (dependency_value[key] === value) {
							matched = true;
							break;
						}
					}
					if (matched) {
						match_function($elem);
					} else {
						mismatch_function($elem);
					}
				}
				if (typeof dependency_value_not !== typeof undefined && dependency_value_not !== false) {
					if (dependency_value_not !== value) {
						match_function($elem);
					} else {
						mismatch_function($elem);
					}
				}
			}
		}
		$(document).on('change', '[communityally-data-dependency-source]', function() {
			var $element = $(this),
				value = 'no',
				dependency_name = $element.attr('communityally-data-dependency-source'),
				dependencies = $('[communityally-data-dependency="' + dependency_name + '"]');
			if($element.attr('type') === 'checkbox') {
				if ($element.is(':checked')){
					value = 'yes';
				}
			} else if ($element.attr('type') === 'radio') {
				if ($element.is(':checked')){	// only evaluate for the element that is checked
					value = $element.val();
				} else {
					return;
				}
			} else {
				value = $element.val();
			}

			if (value){
				value = value.replace(/\"/g, '\\"');
			}
			evaluate_dependency(dependencies.filter('[hide-toggle]'), value, function(elem) { elem.show(); }, function(elem) { elem.hide(); });
			evaluate_dependency(dependencies.filter('[readonly-toggle]'), value, function(elem) { elem.prop('readonly', false); }, function(elem) { elem.prop('readonly', true); });
			evaluate_dependency(dependencies.filter('[disable-toggle]'), value, function(elem) { elem.prop('disabled', false); }, function(elem) { elem.prop('disabled', true); });
		});
		// </editor-fold>

		function async_load_js(firstScriptTag, js_url) {
			if ($('script[src^="' + js_url + '"]').length > 0) {
				return;
			}
			let tag = document.createElement('script');
			tag.src = js_url;

			firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
		}
		function async_load_css(firstCssTag, css_url) {
			if ($('link[href^="' + css_url + '"]').length > 0) {
				return;
			}
			let tag = document.createElement('link');
			tag.rel = 'stylesheet';
			tag.media = 'all';
			tag.href = css_url;

			firstCssTag.parentNode.insertBefore(tag, firstCssTag);
		}
		function async_load_activity_js() {
			let firstCssTag = document.getElementsByTagName('link')[0];
			async_load_css(firstCssTag, CommunityAllyLoader.base_url + 'bp-activity/css/mentions.min.css');

			let firstScriptTag = document.getElementsByTagName('script')[0];
			async_load_js(firstScriptTag, CommunityAllyLoader.base_url + 'bp-templates/bp-nouveau/js/buddypress-activity.min.js');
			async_load_js(firstScriptTag, CommunityAllyLoader.base_url + 'bp-templates/bp-nouveau/js/communityally-discussion.min.js');
			async_load_js(firstScriptTag, CommunityAllyLoader.base_url + 'bp-core/js/vendor/jquery.caret.min.js');
			async_load_js(firstScriptTag, CommunityAllyLoader.base_url + 'bp-core/js/vendor/jquery.atwho.min.js');
			async_load_js(firstScriptTag, CommunityAllyLoader.base_url + 'bp-activity/js/mentions.min.js');
		}
		function async_load_notification_js() {
			let firstScriptTag = document.getElementsByTagName('script')[0];
			async_load_js(firstScriptTag, CommunityAllyLoader.base_url + 'bp-templates/bp-nouveau/js/buddypress-notifications.min.js');
		}
		let $communityally_elements = $('.communityally-shortcode-element');
		if ($communityally_elements.length > 0) {
			async_load_activity_js();
		}
		let $notification_elements = $('.communityally-notification-element');
		if ($notification_elements.length > 0) {
			async_load_notification_js();
		}

		// <editor-fold defaultstate="collapsed" desc="Tab control">
		function change_tab($elem) {
			var selector = $elem.attr('communityally-tab-group'),
				target = $elem.attr('communityally-target'),
				active = $elem.attr('communityally-active-class'),
				click_target = $elem.attr('communityally-click-target'),
				$tabs = $('[' + selector + ']');
			$('[communityally-tab-group=' + selector + ']').removeClass(active);
			$elem.addClass(active);
			$tabs.filter('[' + selector + '!=' + target + ']').hide();
			$tabs.filter('[' + selector + '=' + target + ']').show();
			$('[communityally-tab-group-value="' + selector + '"]').val(target);
			if (typeof click_target !== typeof undefined && click_target !== false) {
				$(click_target).val(target).change();
			}
		}
		$(document).on('click touchend', '[communityally-tab-group]', function(e) {
			change_tab($(this));
			return false;
		});
		// </editor-fold>

		// <editor-fold defaultstate="collapsed" desc="User name search without @ symbol">
		let communityally_autocomplete_cache = {};
		$.widget("custom.communityally_name_search_box", {
			_create: function () {
				this.wrapper = $('<span>').addClass('communityally-autocomplete-combobox');
				this.wrapper.insertAfter(this.element);
				this.element.hide();

				// this override is required to show entries with no name
				$.ui.menu.prototype._isDivider = function() { return false; };

				this._createAutocomplete();
			},
			_createAutocomplete: function () {
				var selected = this.element.children(":selected"),
					value = selected.val() ? selected.text() : "",
					size = this.element.attr('size'),
					placeholder = this.element.attr('placeholder');

				this.input = $('<input type="text">')
						.appendTo(this.wrapper)
						.val(value)
						.attr('size', size)
						.attr('placeholder', placeholder)
						.attr('title', '')
						.autocomplete({
							delay: 0,
							minLength: 0,
							source: $.proxy(this, "_source")
						})
						.keypress(function(e) {
							if(e.keyCode == 13){
								return false;
							}
						});
				this.input.data("ui-autocomplete")._renderItem = generate_autocomplete_entry_display;

				this._on(this.input, {
					autocompleteselect: function (event, ui) {
						let $elem = $('<div class="communityally-message-recipient-entry"><img src="' +
								esc_html(ui.item.image) + '" /><span class="communityally-message-recipient-name">' + esc_html(ui.item.name) +
								'</span><input name="recipient[]" type="hidden" value="' + ui.item.value + '" />' +
								'<div class="communityally-message-recipient-delete"></div></div>');
						this.element.before($elem);
						this.input.val('');
						return false;
					},
					autocompletechange: "_removeIfInvalid",
					focus: function() {
						this.input.keydown();
					}
				});
				this.input.focus();
			},
			_source: function (request, generate_display_func) {
				let search_pattern = request.term.toLowerCase(),
					data = {
					action: 'bp_get_suggestions',
					term: search_pattern,
					type: 'members'
				};
				if (search_pattern in communityally_autocomplete_cache) {
					if ('sent' === communityally_autocomplete_cache[search_pattern]) {
						return;
					}
					if (communityally_autocomplete_cache[search_pattern]) {
						generate_display_func(communityally_autocomplete_cache[search_pattern]);
						return;
					}
				}
				communityally_autocomplete_cache[search_pattern] = 'sent';
				$.ajax({
					type: 'GET',
					url: CommunityAllyLoader.ajax_url,
					data: data,
					success: function(response) {
						try {
							let item_list = [],
								search_pattern = request.term.toLowerCase(),
								search_length = search_pattern.length;
							if (!response.success) {
								communityally_autocomplete_cache[search_pattern] = false;
								return;
							}

							for (let key in response.data) {
								let entry = response.data[key],
									text = entry.name;
								if (!request.term) {
									item_list.push({
										label: '<img src="' + esc_html(entry.image) + '" /><span>' + esc_html(text) + '</span>',
										value: entry.user_id,
										image: entry.image,
										name: text
									});
								} else {
									let index = text.toLowerCase().indexOf(search_pattern);
									if (index >= 0) {
										item_list.push({
											label: '<img src="' + esc_html(entry.image) + '" />' + highlight_text(text, index, search_length),
											value: entry.user_id,
											image: entry.image,
											name: text
										});
									}
								}
							}
							communityally_autocomplete_cache[search_pattern] = item_list;
							generate_display_func(item_list);
						} catch (e) {
						}
					}
				});
			},
			_removeIfInvalid: function (event, ui) {
				// Selected an item, nothing to do
				if (ui.item) {
					return;
				}

				// Search for a match (case-insensitive)
				var value = this.input.val(),
						valueLowerCase = value.toLowerCase(),
						valid = false;
				this.element.children("option").each(function () {
					if ($(this).text().toLowerCase() === valueLowerCase) {
						this.selected = valid = true;
						return false;
					}
				});

				// Found a match, nothing to do
				if (valid) {
					this.element.change();
					return;
				}

				// Remove invalid value
				this.input
						.val("")
						.attr("title", value + " didn't match any item");
				this.element.val("").change();
				this.input.autocomplete("instance").term = "";
			},
			_destroy: function () {
				this.wrapper.remove();
				this.element.show();
			}
		});
		function generate_autocomplete_entry_display(ul, item) {
			if (item) {
				var result = $('<li class="communityally-name-option" tab-index="-1">' +
						item.label + '</li>');
				ul.append(result);
				return result;
			}
		}

		// initialize auto complete
		$(document).on('focus', '.communityally-name-trigger-suggestions', function() {
			$(this).removeClass('communityally-name-trigger-suggestions').communityally_name_search_box();
		});
		// </editor-fold>

		// <editor-fold defaultstate="collapsed" desc="User profile / message popup">
		function show_private_message_popup(event, $source_elem, user_arg) {
			let $modal = $('#communityally-user-private-message-modal');
			if ($modal.length < 1) {
				if (!CommunityAllyLoader.private_message_popup) {
					return false;	// do not intercept the event
				}
				$('body').append(CommunityAllyLoader.private_message_popup);
				$modal = $('#communityally-user-private-message-modal');
			}
			let $message_link = $modal.find('.communityally-activity-user-button-message'),
				message_base_url = $message_link.attr('communityally-base-href'),
				$profile_link = $modal.find('.communityally-activity-user-button-profile'),
				profile_base_url = $profile_link.attr('communityally-base-href');
			$message_link.attr('href', message_base_url + '?communityally-send-to=' + user_arg);
			$profile_link.attr('href', profile_base_url + user_arg + '/');

			let x = event.pageX,
				y = event.pageY;
			$modal.css('left', x).css('top', y).show();
			return true;
		}
		function click_to_open_message_button_container(e){
			let $this = $(this),
				user_arg = $this.attr('communityally-user-link');
			if (show_private_message_popup(e, $this, user_arg)) {
				e.preventDefault();
				return false;
			}
			return true;
		}
		$(document).on('click touchend', '[communityally-user-link]', click_to_open_message_button_container);
		function close_message_button_container(e){
			let $modal = $('#communityally-user-private-message-modal');
			// the click is on the background and not in the links
			if (e.target === this) {
				$modal.hide();
			}
		}
		$(document).on('click touchend', '.communityally-activity-user-button-background-overlay', close_message_button_container);
		// </editor-fold>

		// <editor-fold defaultstate="collapsed" desc="Delete private message recipient">
		$(document).on('click touchend', '.communityally-message-recipient-delete', function() {
			$(this).parents('.communityally-message-recipient-entry').remove();
		});
		// </editor-fold>

		// <editor-fold defaultstate="collapsed" desc="Highlight autocomplete text">
		function highlight_text(target, start, length) {
			var result = '';
			if (start > 0) {
				result += esc_html(target.substring(0, start));
			}
			result += '<span class="communityally-name-option-highlight">' + esc_html(target.substring(start, start + length)) + '</span>';
			if (start + length < target.length) {
				result += esc_html(target.substring(start + length));
			}
			return result;
		}
		// </editor-fold>

		// <editor-fold defaultstate="collapsed" desc="Utility function to escape HTML text">
		function esc_html(code) {
			code = code.replace(/&/g, '&amp;');
			code = code.replace(/</g, '&lt;');
			code = code.replace(/>/g, '&gt;');
			code = code.replace(/'/g, '&#39;');
			code = code.replace(/"/g, '&quot;');
			return code;
		}
		// </editor-fold>
	});
} )( window.bp, jQuery );