/**
 * Serverstats class, manage stats edit view activities
 * such as fancybox management and server stats JQVMap
 * 
 * @package JREALTIMEANALYTICS::SERVERSTATS::administrator::components::com_jrealtimeanalytics
 * @subpackage js
 * @author Joomla! Extensions Store
 * @copyright (C)2014 Joomla! Extensions Store
 * @license GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html
 */
// 'use strict';
(function($) {
	var Serverstats = function(DOMViewSelectors) {
		var aiRequestRunning = false;
		var aiToolbarButton = null;

		/**
		 * Wrapped set for search input fields
		 * 
		 * @access private
		 * @var Object
		 */
		var searchFields = $('input[data-role=filter]');
		
		/**
		 * Wrapped set for reset buttons
		 * 
		 * @access private
		 * @var Object
		 */
		var resetButtons = $('button[data-role=reset-filter]');
		
		/**
		 * Intercepts the key events to filter table results accordingly
		 * 
		 * @access private
		 * @return Boolean
		 */
		function filterResults(jqEvent) {
			var targetTable = $(this).parents('div.accordion-group').find('table.adminlist');
			var tdFieldPosition = parseInt($(this).data('field')) - 1;
			var searchedValue = $(this).val().toLowerCase();
			
			// Reset other search fields if any
			var currentDataField = $(this).data('field');
			$('input[data-role=filter]').filter(function(index, element){
				return $(element).data('field') == currentDataField ? false : true;
			}).val('');
			
			// Cycle for all table rows
			var occurrences = 0;
			$('tbody tr', targetTable).each(function(index, trElement){
				var currentFieldValue = $($('td', trElement).get(tdFieldPosition)).filter(function(){
					return $('a.preview', this).length ? false : true;
				}).text().toLowerCase();
				
				// If not a valid value has been found continue the cycle here to the next record
				if(!currentFieldValue) {
					return true;
				}

				// Switch the action to be taken on this record
				if(currentFieldValue.indexOf(searchedValue) >= 0) {
					$(trElement).show();
					occurrences++;
				} else {
					$(trElement).hide();
				}
			});
			
			// Remove and append results occurrences label
			$(this).nextAll('span[data-role=badge-occurrences]').remove();
			
			if(searchedValue) {
				var labelClass = occurrences > 0 ? 'bg-success' : 'bg-danger';
				$(this).nextAll('button.btn').after('<span data-role="badge-occurrences" class="badge ' + labelClass + ' badge-occurrences">' + COM_JREALTIME_NUMRESULTS + occurrences + '</span>');
			}

			return false;
		};

		function escapeHtml(text) {
			return $('<div/>').text(text).html();
		}

		function renderAIAnalysis(rawContent) {
			var normalizedContent = (rawContent || '').replace(/\r\n/g, '\n').replace(/\r/g, '\n');
			normalizedContent = normalizedContent.replace(/\*\*/g, '');
			return '<div class="jrealtime-ai-output"><pre>' + escapeHtml(normalizedContent) + '</pre></div>';
		}

		function setAIButtonBusy(isBusy) {
			if(!aiToolbarButton || !aiToolbarButton.length) {
				return;
			}

			aiToolbarButton.prop('disabled', isBusy);
			aiToolbarButton.toggleClass('disabled', isBusy);
			aiToolbarButton.find('.icon-wand').toggleClass('icon-spin', isBusy);
		}

		function runAIAnalysis() {
			if(aiRequestRunning) {
				return false;
			}

			var fromPeriod = $('input#fromPeriod').val() || '';
			var toPeriod = $('input#toPeriod').val() || '';
			var graphTheme = $('select[name=graphtheme]').val() || 'Universal';
			var statsReport = $('input[name=statsreport]').val() || 'full';
			var payload = {
				idtask: 'getServerstatsAIAnalysis',
				param: {
					fromperiod: fromPeriod,
					toperiod: toPeriod,
					graphtheme: graphTheme,
					statsreport: statsReport
				}
			};

			var requestData = { data: JSON.stringify(payload) };
			if(typeof jrealtimeAIAnalysisCsrfToken !== 'undefined' && jrealtimeAIAnalysisCsrfToken) {
				requestData[jrealtimeAIAnalysisCsrfToken] = 1;
			}

			aiRequestRunning = true;
			setAIButtonBusy(true);

			$.ajax({
				type: 'POST',
				url: jrealtimeAIAnalysisAjaxEndpoint,
				data: requestData,
				dataType: 'json'
			}).done(function(response) {
				if(response && response.result && response.analysis) {
					$('#jrealtimeAiAnalysisModalBody').html(renderAIAnalysis(response.analysis));
					if(window.bootstrap && document.getElementById('jrealtimeAiAnalysisModal')) {
						bootstrap.Modal.getOrCreateInstance(document.getElementById('jrealtimeAiAnalysisModal')).show();
					}
					return;
				}

				var errorMessage = (response && response.message) ? response.message : COM_JREALTIME_AI_ANALYSIS_REQUEST_FAILED;
				window.alert(errorMessage);
			}).fail(function() {
				window.alert(COM_JREALTIME_AI_ANALYSIS_REQUEST_FAILED);
			}).always(function() {
				aiRequestRunning = false;
				setAIButtonBusy(false);
			});

			return false;
		}

		/**
		 * Function dummy constructor
		 * 
		 * @access private
		 * @param String
		 *            contextSelector
		 * @method <<IIFE>>
		 * @return Void
		 */
		(function __construct() {
			// Initialize calendar
			if(jrealtimeStatsCalendarFormat == 'date') {
				$('input[data-role=calendar]').datepicker({
					dateFormat : 'yy-mm-dd',
					firstDay : 1
				}).prev('span').on('click', function() {
					$(this).datepicker('show');
				});
			} else if(jrealtimeStatsCalendarFormat == 'datetime') {
				$('input[data-role=calendar]').datetimepicker({
					dateFormat : 'yy-mm-dd',
					timeFormat: 'HH:mm:ss',
					firstDay : 1
				}).prev('span').on('click', function() {
					$(this).datetimepicker('show');
				});
			}

			// Initialize table sorter
			$('table.table-striped').tablesorter({
				cssHeader : ''
			});

			// Initialize fancybox map
			$('*[data-bind=geomap]').vectorMap({
				map: 'world_en',
				backgroundColor : '#FFFFFF',
			    color: '#DEDEDE',
			    hoverOpacity: 0.7,
			    selectedColor: '#666666',
			    enableZoom: true,
			    showTooltip: true,
			    values: jrealtimeGeoMapData,
			    scaleColors: ['#B4D6E6', '#4B97BA'],
			    normalizeFunction: 'polynomial',
			    onLabelShow: function(event, label, name, value) {
			    	label.text(name + ': ' + value);
			    }
			});
			
			// Initialize fancybox for stats details
			$('.preview').fancybox({
				width : '95%',
				height : '90%',
				autoScale : false,
				scrolling : 'no',
				transitionOut : 'none',
				type : 'iframe',
				title : COM_JREALTIME_STATS_DETAILS
			});
			
			// Initialize fancybox for geomap
			$('#open_visualmap').fancybox({
				width : '100%',
				height : 350,
				autoScale : true,
				transitionOut : 'none',
				type : 'inline',
				title : COM_JREALTIME_VISUALMAP,
			    onCleanup: function(currentArray, currentIndex, currentOpts) {
			    	var originalVisualMap = $('#fancybox_visualmap'); 
			    	originalVisualMap.appendTo('div.fancybox.geomap');
			    }
			});
			
			$('div.rightgraph_stats.pie a.fancybox-image, div.rightgraph_stats.bar a.fancybox-image').fancybox({
				width : 580,
				height : 350,
				autoScale : false,
				transitionOut : 'none',
				type : 'image' 
			});
			
			// Bind search fields event
			searchFields.on('click', function(){return false;}).on('keyup', filterResults);
			resetButtons.on('click', function(jqEvent){
				$(this).prevAll('input').val('').trigger('keyup');
				return false;
			});

			// Enables bootstrap popover
			[].slice.call(document.querySelectorAll('a.hasClickPopover')).map(function (popoverEl) {
				let popoverInstance = new bootstrap.Popover(popoverEl,{
					template : '<div class="popover"><div class="popover-arrow"></div><h3 class="popover-header"></h3><div class="popover-body"></div></div>',
					trigger: 'click', 
					placement: 'right',
					html: true,
					sanitize: false,
					content: function(element) {
						var targetElem = element ? element : this; 
						var ipToLookup = $(targetElem).data('ip');
						var parentTrIndex = $(targetElem).parents('tr').index();
						var uniqueIdentifier = ipToLookup.replace(/[\.:]/g, '');
						uniqueIdentifier = 'jrealtimeip' + parentTrIndex + uniqueIdentifier;
						
						// Already contents IP info retrieved? Stop and return now
						if($(targetElem).data('jrealtime_iprequest')) {
							return '<div id="' + uniqueIdentifier + '"></div>';
						}
						
						if($(targetElem).data('jrealtime_ipinfo')) {
							var currentData = $(targetElem).data('jrealtime_ipinfo');
							
							// Process additional host info if needed
							if(jrealtimeBackendHostInfo) {
								var ipAddressData = $(targetElem).data('jrealtime_ipaddressinfo');
								if(ipAddressData) {
									currentData = currentData.replace('</ul>', ipAddressData + '</ul>');
								}
							}
							
							return currentData;
						}
						
						$(targetElem).data('jrealtime_iprequest', true);
						
						// Get the async IP info
						if(jrealtimeGeolocationService == 'geoiplookup') {
							var webServiceEndpoint = 'https://json.geoiplookup.io/' + ipToLookup;
							var jsonp = 'jsonp';
						} else {
							var webServiceEndpoint = 'https://ipapi.co/' + ipToLookup + '/json';
							var jsonp = null;
						}
						
						$.get(webServiceEndpoint, function (response) {
							var emptyResponse = true;
							if(response) {
								var htmlIpInfo = '<ul class="jrealtime_ipgeolocation">';
								if(response.city) {
									htmlIpInfo += '<li>' + response.city + '</li>';
									emptyResponse = false;
								}
								
								if(response.country_name) {
									htmlIpInfo += '<li>' + response.country_name + '</li>';
									emptyResponse = false;
								}
								
								if(response.region) {
									htmlIpInfo += '<li>' + response.region + '</li>';
									emptyResponse = false;
								}
								
								if(response.isp) {
									htmlIpInfo += '<li>' + response.isp + '</li>';
									emptyResponse = false;
								} else if(response.org) {
									htmlIpInfo += '<li>' + response.org + '</li>';
									emptyResponse = false;
								}
							} else {
								// Empty response
								htmlIpInfo = '-';
							}
							// Empty response
							if(emptyResponse) {
								htmlIpInfo = '-';
							} else {
								htmlIpInfo += '</ul><span class="icon-location" aria-hidden="true"></span>';
							}
							
							// Update the placeholder in async way
							$('#' + uniqueIdentifier).html(htmlIpInfo);
							$(targetElem).data('jrealtime_ipinfo', htmlIpInfo);
							$(targetElem).data('jrealtime_iprequest', false);
							
							// Make additional get request for gethostbyaddr
							if(jrealtimeBackendHostInfo) {
								var noCacheEndPoint = jrealtimeIpAddressServerStatsEndpoint + '?time=' + (new Date().getTime()) + '&ipaddress=' + ipToLookup;
								$.ajax({
									type : 'GET',
									async : true,
									url : noCacheEndPoint,
									dataType : 'text',
									success : function(ipAddrInfo) {
										var additionalIpinfo = '<li>' + ipAddrInfo + '</li>';
										
										// Append and calculate the extra height
										var additionalIpInfoHeight = $('ul.jrealtime_ipgeolocation', '#' + uniqueIdentifier).append(additionalIpinfo);
										
										// Store data into the HTML element for page caching
										$(targetElem).data('jrealtime_ipaddressinfo', additionalIpinfo);
									}
								});
							}
						}, jsonp);
						
						return '<div id="' + uniqueIdentifier + '"></div>';
					}
				});
				
				popoverEl.addEventListener('shown.bs.popover', function(){
					setTimeout(function(context){
						$(context).addClass('active');
					}, 0, this);
				});
				
				popoverEl.addEventListener('hidden.bs.popover', function(){
					$(this).removeClass('active');
				});
				
				return popoverInstance;
			});

			// Ensure closing it when click on other DOM elements
			$(document).on('click', 'body', function(jqEvent){
				var targetClicked = $(jqEvent.target);
				if(!targetClicked.hasClass('hasClickPopover active') && !targetClicked.hasClass('popover-body') && targetClicked.parents('popover-body').length == 0) {
					[].slice.call(document.querySelectorAll('a.hasClickPopover.active')).map(function (popoverEl) {
						bootstrap.Popover.getInstance(popoverEl).hide();
					});
				}
			});

			$('div.accordion-body').on('scroll', function(jqEvent) {
				if($('a.hasClickPopover.active').length) {
					[].slice.call(document.querySelectorAll('a.hasClickPopover.active')).map(function (popoverEl) {
						bootstrap.Popover.getInstance(popoverEl).hide();
					});
				}
			});
			
			// Always enable the 'Delete all metainfo' button
			if(typeof(COM_JREALTIME_DELETE_SERVERSTATS_PERIOD_CACHE) !== 'undefined') {
				$('#toolbar-delete').attr('confirm-message', COM_JREALTIME_DELETE_SERVERSTATS_PERIOD_CACHE);
			}
			
			// Always enable the 'Delete all metainfo' button
			if(typeof(COM_JREALTIME_DELETE_SERVERSTATS_ALL_CACHE) !== 'undefined') {
				$('#toolbar-cancel').attr('confirm-message', COM_JREALTIME_DELETE_SERVERSTATS_ALL_CACHE);
			}

			aiToolbarButton = $('#toolbar-wand button, #toolbar-wand a');
			this.runAIAnalysis = runAIAnalysis;
		}).call(this);
	}

	// On DOM Ready
	$(function() {
		window.JRealtimeServerstats = new Serverstats();
	});
})(jQuery);