(function($) {
	
	// Deselect all
	// https://jsfiddle.net/9zme6krw/2/
	Selectize.define("deselect_all_options", function(options) {
		if (this.settings.mode === "single") return;

		var self = this;

		self.setup = (function() {
			var original = self.setup;
			return function() {
				original.apply(this, arguments);

				var clearBtn = $('<button type=\"button\" class="sfwc-deselect">&#9447; ' + sfwc_vars_filter_orders.deselectAll + '</button>');

				clearBtn.on("click", function() {
					self.setValue([]);
				});

				this.$wrapper.append(clearBtn)
			};
		})();
	});


	
	/**
	 * Plugin: "preserve_search" (selectize.js)
	 * Based on: "preserve_on_blur" of Eric M. Klingensmith
	 *
	 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
	 * file except in compliance with the License. You may obtain a copy of the License at:
	 * http://www.apache.org/licenses/LICENSE-2.0
	 *
	 * Unless required by applicable law or agreed to in writing, software distributed under
	 * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
	 * ANY KIND, either express or implied. See the License for the specific language
	 * governing permissions and limitations under the License.
	 */
	Selectize.define('preserve_search', function (options) {
		var self = this;

		options.text = options.text || function (option) {
			return option[this.settings.labelField];
		};

		this.onBlur = (function (e) {
			var original = self.onBlur;

			return function (e) {
				// Capture the current input value
				var $input = this.$control_input;
				var inputValue = $input.val();

				// Do the default actions
				original.apply(this, [e]);

				// Set the value back                    
				this.setTextboxValue(inputValue);
			};
		})();

		this.onOptionSelect = (function (e) {
			var original = self.onOptionSelect;

			return function (e) {
				// Capture the current input value
				var $input = this.$control_input;
				var inputValue = $input.val();

				original.apply(this, [e]);
				this.setTextboxValue(inputValue);
				this.refreshOptions();
				if (this.currentResults.items.length <= 0) {
					this.setTextboxValue('');
					this.refreshOptions();
				}
			};
		})();
	});
	
	
	// Initialize Selectize.
	$("#sfwc-select-subaccount-orders").selectize({
		copyClassesToDropdown: true,
		plugins:
		[
			"remove_button",
			"deselect_all_options",
			"preserve_search"
		]
	});
	
	
	
	// Populate Selectize form with selected values.
	for( var i=0; i < sfwc_vars_filter_orders.preSelectedUsers.length; i++ ){
		$('#sfwc-select-subaccount-orders').selectize()[0].selectize.addOption( {value: sfwc_vars_filter_orders.preSelectedUsers[i].optionValue, text: sfwc_vars_filter_orders.preSelectedUsers[i].optionText} );
		$('#sfwc-select-subaccount-orders').selectize()[0].selectize.addItem( sfwc_vars_filter_orders.preSelectedUsers[i].optionValue );
	}					
	
	

	/********
	 * AJAX
	 ********/
	
	$("#sfwc-select-subaccount-orders-form-wrap #sfwc-loading-icon").hide();

	var selected_users = $('#sfwc-select-subaccount-orders').selectize()[0].selectize.getValue();

	var page = 0;
	
	var ajaxAction;

	if( sfwc_vars_filter_orders.accountType == 'manager' ){
		var currentAccountType = 'manager';
		ajaxAction = 'frontend_populate_subaccount_orders_dropdown_with_subaccounts';
		
		// Run function only on first click after page load.
		$("#sfwc-select-subaccount-orders-form-wrap .selectize-input").one("click", function () {
			getUsersPopulateSelectFieldOrders();
		});
	}
	
	
	if ( typeof search_val == 'undefined' ) {
		var search_val = null;
	}

	var endReached = false;

	function wrapGetUsersPopulateSelectFieldOrders() {
		
		$('#sfwc-select-subaccount-orders-form-wrap .selectize-dropdown-content').on('scroll', function() {
			if( $(this).scrollTop() + $(this).innerHeight() >= $(this)[0].scrollHeight ) {
				//console.log('end reached');
				if (endReached != true ) {
					getUsersPopulateSelectFieldOrders();
				}
				

			}
		})
		
		// Detect changes in preselected values.	
		var selectizeControl = $("#sfwc-select-subaccount-orders").selectize()[0].selectize;		
		selectizeControl.on('change', function() {
			selected_users = $('#sfwc-select-subaccount-orders').selectize()[0].selectize.getValue();
			//console.log(selected_users);
		});
		
		
		/**
		 * Trigger getUsersPopulateSelectFieldOrders() function some seconds after user has finished typing.
		 */
		 
		// Timer setup.
		var typingTimerSubaccountOrders;          		// Timer identifier.
		var doneTypingIntervalSubaccountOrders = 2000;  // Time in ms.
		var $inputSubaccountOrders = $('#sfwc-select-subaccount-orders-form-wrap .selectize-input input');
		
		// On keyup, start the countdown.
		$inputSubaccountOrders.on('keyup', function (e) {
			
			var TextboxValue = $('#sfwc-select-subaccount-orders').selectize()[0].selectize.getTextboxValue();
			
			/**
			 * Reference: https://developer.mozilla.org/en-US/docs/Web/API/UI_Events/Keyboard_event_key_values
			 *
			 * Note: do not use "KeyCode" since it's deprecated. "key" property is fine.
			 */
			if (   e.key == "CapsLock"
				|| e.key == "Shift"
				|| e.key == "Tab"
				|| e.key == "Escape"
				|| e.key == "Control"
				|| e.key == "Meta" /* E.g. Windows, Command Key */
				|| e.key == "Pause"
				|| e.key == "Alt"
				|| e.key == "Fn"
				|| e.key == "Home" 
				|| e.key == "ArrowDown"
				|| e.key == "ArrowUp"
				|| e.key == "ArrowLeft"
				|| e.key == "ArrowRight"
				|| e.key == "Insert"
				|| e.key == "PageDown"
				|| e.key == "PageUp"
				|| e.key == "PageUp"
				|| e.key == "F1"
				|| e.key == "F2"
				|| e.key == "F3"
				|| e.key == "F4"
				|| e.key == "F5"
				|| e.key == "F6"
				|| e.key == "F7"
				|| e.key == "F8"
				|| e.key == "F9"
				|| e.key == "F10"
				|| e.key == "F11"
				|| e.key == "F12"
				|| e.key == "NumLock"
				|| e.key == "ScrollLock"
				|| (e.key = "Backspace" && TextboxValue.length == 0 && noMoreCharacters == false ) /* Backspace when there are no characters */
			) {									
				// Do nothing when above key are pressed.
				// Do not return, we need this function to continue.
			 } else {
				
				if (e.key = "Backspace" && TextboxValue.length == 0) {
					noMoreCharacters = false;
				} else {
					noMoreCharacters = true;
				}
				
				clearTimeout(typingTimerSubaccountOrders);
				typingTimerSubaccountOrders = setTimeout(doneTypingSubaccountOrders, doneTypingIntervalSubaccountOrders);
			}
		});
		
		// On keydown, clear the countdown.
		$inputSubaccountOrders.on('keydown', function () {
		  clearTimeout(typingTimerSubaccountOrders);
		});

		// User has finished typing.
		function doneTypingSubaccountOrders() {
			search_val = $('#sfwc-select-subaccount-orders-form-wrap .selectize-input input').val();
			page = 0;
			getUsersPopulateSelectFieldOrders();
		}
	}
	wrapGetUsersPopulateSelectFieldOrders();


	/**
	 * Retrieve users via Ajax and populate Selectize form.
	 */
	function getUsersPopulateSelectFieldOrders() {
		
		$.ajax({
			type: 'POST',
			data: {
				action: ajaxAction,
				ajax_user_id: sfwc_vars_filter_orders.userId,
				ajax_page: page + 1,
				ajax_search: search_val,
				nonce: sfwc_vars_filter_orders.nonce,
			},
			url: sfwc_vars_filter_orders.adminAjaxUrl,
			beforeSend: function () {
				
				// Temporarily disable dropdown items selection.
				$('#sfwc-select-subaccount-orders-form-wrap .selectize-dropdown-content').css({ 'opacity' : '0.5', 'pointer-events' : 'none' });
				
				// Show loading icon.
				$("#sfwc-select-subaccount-orders-form-wrap #sfwc-loading-icon").show();									
			},
			success: function (value) {									
				
				// Get value of search text.
				var TextboxValue = $('#sfwc-select-subaccount-orders').selectize()[0].selectize.getTextboxValue();									
				
				// Check if "value" contains any option tags, if not it means there are no more users to show.
				if ( value.indexOf('</option>') > -1 ) {
					
					// console.log(value);
					
					endReached = false;
					
					page++;
					
					// Store pre-selected items in array.
					var preSelectedValues = new Array();
					if ( selected_users && selected_users.length > 0 ) {										
						var i;
						for ( i = 0; i < selected_users.length; ++i ) {
							
							var text =  $('#sfwc-select-subaccount-orders').selectize()[0].selectize.getItem(selected_users[i]).text().replace('×', ''); // Remove × added from "remove_button" plugin.
							//var text =  $('#sfwc-select-subaccount-orders').selectize()[0].selectize.getItem(selected_users[i]).text();
							preSelectedValues[i]= { 'optVal': selected_users[i], 'optText': text }
						}
					}									
					
					// Destroy previous Selectize instance.
					$('#sfwc-select-subaccount-orders').selectize()[0].selectize.destroy();
					
					if ( search_val != null && page == 1 ) {
						
						$('select#sfwc-select-subaccount-orders').html('');
					}
					
					// Append new options.
					$('select#sfwc-select-subaccount-orders').append(value);

					// Reinitialize Selectize with new values.
					$("#sfwc-select-subaccount-orders").selectize({
						copyClassesToDropdown: true,
						plugins:
						[
							"remove_button",
							"deselect_all_options",
							"preserve_search"
						]
					});
					
					// Set value of search text (if any).
					if ( TextboxValue.length > 0 ) {
						$( '#sfwc-select-subaccount-orders' ).selectize()[0].selectize.setTextboxValue( TextboxValue );
					}
						
					// Add pre-selected items from the array.
					if ( preSelectedValues && preSelectedValues.length > 0 ) {										
						
						var i;
						for ( i = 0; i < preSelectedValues.length; ++i ) {
							
							// For pre-selected values it is necessary to add options in order to select them.
							$('#sfwc-select-subaccount-orders').selectize()[0].selectize.addOption( {value: preSelectedValues[i]['optVal'], text: preSelectedValues[i]['optText']} );
							$('#sfwc-select-subaccount-orders').selectize()[0].selectize.addItem( preSelectedValues[i]['optVal'] );
						}
					}
					
					// Refresh Selectize options.
					$('#sfwc-select-subaccount-orders').selectize()[0].selectize.refreshOptions();
					
					// Keep scroll position.
					var $container = $('#sfwc-select-subaccount-orders-form-wrap .selectize-dropdown-content');
					var $scrollTo = $('#sfwc-select-subaccount-orders-form-wrap div.first-item-loaded:last').prevAll().eq(6); // 6 = number of visible items in selectize dropdown without scrolling (7) minus 1.
					jQuery(document).ready(function(){
						
						if ( $scrollTo.offset() && $scrollTo.offset() ) {
							$container.scrollTop(
								$scrollTo.offset().top - $container.offset().top + $container.scrollTop()
							);
						}
					});
					
					// Hide loading icon.
					$("#sfwc-select-subaccount-orders-form-wrap #sfwc-loading-icon").hide();
					
					// Re-enable dropdown items selection.
					$('#sfwc-select-subaccount-orders-form-wrap .selectize-dropdown-content').css({ 'opacity' : '1', 'pointer-events' : '' });
					
					wrapGetUsersPopulateSelectFieldOrders();
					
				} else {
					endReached = true;
					$("#sfwc-select-subaccount-orders-form-wrap #sfwc-loading-icon").hide();
					$('#sfwc-select-subaccount-orders-form-wrap .selectize-dropdown-content').css({ 'opacity' : '1', 'pointer-events' : '' });
				}
			}
		});
	}
})( jQuery );