HEX
Server: Apache
System: Linux vps.teamads.com 4.18.0-553.126.1.el8_10.x86_64 #1 SMP Thu May 28 06:44:09 EDT 2026 x86_64
User: teamadsc (1024)
PHP: 8.1.34
Disabled: NONE
Upload Files
File: /home/teamadsc/public_html/wp-content/plugins/visitors/js/ahcpro_js_scripts.js
// Global number formatter — adds thousands separator (e.g. 125019 → "125,019")
function ahcProNumFormat(num) {
	if (num === null || num === undefined || num === '') return num;
	var n = Number(num);
	if (isNaN(n)) return num;
	return n.toLocaleString('en-US');
}

var colors = ['#DB6946', '#C14543', '#445060', '#395953', '#6C8C80', '#829AB5', '#BF807A', '#BF0000', '#006BB7', '#EC732C', '#BF3D27', '#A6375F',
	'#8C6D46', '#326149', '#802B35', '#8A3842', '#366D73', '#4D6173', '#4A4659', '#C9D65B', '#F45552', '#F3CC5E', '#F29B88', '#D96941',
	'#484F73', '#C9AB81', '#F5655C', '#F0C480'];

jQuery(document).ready(function () {




	if (typeof google === 'object' && typeof google.maps === 'object') {
		return;
	} else {

	}



});

//------------------------------------------------------------------------------				
function convertToNumeric(data) {
	if (data instanceof Array) {
		for (var index in data) {
			data[index] = Number(data[index]);
		}
	} else {
		data = Number(data);
	}
	return data;
}
//------------------------------------------------------------------------------
function getRandomElementFromArray(array) {
	var ranIndex = Math.floor(Math.random() * array.length);
	return array[ranIndex];
}
//------------------------------------------------------------------------------
function drawVisitsLineChart(start_date, end_date, interval, visitors, visits, duration) {
	// Safety check first
	if (!visits || !visitors || visits.length === 0 || visitors.length === 0) {
		jQuery('#visitscount').html('<div style="text-align:center;padding:50px;color:#666;">No chart data available</div>');
		return;
	}

	// Prepare data for Chart.js
	var labels = [];
	var visitorsData = [];
	var visitsData = [];

	// Extract labels and data from the arrays
	for (var i = 0; i < visits.length; i++) {
		if (visits[i] && visits[i][0] && visits[i][1] !== undefined) {
			// Format date for display
			var date = new Date(visits[i][0]);
			var formattedDate = (date.getMonth() + 1) + '/' + date.getDate();
			labels.push(formattedDate);
			visitsData.push(parseInt(visits[i][1]) || 0);
		}
	}

	for (var i = 0; i < visitors.length; i++) {
		if (visitors[i] && visitors[i][1] !== undefined) {
			visitorsData.push(parseInt(visitors[i][1]) || 0);
		}
	}

	var visitsColor = '#7c3aed';      // purple
	var visitorsColor = '#f59e0b';    // amber

	var barChartData = {
		labels: labels,
		datasets: [
			{
				label: "Visitors",
				borderColor: visitorsColor,
				backgroundColor: function(context) {
					var chart = context.chart;
					var ctx = chart.ctx;
					var chartArea = chart.chartArea;
					if (!chartArea) return null;
					var grad = ctx.createLinearGradient(0, chartArea.top, 0, chartArea.bottom);
					grad.addColorStop(0, 'rgba(245, 158, 11, 0.18)');
					grad.addColorStop(1, 'rgba(245, 158, 11, 0)');
					return grad;
				},
				borderWidth: 2,
				pointRadius: 4,
				pointBackgroundColor: '#fff',
				pointBorderColor: visitorsColor,
				pointBorderWidth: 2,
				pointHoverRadius: 6,
				tension: 0.35,
				fill: true,
				data: visitorsData
			},
			{
				label: "Visits",
				borderColor: visitsColor,
				backgroundColor: function(context) {
					var chart = context.chart;
					var ctx = chart.ctx;
					var chartArea = chart.chartArea;
					if (!chartArea) return null;
					var grad = ctx.createLinearGradient(0, chartArea.top, 0, chartArea.bottom);
					grad.addColorStop(0, 'rgba(124, 58, 237, 0.18)');
					grad.addColorStop(1, 'rgba(124, 58, 237, 0)');
					return grad;
				},
				borderWidth: 2,
				pointRadius: 4,
				pointBackgroundColor: '#fff',
				pointBorderColor: visitsColor,
				pointBorderWidth: 2,
				pointHoverRadius: 6,
				tension: 0.35,
				fill: true,
				data: visitsData
			}
		]
	};

	// Clear previous chart
	var ctx = document.getElementById("visitscount");
	if (!ctx) {
		return;
	}

	// Destroy existing chart if it exists
	if (window.visitChart) {
		window.visitChart.destroy();
	}

	// Create new chart
	ctx = ctx.getContext("2d");
	window.visitChart = new Chart(ctx, {
		type: 'line',
		data: barChartData,
		options: {
			responsive: true,
			maintainAspectRatio: false,
			interaction: {
				mode: 'index',
				intersect: false
			},
			scales: {
				y: {
					beginAtZero: true,
					border: { display: false },
					grid: {
						color: 'rgba(16, 24, 40, 0.05)',
						drawTicks: false
					},
					ticks: {
						stepSize: 1,
						precision: 0,
						color: '#98a2b3',
						font: { size: 11 },
						padding: 8
					}
				},
				x: {
					border: { display: false },
					grid: { display: false },
					ticks: {
						color: '#98a2b3',
						font: { size: 11 },
						padding: 4
					}
				}
			},
			plugins: {
				legend: {
					display: true,
					position: 'bottom',
					align: 'start',
					labels: {
						boxWidth: 10,
						boxHeight: 10,
						usePointStyle: true,
						pointStyle: 'circle',
						color: '#475467',
						font: { size: 12, weight: '500' },
						padding: 16
					}
				},
				tooltip: {
					backgroundColor: '#101828',
					titleColor: '#fff',
					bodyColor: '#fff',
					borderColor: 'transparent',
					padding: 10,
					cornerRadius: 8,
					displayColors: true,
					boxPadding: 4,
					titleFont: { size: 12, weight: '600' },
					bodyFont: { size: 12 }
				}
			}
		}
	});
}
//------------------------------------------------------------------------------


function drawSrhEngVstLineChart() {
	var srh_series = [];
	var container = jQuery('#srchEngLegContainer');
	var html = '';
	document.getElementById('srchEngLegContainer').style.display = 'none';

	// Search engine specific colors
	const searchEngineColors = {
		'google': '#4285f4',
		'bing': '#00a650',
		'yahoo': '#720e9e',
		'duckduckgo': '#de5833',
		'yandex': '#ffcc00',
		'baidu': '#2932e1',
		'unknown': '#95a5a6',
		'other': '#34495e'
	};

	// Generate distinct colors based on item count
	function generateDistinctColors(count) {
		const colors = [];
		const hueStep = 360 / count;

		for (let i = 0; i < count; i++) {
			const hue = i * hueStep;
			const saturation = 70 + (i % 3) * 10;
			const lightness = 45 + (i % 2) * 10;
			colors.push(`hsl(${hue}, ${saturation}%, ${lightness}%)`);
		}

		return colors;
	}

	// Get all search engines with non-zero values first
	var searchEngines = [];
	for (var index in srhEngVisitsData.data.search_engines) {
		var value = countVisits(srhEngVisitsData.data.search_engines[index]);
		if (parseFloat(value) != 0) {
			searchEngines.push({ name: index, value: value });
		}
	}

	var ctx = document.getElementById("srhEngBieChartContainer").getContext("2d");

	// Check if no data available
	if (searchEngines.length === 0) {
		// Clear any existing chart
		ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);

		// Draw "No Data Available" message
		ctx.font = "16px Arial";
		ctx.fillStyle = "#666";
		ctx.textAlign = "center";
		ctx.textBaseline = "middle";
		ctx.fillText("No Data Available", ctx.canvas.width / 2, ctx.canvas.height / 2);

		document.getElementById('srchEngLegContainer').style.display = 'none';
		return;
	}

	// Generate distinct colors for unknown engines
	var distinctColors = generateDistinctColors(searchEngines.length);
	var unknownEngineIndex = 0;

	document.getElementById('srchEngLegContainer').style.display = 'block';

	searchEngines.forEach(function (engine, i) {
		var color;
		var engineKey = engine.name.toLowerCase().replace(/\s+/g, '').replace(/[^a-z]/g, '');

		// Use predefined colors for known search engines
		if (searchEngineColors[engineKey]) {
			color = searchEngineColors[engineKey];
		} else {
			// Use generated colors for unknown engines
			color = distinctColors[unknownEngineIndex];
			unknownEngineIndex++;
		}

		srh_series.push({
			"label": engine.name,
			"value": engine.value,
			"color": color
		});

		html += '<div class="legend">' +
			'<span class="color" style="background-color: ' + color + ';">&nbsp;&nbsp;</span>' +
			'<span class="name">' + engine.name + '</span>' +
			'<span class="value">' + ahcProNumFormat(engine.value) + '</span>' +
			'</div>';
	});

	html += '<div class="cleaner"></div>';
	container.html(html);
	window.myPie = new Chart(ctx).Pie(srh_series, { responsive: true });
}

function drawBrowsersBieChart(browsersData) {
	var brsBieChartData = [];
	var container = jQuery('#browsersLegContainer');
	var html = '';

	// Browser specific colors
	const browserColors = {
		'chrome': '#4285f4',
		'firefox': '#ff7139',
		'safari': '#1c1c1e',
		'edge': '#0078d4',
		'opera': '#ff1b2d',
		'internet explorer': '#1ebbee',
		'unknown': '#95a5a6',
		'other': '#34495e'
	};

	// Generate distinct colors based on item count
	function generateDistinctColors(count) {
		const colors = [];
		const hueStep = 360 / count;

		for (let i = 0; i < count; i++) {
			const hue = i * hueStep;
			const saturation = 70 + (i % 3) * 10;
			const lightness = 45 + (i % 2) * 10;
			colors.push(`hsl(${hue}, ${saturation}%, ${lightness}%)`);
		}

		return colors;
	}

	var ctx = document.getElementById("brsBiechartContainer").getContext("2d");

	// Check if no data available
	if (browsersData.length == 0) {
		// Clear any existing chart
		ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);

		// Draw "No Data Available" message
		ctx.font = "16px Arial";
		ctx.fillStyle = "#666";
		ctx.textAlign = "center";
		ctx.textBaseline = "middle";
		ctx.fillText("No Data Available", ctx.canvas.width / 2, ctx.canvas.height / 2);

		document.getElementById('browsersLegContainer').style.display = 'none';
		return;
	}

	document.getElementById('browsersLegContainer').style.display = 'block';

	// Filter browsers with non-zero values
	var validBrowsers = browsersData.filter(function (browser) {
		return !isEmpty(Number(browser.hits));
	});

	var distinctColors = generateDistinctColors(validBrowsers.length);

	for (var i = 0; i < browsersData.length; i++) {
		var color;
		var value = Number(browsersData[i].hits);
		var browserKey = browsersData[i].bsr_name.toLowerCase().replace(/\s+/g, '');

		// Use predefined colors for known browsers, otherwise use generated colors
		if (browserColors[browserKey]) {
			color = browserColors[browserKey];
		} else {
			color = distinctColors[i % distinctColors.length];
		}

		brsBieChartData[i] = { label: browsersData[i].bsr_name, value: value, color: color };
		html += (isEmpty(value)) ? '' : '<div class="legend">' +
			'<span class="color" style="background-color: ' + color + ';">&nbsp;&nbsp;</span>' +
			'<span class="name">' + browsersData[i].bsr_name + '</span>' +
			'<span class="value">' + ahcProNumFormat(value) + '</span>' +
			'</div>';
	}
	html += '<div class="cleaner"></div>';
	container.html(html);
	window.myPie = new Chart(ctx).Pie(brsBieChartData, { responsive: true });
}

function drawCountriesPieChart(countriesData) {
	var countriesPieChartData = [];
	var container = jQuery('#countriesLegContainer');
	var html = '';

	// Generate distinct colors based on item count
	function generateDistinctColors(count) {
		const colors = [];
		const hueStep = 360 / count;

		for (let i = 0; i < count; i++) {
			const hue = i * hueStep;
			const saturation = 70 + (i % 3) * 10;
			const lightness = 45 + (i % 2) * 10;
			colors.push(`hsl(${hue}, ${saturation}%, ${lightness}%)`);
		}

		return colors;
	}

	var ctx = document.getElementById("countriesPiechartContainer").getContext("2d");

	// Check if no data available
	if (countriesData.length == 0) {
		// Clear any existing chart
		ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);

		// Draw "No Data Available" message
		ctx.font = "16px Arial";
		ctx.fillStyle = "#666";
		ctx.textAlign = "center";
		ctx.textBaseline = "middle";
		ctx.fillText("No Data Available", ctx.canvas.width / 2, ctx.canvas.height / 2);

		document.getElementById('countriesLegContainer').style.display = 'none';
		return;
	}

	document.getElementById('countriesLegContainer').style.display = 'block';

	// Filter countries with non-zero values
	var validCountries = countriesData.filter(function (country) {
		return !isEmpty(Number(country.visits));
	});

	var distinctColors = generateDistinctColors(validCountries.length);

	for (var i = 0; i < countriesData.length; i++) {
		var color = distinctColors[i % distinctColors.length];
		var value = Number(countriesData[i].visits);

		countriesPieChartData[i] = { label: countriesData[i].ctr_name, value: value, color: color };
		html += (isEmpty(value)) ? '' : '<div class="legend">' +
			'<span class="color" style="background-color: ' + color + ';">&nbsp;&nbsp;</span>' +
			'<span class="name">' + countriesData[i].ctr_name + '</span>' +
			'<span class="value">' + ahcProNumFormat(value) + '</span>' +
			'</div>';
	}
	html += '<div class="cleaner"></div>';
	container.html(html);
	window.myPie = new Chart(ctx).Pie(countriesPieChartData, { responsive: true });
}
function isEmpty(val) {
	return (val == null || val == 0 || val == '' || val == '0');
}

//------------------------------------------------------------------------------
function countVisits(arr) {
	var count = 0;
	for (var i = 0; i < arr.length; i++) {
		count += Number(arr[i]);
	}
	return count;
}
//------------------------------------------------------------------------------

jQuery(document).ready(function () {
	if (!jQuery('#countriesPiechartContainer').length) {
		return;
	}
	//------------------------------------------
	//if(visitsData.success && typeof visitsData.data != 'undefined'){
	var duration = jQuery('#hits-duration').val();

	drawVisitsLineChart(mystart_date, myend_date, '1 day', visitors_data, visits_data, duration);
	//}
	//------------------------------------------
	if (browsersData.success && typeof browsersData.data != 'undefined' && typeof drawBrowsersBieChart === "function") {
		drawBrowsersBieChart(browsersData.data);
	}
	//------------------------------------------
	if (srhEngVisitsData.success && typeof srhEngVisitsData.data != 'undefined' && typeof drawSrhEngVstLineChart === "function") {
		drawSrhEngVstLineChart(srhEngVisitsData);
	}
	//------------------------------------------
	if (countriesData.success && typeof countriesData.data != 'undefined' && typeof drawCountriesPieChart === "function") {
		drawCountriesPieChart(countriesData.data);
	}
	
	if (jQuery('#traffic_by_title').length) {
	// Destroy existing instance if present
	if (jQuery.fn.DataTable.isDataTable('#traffic_by_title')) {
		jQuery('#traffic_by_title').DataTable().destroy();
	}
	
	var trafficTable = jQuery('#traffic_by_title').DataTable({
		"pageLength": 10,
		"searching": true,
		"ordering": false,
		"bLengthChange": false,
		"bFilter": true,
		"bInfo": false,
		"bAutoWidth": false,
		"bJQueryUI": true,
		"processing": true,
		"serverSide": true,
		"deferRender": true,
		"destroy": true,
		ajax: {
			url: ahc_ajax.ajax_url,
			type: 'POST',
			data: function(d) {
				d.action = 'traffic_by_title';
				return d;
			},
			dataSrc: 'data',
			timeout: 60000,
			error: function (xhr, error, thrown) {
				console.error('Traffic by Title AJAX Error:', {
					error: error,
					thrown: thrown,
					status: xhr.status,
					responseText: xhr.responseText
				});
				
				if (error === 'timeout') {
					alert('Request timed out. Please try filtering or search.');
				}
			}
		},
		columns: [
			{ 
				data: 'rank',
				defaultContent: '-',
				width: '5%'
			},
			{ 
				data: 'til_page_title',
				defaultContent: 'No title',
				width: '50%'  // Wider since we removed a column
			},
			{
				data: 'til_hits',
				defaultContent: '0',
				width: '15%',
				render: function (data, type, row) {
					if (type === 'display') {
						var cleanTitle = '';
						if (row.til_page_title) {
							cleanTitle = row.til_page_title.replace(/<[^>]*>/g, '').trim() || 'Unknown Page';
						}

						var postId = row.til_page_id || 0;
						var hits = parseInt(data) || 0;

						return '<div class="ahc-stats-cell">' +
							'<a href="#" class="ahc-stats-number datatable-stats-link" ' +
							'data-post-id="' + postId + '" ' +
							'data-page-title="' + cleanTitle.replace(/"/g, '&quot;') + '">' +
							'<span class="dashicons dashicons-chart-bar"></span>' +
							'<span class="stat-number">' + hits.toLocaleString() + ' hits</span>' +
							'</a>' +
							'</div>';
					}
					return data;
				}
			},
			{ 
				data: 'percent',
				defaultContent: '0%',
				width: '15%'
			},
			// TIME SPENT COLUMN REMOVED
			{ 
				data: 'bounce_rate',
				defaultContent: '0%',
				width: '15%'
			}
		],
		language: {
			searchPlaceholder: "Search by title...",
			processing: "<div class='datatable-loading'><span class='loader'>&nbsp;</span><br>Loading...</div>",
			zeroRecords: "No pages found.",
			emptyTable: "No traffic data available yet.",
			paginate: {
				next: '<i class="dashicons dashicons-arrow-right-alt2"></i>',
				previous: '<i class="dashicons dashicons-arrow-left-alt2"></i>'
			}
		},
		drawCallback: function (settings) {
			if (settings._iDisplayLength > settings.fnRecordsDisplay()) {
				jQuery(settings.nTableWrapper).find('.dataTables_paginate').hide();
			} else {
				jQuery(settings.nTableWrapper).find('.dataTables_paginate').show();
			}
			
			if (!jQuery(document).data('modal-events-bound')) {
				if (typeof bindModalEvents === 'function') {
					bindModalEvents();
					jQuery(document).data('modal-events-bound', true);
				}
			}
		},
		dom: 'Bfrtip',
		buttons: [{
			extend: 'excelHtml5',
			text: '<i class="dashicons dashicons-media-spreadsheet"></i> Export',
			title: "Traffic by Title",
			className: 'btn-excel-export',
			action: function (e, dt, node, config) {
				jQuery("#traffic_by_title").parents(".panelcontent").find(".dataTables_processing").show();

				setTimeout(function () {
					jQuery.ajax({
						url: ahc_ajax.ajax_url,
						type: 'POST',
						data: {
							action: 'traffic_by_title',
							page: 'all',
							search: { value: dt.search() }
						},
						timeout: 120000,
						success: function (res) {
							try {
								var xlsRows = (typeof res === 'string') ? JSON.parse(res) : res;
								if (!Array.isArray(xlsRows)) throw new Error('Invalid data');
								
								var createXLSLFormatObj = [];
								// REMOVED "Time Spent" from header
								var xlsHeader = ["Rank", "Page Title", "Hits", "Visit %", "Bounce Rate"];
								createXLSLFormatObj.push(xlsHeader);

								xlsRows.forEach(function (value) {
									// REMOVED avg_time from export
									createXLSLFormatObj.push([
										value.rank || '-',
										value.clean_title || value.til_page_title || 'No title',
										value.til_hits || 0,
										value.percent || '0%',
										value.bounce_rate || '0%'
									]);
								});

								var filename = "traffic_by_title_" + new Date().toISOString().slice(0,10) + ".xlsx";
								var ws_name = "Traffic Data";
								var wb = XLSX.utils.book_new();
								var ws = XLSX.utils.aoa_to_sheet(createXLSLFormatObj);
								
								// Adjusted column widths (removed time column)
								ws['!cols'] = [
									{wch: 8},  // Rank
									{wch: 50}, // Title
									{wch: 10}, // Hits
									{wch: 10}, // Percent
									{wch: 12}  // Bounce Rate
								];
								
								XLSX.utils.book_append_sheet(wb, ws, ws_name);
								XLSX.writeFile(wb, filename);
								
								console.log('Excel export successful');
							} catch (error) {
								console.error('Excel error:', error);
								alert('Error generating Excel: ' + error.message);
							} finally {
								jQuery("#traffic_by_title").parents(".panelcontent").find(".dataTables_processing").hide();
							}
						},
						error: function (xhr, status, error) {
							console.error('Export error:', {status, error, response: xhr.responseText});
							alert('Export failed: ' + error);
							jQuery("#traffic_by_title").parents(".panelcontent").find(".dataTables_processing").hide();
						}
					});
				}, 100);
			}
		}]
	});
	
	console.log('Traffic by Title table initialized (without Time Spent)');
}

	// Performance: Global variables with lazy initialization
	window.ahcChart = null;
	window.googleChartsLoaded = false;
	window.googleChartsLoading = false;
	window.modalCreated = false;

	// Performance: Efficient event binding with delegation (only bind once)
	function bindModalEvents() {
		// Performance: Unbind existing events to prevent duplicates
		jQuery(document).off('click.ahcModal', '.datatable-stats-link');

		// Performance: Use namespaced events for better control
		jQuery(document).on('click.ahcModal', '.datatable-stats-link', function (e) {
			e.preventDefault();

			var postId = jQuery(this).data('post-id');
			var pageTitle = jQuery(this).data('page-title');

			// Performance: Clean title efficiently
			if (pageTitle.includes('http')) {
				pageTitle = pageTitle.split('http')[0].trim();
			}
			pageTitle = pageTitle.replace(/[\/\s]*$/, '');
			if (!pageTitle || pageTitle.length < 2) {
				pageTitle = 'Page Statistics';
			}

			// Performance: Only create modal when first needed
			if (!window.modalCreated) {
				createStatsModal();
				window.modalCreated = true;
			}

			// Performance: Lazy load Google Charts only when modal is opened
			if (!window.googleChartsLoaded && !window.googleChartsLoading) {
				loadGoogleCharts();
			}

			// Update modal and show
			jQuery('#ahcModalTitle').text('Statistics: ' + pageTitle);
			jQuery('#ahcModalLink').hide();
			jQuery('#ahcHitsModal').data('post-id', postId);
			jQuery('#ahcTimeRange').val('14');

			// Performance: Show modal immediately, load data asynchronously
			jQuery('#ahcHitsModal').show();

			// Performance: Load chart data with debouncing
			clearTimeout(window.chartLoadTimeout);
			window.chartLoadTimeout = setTimeout(function () {
				fetchChartData(postId, '14');
			}, 100);
		});
	}

	// Performance: Optimized chart destroyer
	function destroyChart() {
		if (window.ahcChart) {
			try {
				if (typeof window.ahcChart.clearChart === 'function') {
					window.ahcChart.clearChart();
				}
			} catch (error) {
				// Silent fail - don't log to avoid console spam
			}
			window.ahcChart = null;
		}
	}

	// Performance: Create modal only when needed (lazy loading)
	function createStatsModal() {
		// Performance: Check if already created
		if (jQuery('#ahcHitsModal').length) {
			return;
		}

		var modalHtml = `
	<div id="ahcHitsModal" class="ahc-modal">
		<div class="ahc-modal-content">
			<div class="ahc-modal-header">
				<div class="ahc-modal-title-section">
					<h2 id="ahcModalTitle">Page Statistics</h2>
					<div id="ahcModalLink" class="ahc-modal-link"></div>
				</div>
				<span class="ahc-modal-close">&times;</span>
			</div>
			<div id="ahcStatsSummary" class="ahc-stats-summary"></div>
			<div class="ahc-time-range">
				<label for="ahcTimeRange"><strong>Time Range:</strong></label>
				<select id="ahcTimeRange">
					<option value="7">Last 7 days</option>
					<option value="14" selected>Last 14 days</option>
					<option value="30">Last 30 days</option>
					<option value="this_month">This month</option>
				</select>
			</div>
			<div class="ahc-chart-container">
				<div id="ahcHitsChart" style="width: 100%; height: 400px;"></div>
			</div>
		</div>
	</div>`;

		jQuery('body').append(modalHtml);

		// Performance: Only add CSS once
		if (!jQuery('#ahc-modal-styles').length) {
			addModalStyles();
		}

		// Performance: Bind events with efficient delegation
		bindModalCloseEvents();
	}

	// Performance: Separate CSS loading to avoid re-adding
	function addModalStyles() {
		var styles = `
	<style id="ahc-modal-styles">
		.column-hits { width: 120px !important; text-align: center; }
		.ahc-icon:before {
			content: "\\f185";
			color: #1DAE22;
			font-family: dashicons;
			position: relative;
			top: 3px;
		}
		.ahc-stats-number {
			display: flex;
			flex-direction: column;
			align-items: center;
			text-decoration: none;
			color: #2271b1;
			gap: 2px;
			padding: 4px;
			border-radius: 3px;
			transition: background-color 0.2s;
		}
		.ahc-stats-number:hover {
			background-color: rgba(0,0,0,0.05);
		}
		.stat-number { font-size: 13px; font-weight: 500; }
		.ahc-modal {
			display: none;
			position: fixed;
			z-index: 999999;
			left: 0;
			top: 0;
			width: 100%;
			height: 100%;
			background-color: rgba(0,0,0,0.4);
		}
		.ahc-modal-content {
			background-color: #fff;
			margin: 5% auto;
			padding: 20px;
			border-radius: 4px;
			width: 80%;
			max-width: 800px;
			max-height: 80vh;
			overflow-y: auto;
		}
		.ahc-modal-header {
			display: flex;
			justify-content: space-between;
			align-items: flex-start;
			margin-bottom: 20px;
			border-bottom: 2px solid #f0f0f0;
			padding-bottom: 15px;
		}
		.ahc-modal-title-section {
			flex: 1;
		}
		.ahc-modal-title-section h2 {
			margin: 0 0 8px 0;
			font-size: 22px;
			font-weight: 600;
			color: #2c3e50;
		}
		.ahc-modal-link {
			font-size: 13px;
			color: #7f8c8d;
			font-family: monospace;
			background: #f8f9fa;
			padding: 4px 8px;
			border-radius: 4px;
			border: 1px solid #e9ecef;
			word-break: break-all;
			max-width: 500px;
		}
		.ahc-modal-close {
			cursor: pointer;
			font-size: 24px;
			padding: 8px;
			color: #7f8c8d;
			border-radius: 50%;
			width: 40px;
			height: 40px;
			display: flex;
			align-items: center;
			justify-content: center;
			transition: all 0.2s ease;
			background: #f8f9fa;
			border: 1px solid #e9ecef;
		}
		.ahc-modal-close:hover {
			background: #e74c3c;
			color: white;
			transform: scale(1.1);
		}
		.ahc-chart-container {
			position: relative;
			width: 100%;
			margin-top: 20px;
			background: #fff;
			border: 1px solid #ddd;
			border-radius: 4px;
			padding: 10px;
		}
		.ahc-time-range {
			margin-bottom: 15px;
		}
		.ahc-stats-summary {
			display: grid;
			grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
			gap: 15px;
			margin-bottom: 20px;
			padding: 15px;
			background: #f9f9f9;
			border-radius: 4px;
		}
		.ahc-stat-item {
			text-align: center;
		}
		.ahc-stat-number {
			font-size: 24px;
			font-weight: bold;
			color: #1DAE22;
			display: block;
		}
		.ahc-stat-label {
			font-size: 12px;
			color: #666;
			text-transform: uppercase;
		}
		#traffic_by_title .ahc-stats-cell {
			text-align: center;
		}
	</style>`;

		jQuery('head').append(styles);
	}

	// Performance: Separate modal close event binding
	function bindModalCloseEvents() {
		// Performance: Use namespaced events and efficient delegation
		jQuery(document).off('click.ahcModalClose').on('click.ahcModalClose', '.ahc-modal-close', function () {
			jQuery('#ahcHitsModal').hide();
			destroyChart();
		});

		jQuery(document).off('click.ahcModalOverlay').on('click.ahcModalOverlay', '#ahcHitsModal', function (e) {
			if (e.target === this) {
				jQuery('#ahcHitsModal').hide();
				destroyChart();
			}
		});

		// Performance: Debounced time range change
		jQuery(document).off('change.ahcTimeRange').on('change.ahcTimeRange', '#ahcTimeRange', function () {
			var postId = jQuery('#ahcHitsModal').data('post-id');
			var range = jQuery(this).val();

			clearTimeout(window.timeRangeTimeout);
			window.timeRangeTimeout = setTimeout(function () {
				fetchChartData(postId, range);
			}, 200);
		});
	}

	// Performance: Lazy load Google Charts only when needed
	function loadGoogleCharts() {
		if (window.googleChartsLoaded || window.googleChartsLoading) {
			return;
		}

		window.googleChartsLoading = true;

		// Performance: Check if already loaded
		if (typeof google !== 'undefined' && google.charts) {
			window.googleChartsLoaded = true;
			window.googleChartsLoading = false;
			return;
		}

		// Performance: Load from CDN with error handling
		var script = document.createElement('script');
		script.src = 'https://www.gstatic.com/charts/loader.js';
		script.async = true;
		script.onload = function () {
			google.charts.load('current', {
				'packages': ['corechart'],
				'callback': function () {
					window.googleChartsLoaded = true;
					window.googleChartsLoading = false;
				}
			});
		};
		script.onerror = function () {
			window.googleChartsLoading = false;
			console.error('Failed to load Google Charts');
		};
		document.head.appendChild(script);
	}

	// Performance: Optimized chart data fetching with caching
	var chartDataCache = {};
	function fetchChartData(postId, range) {
		// Performance: Cache key for avoiding duplicate requests
		var cacheKey = postId + '_' + range;
		var now = Date.now();

		// Performance: Use cached data if less than 5 minutes old
		if (chartDataCache[cacheKey] && (now - chartDataCache[cacheKey].timestamp) < 300000) {
			var cachedData = chartDataCache[cacheKey].data;
			updateSummaryStats(cachedData.summary);
			createChart(cachedData.chart);
			return;
		}

		// Performance: Abort previous request if still pending
		if (window.currentChartRequest) {
			window.currentChartRequest.abort();
		}

		window.currentChartRequest = jQuery.ajax({
			url: ajaxurl || ahc_ajax.ajax_url,
			method: "POST",
			timeout: 15000,
			data: {
				action: "ahcpro_get_hits_data",
				post_id: postId,
				range: range
			},
			beforeSend: function () {
				jQuery("#ahcHitsChart").html("<div style='text-align:center;padding:50px;color:#666;'>Loading chart...</div>");
			},
			success: function (response) {
				window.currentChartRequest = null;

				if (!response.success) {
					jQuery("#ahcHitsChart").html("<div style='text-align:center;padding:50px;color:red;'>Error loading data</div>");
					return;
				}

				var data = response.data;

				// Performance: Cache the response
				chartDataCache[cacheKey] = {
					data: data,
					timestamp: now
				};

				// Performance: Clean old cache entries (keep last 10)
				var cacheKeys = Object.keys(chartDataCache);
				if (cacheKeys.length > 10) {
					var oldestKey = cacheKeys.reduce(function (oldest, key) {
						return chartDataCache[key].timestamp < chartDataCache[oldest].timestamp ? key : oldest;
					});
					delete chartDataCache[oldestKey];
				}

				updateSummaryStats(data.summary);

				// Performance: Create chart when Google Charts is ready
				if (window.googleChartsLoaded) {
					createChart(data.chart);
				} else {
					var checkInterval = setInterval(function () {
						if (window.googleChartsLoaded) {
							clearInterval(checkInterval);
							createChart(data.chart);
						}
					}, 100);

					setTimeout(function () {
						clearInterval(checkInterval);
						if (!window.googleChartsLoaded) {
							jQuery("#ahcHitsChart").html("<div style='text-align:center;padding:50px;color:red;'>Chart library failed to load</div>");
						}
					}, 10000);
				}
			},
			error: function (xhr, status, error) {
				window.currentChartRequest = null;
				if (status !== 'abort') {
					jQuery("#ahcHitsChart").html("<div style='text-align:center;padding:50px;color:red;'>Failed to load data</div>");
				}
			}
		});
	}

	// Performance: Optimized chart creation
	function createChart(chartData) {
		if (!chartData || !Array.isArray(chartData) || chartData.length === 0) {
			jQuery("#ahcHitsChart").html("<div style='text-align:center;padding:50px;color:orange;'>No data available for chart</div>");
			return;
		}

		destroyChart();

		try {
			// Performance: Pre-allocate array size
			var dataArray = new Array(chartData.length + 1);
			dataArray[0] = ['Date', 'Hits', 'Visitors'];

			// Performance: Use for loop instead of forEach for better performance
			for (var i = 0; i < chartData.length; i++) {
				var item = chartData[i];
				var date = item.date || 'Unknown';
				var hits = parseInt(item.hits) || 0;
				var visitors = parseInt(item.visitors) || 0;

				var dateObj = new Date(date);
				var formattedDate = dateObj.toLocaleDateString('en-US', {
					month: 'short',
					day: 'numeric'
				});

				dataArray[i + 1] = [formattedDate, hits, visitors];
			}

			var data = google.visualization.arrayToDataTable(dataArray);

			var options = {
				title: 'Page Traffic Over Time',
				titleTextStyle: {
					fontSize: 16,
					bold: true,
					color: '#333'
				},
				hAxis: {
					title: 'Date',
					titleTextStyle: {
						fontSize: 12,
						bold: true
					},
					textStyle: {
						fontSize: 11
					}
				},
				vAxis: {
					title: 'Count',
					titleTextStyle: {
						fontSize: 12,
						bold: true
					},
					minValue: 0,
					format: 'short',
					viewWindow: {
						min: 0
					},
					format: '#',
					gridlines: {
						count: -1
					}
				},
				legend: {
					position: 'top',
					alignment: 'center',
					textStyle: {
						fontSize: 12
					}
				},
				colors: ['#1DAE22', '#0073aa'],
				lineWidth: 3,
				pointSize: 6,
				pointShape: 'circle',
				backgroundColor: '#fff',
				chartArea: {
					left: 80,
					top: 80,
					width: '80%',
					height: '65%'
				},
				animation: {
					startup: true,
					duration: 1000,
					easing: 'out'
				},
				curveType: 'function',
				explorer: {
					actions: ['dragToZoom', 'rightClickToReset'],
					axis: 'horizontal',
					keepInBounds: true
				},
				series: {
					0: {
						color: '#1DAE22',
						lineWidth: 3,
						pointSize: 6
					},
					1: {
						color: '#0073aa',
						lineWidth: 3,
						pointSize: 6
					}
				}
			};

			var chartDiv = document.getElementById('ahcHitsChart');
			window.ahcChart = new google.visualization.LineChart(chartDiv);
			window.ahcChart.draw(data, options);

		} catch (error) {
			jQuery("#ahcHitsChart").html("<div style='text-align:center;padding:50px;color:red;'>Error creating chart: " + error.message + "</div>");
		}
	}

	// Performance: Optimized summary stats update
	function updateSummaryStats(summary) {
		var html = `
	<div class="ahc-stat-item">
		<span class="ahc-stat-number">${summary.total_hits.toLocaleString()}</span>
		<span class="ahc-stat-label">Total Hits</span>
	</div>
	<div class="ahc-stat-item">
		<span class="ahc-stat-number">${summary.unique_visitors.toLocaleString()}</span>
		<span class="ahc-stat-label">Unique Visitors</span>
	</div>
	<div class="ahc-stat-item">
		<span class="ahc-stat-number">${summary.avg_daily_hits.toLocaleString()}</span>
		<span class="ahc-stat-label">Avg Daily Hits</span>
	</div>
	<div class="ahc-stat-item">
		<span class="ahc-stat-number">${summary.peak_day_hits.toLocaleString()}</span>
		<span class="ahc-stat-label">Peak Day</span>
	</div>
	`;
		jQuery("#ahcStatsSummary").html(html);
	}

	// Performance: Initialize only essential components immediately
	jQuery(document).ready(function ($) {
		// Performance: Only bind initial events, create modal and load charts on demand
		bindModalEvents();

		// Performance: Clean up on page unload
		jQuery(window).on('beforeunload', function () {
			// Cancel any pending requests
			if (window.currentChartRequest) {
				window.currentChartRequest.abort();
			}
			// Clear timeouts
			clearTimeout(window.chartLoadTimeout);
			clearTimeout(window.timeRangeTimeout);
			// Clear cache
			chartDataCache = {};
		});
	});
	if (jQuery('#lasest_search_words').length) {
		latestSearchTable();
	}
	// Initialize table when ready
	if (jQuery('#traffic_sources_table').length && jQuery('#traffic_sources_table tbody tr').length > 0) {
		jQuery('#traffic_sources_table').DataTable({
			"pageLength": 10,
			"searching": false,
			"ordering": true,
			"bLengthChange": false,
			"bFilter": true,
			"bInfo": false,
			"bJQueryUI": true,
			"order": [[0, "asc"]],
			language: {
				"zeroRecords": "No traffic sources data available.",
				paginate: {
					next: '<i class="dashicons dashicons-arrow-right-alt2"></i>',
					previous: '<i class="dashicons dashicons-arrow-left-alt2"></i>'
				}
			},
			"fnDrawCallback": function (oSettings) {
				if (oSettings._iDisplayLength > oSettings.fnRecordsDisplay()) {
					jQuery(oSettings.nTableWrapper).find('.dataTables_paginate').hide();
				}
			},
			columnDefs: [
				{
					targets: [1, 3],
					orderable: false
				}
			],
			dom: 'Bfrtip',
			buttons: [{
				extend: 'excelHtml5',
				title: "Traffic Sources Report",
				filename: "Traffic_Sources_Report",
				exportOptions: {
					columns: [0, 1, 2, 3],
					format: {
						body: function (data, row, col, node) {
							// Strip HTML tags and clean text
							const tempDiv = document.createElement("div");
							tempDiv.innerHTML = data;
							let cleanText = tempDiv.textContent || tempDiv.innerText || "";

							// Clean up whitespace
							cleanText = cleanText.replace(/\s+/g, ' ').trim();

							return cleanText;
						}
					}
				}
			}]
		});
	}
	function latestSearchTable() {
		jQuery('#lasest_search_words_wrapper').html(`
			<div class="panel" style="border-radius: 7px !important; border: 0 !important; box-shadow: 0 4px 25px 0 rgb(168 180 208 / 10%) !important;">
				<h2 class="box-heading" style="border-radius: 7px 7px 0 0 !important; padding:12px 15px !important; border-bottom:0 !important">
					Latest Search Words<span class="search_data"><a href="#" class="dashicons dashicons-search" title="Search"></a></span><span class="export_data">
						<a href="#" class="dashicons dashicons-media-spreadsheet" title="Export to Excel"></a>
					</span>
				</h2>
				<div class="panelcontent" style="border-radius:0 0 7px 7px !important; padding-right: 50px; text-align: center; padding: 40px 20px;">
					<span class="spinner is-active" style="float: none; margin: 0 10px 0 0;"></span>
					Checking Search Console connection...
				</div>
			</div>
		`);

		jQuery.ajax({
			url: ahc_ajax.ajax_url,
			method: 'POST',
			data: {
				action: 'test_gsc_connection_table',
			},
			success: function (response) {
				if (response.success) {
					// ✅ Connected, initialize the table
					initializeSearchTable();
				} else {
					// ❌ Not connected - show error with proper panel structure
					var errorMessage = response.data && response.data.message ? response.data.message : 'Connection failed';
					showErrorInPanel(errorMessage);
				}
			},
			error: function () {
				showErrorInPanel('Could not verify the connection to Google Search Console. Please try again or check your settings.');
			}
		});
	}
	function showErrorInPanel(message) {
		jQuery('#lasest_search_words_wrapper').html(`
			<div class="panel" style="border-radius: 7px !important; border: 0 !important; box-shadow: 0 4px 25px 0 rgb(168 180 208 / 10%) !important;">
				<h2 class="box-heading" style="border-radius: 7px 7px 0 0 !important; padding:12px 15px !important; border-bottom:0 !important">
					Latest Search Words<span class="search_data"><a href="#" class="dashicons dashicons-search" title="Search"></a></span><span class="export_data">
						<a href="#" class="dashicons dashicons-media-spreadsheet" title="Export to Excel"></a>
					</span>
				</h2>
				<div class="panelcontent" style="border-radius:0 0 7px 7px !important; padding-right: 50px;">
					<div style="padding: 30px 20px; text-align: center; background: #fff; border-left: 4px solid #dc3545;">
						<div style="font-size: 48px; margin-bottom: 15px; color: #dc3545;">⚠️</div>
						<div style="font-size: 14px; font-weight: 400; color: #721c24; margin-bottom: 10px;">
							${message}
						</div>
					</div>
				</div>
			</div>
		`);
	}
	function latestSearchTable() {
		// Show loading state with proper panel structure
		jQuery('#lasest_search_words_wrapper').html(`
			<div class="panel" style="border-radius: 7px !important; border: 0 !important; box-shadow: 0 4px 25px 0 rgb(168 180 208 / 10%) !important;">
				<h2 class="box-heading" style="border-radius: 7px 7px 0 0 !important; padding:12px 15px !important; border-bottom:0 !important">
					Latest Search Words<span class="search_data"><a href="#" class="dashicons dashicons-search" title="Search"></a></span><span class="export_data">
						<a href="#" class="dashicons dashicons-media-spreadsheet" title="Export to Excel"></a>
					</span>
				</h2>
				<div class="panelcontent" style="border-radius:0 0 7px 7px !important; padding-right: 50px; text-align: center; padding: 40px 20px;">
					<span class="spinner is-active" style="float: none; margin: 0 10px 0 0;"></span>
					Checking Search Console connection...
				</div>
			</div>
		`);

		jQuery.ajax({
			url: ahc_ajax.ajax_url,
			method: 'POST',
			data: {
				action: 'test_gsc_connection_table',
			},
			success: function (response) {
				if (response.success) {
					// ✅ Connected, initialize the table
					initializeSearchTable();
				} else {
					// ❌ Not connected - show error with proper panel structure
					var errorMessage = response.data && response.data.message ? response.data.message : 'Connection failed';
					showErrorInPanel(errorMessage);
				}
			},
			error: function () {
				showErrorInPanel('Could not verify the connection to Google Search Console. Please try again or check your settings.');
			}
		});
	}


	function initializeSearchTable() {
		jQuery('#lasest_search_words_wrapper').html(`
			<div class="panel" style="border-radius: 7px !important; border: 0 !important; box-shadow: 0 4px 25px 0 rgb(168 180 208 / 10%) !important;">
				<h2 class="box-heading" style="border-radius: 7px 7px 0 0 !important; padding:12px 15px !important; border-bottom:0 !important">
					Latest Search Words<span class="search_data"><a href="#" class="dashicons dashicons-search" title="Search"></a></span><span class="export_data">
						<a href="#" class="dashicons dashicons-media-spreadsheet" title="Export to Excel"></a>
					</span>
				</h2>
				<div class="search-panel ${jQuery('#from_dt').val() || jQuery('#to_dt').val() ? 'open' : ''}">
					<form method="post" class="search_frm">
						<label>Search in Time Frame: </label>
						<input type="hidden" name="page" value="ahc_hits_counter_menu_pro" />
						<input type="hidden" name="section" value="lastest_search" />
						<input type="text" readonly="readonly" placeholder="From Date" class="ahc_clear" name="from_dt" id="from_dt" autocomplete="off" value="${jQuery('#from_dt').val() || ''}" />
						<input type="text" readonly="readonly" placeholder="To Date" class="ahc_clear" name="to_dt" id="to_dt" autocomplete="off" value="${jQuery('#to_dt').val() || ''}" />
						<input type="submit" class="button button-primary" />
						<input type="button" class="button button-primary clear_form" value="Clear" />
					</form>
				</div>
				<div class="panelcontent" style="border-radius:0 0 7px 7px !important; padding-right: 50px;">
					<table width="100%" border="0" cellspacing="0" id="lasest_search_words">
						<thead>
							<tr>
								<th width="25%">Country/SE/Browser</th>
								<th width="65%">Country/SE/Browser</th>
								<th width="65%">Keyword</th>
								<th width="10%" class='text-center'>Date</th>
							</tr>
						</thead>
						<tbody></tbody>
					</table>
				</div>
			</div>
		`);

		// Add click handler for search toggle
		jQuery('#lasest_search_words_wrapper .search_data a').click(function (e) {
			e.preventDefault();
			jQuery('.search-panel').toggleClass('open');
		});

		// Initialize DataTable exactly like your traffic sources table
		jQuery('#lasest_search_words').DataTable({
			"pageLength": 10,
			"searching": false,
			"ordering": false,
			"bLengthChange": false,
			"bFilter": true,
			"bInfo": false,
			"bJQueryUI": true,
			"processing": true,
			"serverSide": true,
			ajax: {
				url: ahc_ajax.ajax_url + '?action=latest_search_words&fdt=' + jQuery("#from_dt").val() + "&tdt=" + jQuery("#to_dt").val(),
				dataSrc: function (json) {
					// Handle error response format
					if (json.error && !json.success) {
						setTimeout(function () {
							showErrorInPanel(json.message);
						}, 100);
						return [];
					}
					return json.data || [];
				},
				error: function (xhr, error, code) {
					setTimeout(function () {
						showErrorInPanel('There was an error loading the search console data. Please try refreshing the page or check your connection settings.');
					}, 100);
				}
			},
			columnDefs: [{
				targets: 1,
				className: 'hide'
			}],
			columns: [
				{ data: 'img' },
				{ data: 'csb' },
				{ data: 'keyword' },
				{ data: 'dt' },
			],
			language: {
				"zeroRecords": "No search data available yet. This is normal for new sites - Google needs 1-3 days to collect search data.",
				paginate: {
					next: '<i class="dashicons dashicons-arrow-right-alt2"></i>',
					previous: '<i class="dashicons dashicons-arrow-left-alt2"></i>'
				}
			},
			"fnDrawCallback": function (oSettings) {
				if (oSettings._iDisplayLength > oSettings.fnRecordsDisplay()) {
					jQuery(oSettings.nTableWrapper).find('.dataTables_paginate').hide();
				}
			},
			dom: 'Bfrtip',
			buttons: [{
				extend: 'excelHtml5',
				title: "Latest Search Words Report",
				filename: "Latest_Search_Words_Report",
				exportOptions: {
					columns: [1, 2, 3],
					format: {
						body: function (data, row, col, node) {
							// Strip HTML tags and clean text
							const tempDiv = document.createElement("div");
							tempDiv.innerHTML = data;
							let cleanText = tempDiv.textContent || tempDiv.innerText || "";

							// Clean up whitespace
							cleanText = cleanText.replace(/\s+/g, ' ').trim();

							return cleanText;
						}
					}
				}
			}]
		});

		jQuery('#lasest_search_words_wrapper .export_data a').click(function (e) {
			e.preventDefault();
			// Find the specific export button for THIS table only
			jQuery('#lasest_search_words').closest('.dataTables_wrapper').find('.dt-buttons .buttons-excel').click();
		});
	}



	if (jQuery('#traffic_by_countries').length) {
		jQuery('#traffic_by_countries').DataTable({
			"pageLength": 10,
			"searching": false,
			"ordering": false,
			"bLengthChange": false,
			"bFilter": true,
			"bInfo": false,
			"bAutoWidth": false,
			"bJQueryUI": true,
			"processing": true,
			"serverSide": true,
			ajax: ahc_ajax.ajax_url + '?action=traffic_by_countries',
			dataSrc: 'data',
			columns: [
				{ data: 'rank' },
				{ data: 'flag' },
				{ data: 'ctr_name' },
				{ data: 'visitors', render: function(d) { return ahcProNumFormat(d); } },
				{ data: 'visits', render: function(d) { return ahcProNumFormat(d); } }
			],
			language: {
				processing: "<span class='loader'>&nbsp;</span>",
				"zeroRecords": "No data available.",
				paginate: {
					next: '<i class="dashicons dashicons-arrow-right-alt2"></i>',
					previous: '<i class="dashicons dashicons-arrow-left-alt2"></i>'
				}
			},
			"fnDrawCallback": function (oSettings) {
				if (oSettings._iDisplayLength > oSettings.fnRecordsDisplay()) {
					jQuery(oSettings.nTableWrapper).find('.dataTables_paginate').hide();
				}
			},
			dom: 'Bfrtip',
			buttons: [{
				extend: 'excelHtml5',
				title: "",
				action: function (e, dt, node, config) {
					jQuery("#traffic_by_countries").parents(".panelcontent").find(".dataTables_processing").show();
					jQuery.ajax({
						url: ahc_ajax.ajax_url + '?action=traffic_by_countries&page=all',
						data: dt.ajax.params(),
						success: function (res, status, xhr) {
							//console.log(res);

							var createXLSLFormatObj = [];

							/* XLS Head Columns */
							var xlsHeader = ["Rank", "Country", "Visitors", "Visits"];

							/* XLS Rows Data */
							var xlsRows = JSON.parse(res);

							createXLSLFormatObj.push(xlsHeader);
							jQuery.each(xlsRows, function (index, value) {
								var innerRowData = [];
								jQuery.each(value, function (ind, val) {
									innerRowData.push(val);
								});
								createXLSLFormatObj.push(innerRowData);
							});
							jQuery("#traffic_by_countries").parents(".panelcontent").find(".dataTables_processing").hide();

							/* File Name */
							var filename = "traffic_by_countries.xlsx";

							/* Sheet Name */
							var ws_name = "sheet1";

							if (typeof console !== 'undefined') console.log(new Date());
							var wb = XLSX.utils.book_new(),
								ws = XLSX.utils.aoa_to_sheet(createXLSLFormatObj);

							/* Add worksheet to workbook */
							XLSX.utils.book_append_sheet(wb, ws, ws_name);

							/* Write workbook and Download */
							if (typeof console !== 'undefined') console.log(new Date());
							XLSX.writeFile(wb, filename);
							if (typeof console !== 'undefined') console.log(new Date());

						}
					})
				},
				exportOptions: {
					columns: [0, 2, 3, 4]
				},
			}]
		});
	}
	if (jQuery('#top_refering_sites').find("tr").length > 1) {
		jQuery('#top_refering_sites').DataTable({
			"pageLength": 10,
			"searching": false,
			"ordering": false,
			"bLengthChange": false,
			"bFilter": true,
			"bInfo": false,
			"bAutoWidth": false,
			language: {
				paginate: {
					next: '<i class="dashicons dashicons-arrow-right-alt2"></i>',
					previous: '<i class="dashicons dashicons-arrow-left-alt2"></i>'
				}
			},
			"fnDrawCallback": function (oSettings) {
				if (oSettings._iDisplayLength > oSettings.fnRecordsDisplay()) {
					jQuery(oSettings.nTableWrapper).find('.dataTables_paginate').hide();
				}
			},
			dom: 'Bfrtip',
			buttons: [{
				extend: 'excelHtml5',
				title: "Top Referring Sites", // This will be the sheet name
				filename: "top_referring_sites" // This will be the file name
			}]
		});
	}
	if (jQuery('#recent_visit_by_ip').length) {
		recentVisitorByIPTable();
	}



	if (jQuery('#visit_time_graph_table').length) {
		visitTimeGraphTable();
	}
	function recentVisitorByIPTable() {
		// Wait a bit for DOM to be fully ready
		setTimeout(function() {
			initializeTable();
		}, 100);
	}
	
	function initializeTable() {
		// Check if table element exists
		if (jQuery('#recent_visit_by_ip').length === 0) {
			return;
		}
	
		// Wait for DOM to be ready and find form elements
		function getFormValues() {
			// More comprehensive search for form elements
			var year = '';
			var month = '';
			var ip = '';
			
			// Find year element
			var yearElement = null;
			if (jQuery("#ahc_visitor_year").length) {
				yearElement = jQuery("#ahc_visitor_year");
			} else if (jQuery("#year").length) {
				yearElement = jQuery("#year");
			} else if (jQuery("select[name='year']").length) {
				yearElement = jQuery("select[name='year']");
			} else if (jQuery(".search_frm select").length) {
				yearElement = jQuery(".search_frm select").first();
			} else {
				var allSelects = jQuery("select");
				if (allSelects.length >= 1) {
					yearElement = allSelects.eq(0);
				}
			}
			
			// Find month element
			var monthElement = null;
			if (jQuery("#ahc_visitor_month").length) {
				monthElement = jQuery("#ahc_visitor_month");
			} else if (jQuery("#month").length) {
				monthElement = jQuery("#month");
			} else if (jQuery("select[name='month']").length) {
				monthElement = jQuery("select[name='month']");
			} else if (jQuery(".search_frm select").length >= 2) {
				monthElement = jQuery(".search_frm select").eq(1);
			} else {
				var allSelects = jQuery("select");
				if (allSelects.length >= 2) {
					monthElement = allSelects.eq(1);
				}
			}
			
			// Find IP element
			var ipElement = null;
			if (jQuery("#ahc_visitor_ip_addr").length) {
				ipElement = jQuery("#ahc_visitor_ip_addr");
			} else if (jQuery("#ip_addr").length) {
				ipElement = jQuery("#ip_addr");
			} else if (jQuery("input[name='ip_addr']").length) {
				ipElement = jQuery("input[name='ip_addr']");
			} else if (jQuery(".search_frm input[type='text']").length) {
				ipElement = jQuery(".search_frm input[type='text']").first();
			} else {
				var allInputs = jQuery("input[type='text']");
				if (allInputs.length >= 1) {
					ipElement = allInputs.first();
				}
			}
			
			// Get values with null checks
			if (yearElement && yearElement.length) {
				year = yearElement.val() || '';
			}
			
			if (monthElement && monthElement.length) {
				month = monthElement.val() || '';
			}
			
			if (ipElement && ipElement.length) {
				ip = ipElement.val() || '';
			}
			
			return { year: year, month: month, ip: ip };
		}
	
		// Initialize DataTable with proper search functionality
		var table = jQuery('#recent_visit_by_ip').DataTable({
			"pageLength": 10,
			"searching": false,
			"ordering": false,
			"bLengthChange": false,
			"bFilter": false,
			"bInfo": false,
			"bAutoWidth": false,
			"bJQueryUI": true,
			"processing": true,
			"serverSide": true,
			"lengthMenu": [[10, 25, 50, -1], [10, 25, 50, "All"]],
			ajax: {
				url: ahc_ajax.ajax_url + '?action=recent_visitor_by_ip',
				type: 'GET',
				data: function(d) {
					var formValues = getFormValues();
					
					// Add the form values
					d.year = formValues.year;
					d.month = formValues.month;
					d.ip = formValues.ip;
					
					return d;
				},
				dataSrc: 'data',
				error: function(xhr, error, thrown) {
					// Silent error handling
				}
			},
			columns: [
				{ data: 'hit_ip_address' },
				{ data: 'ctr_name' },
				{ data: 'time' },
				{ 
					data: 'duration',
					defaultContent: '00:00:01'
				},
				{
					data: 'day_hits',
					render: function (data, type, row, meta) {
						if (typeof data === 'string' && data.includes('<button')) {
							var buttonHtml = data;
							buttonHtml = buttonHtml.replace('<button', '<button ' +
								'data-time="' + (row.time || '') + '" ' +
								'data-ctr-name="' + (row.ctr_name || '') + '" ' +
								'data-ctr-code="' + (row.ctr_internet_code || 'eg') + '" ' +
								'data-city="' + (row.ahc_city || '') + '" ' +
								'data-region="' + (row.ahc_region || '') + '"'
							);
							return buttonHtml;
						}
						return data;
					}
				}
			],
			language: {
				processing: "<span class='loader'>&nbsp;</span>",
				"zeroRecords": "No data available.",
				paginate: {
					next: '<i class="dashicons dashicons-arrow-right-alt2"></i>',
					previous: '<i class="dashicons dashicons-arrow-left-alt2"></i>'
				}
			},
			"fnDrawCallback": function (oSettings) {
				if (oSettings._iDisplayLength > oSettings.fnRecordsDisplay()) {
					jQuery(oSettings.nTableWrapper).find('.dataTables_paginate').hide();
				}
			},
			dom: 'Bfrtip',
			buttons: [{
				extend: 'excelHtml5',
				title: "",
				action: function (e, dt, node, config) {
					jQuery("#recent_visit_by_ip").parents(".panelcontent").find(".dataTables_processing").show();
					
					// Get current search parameters using the robust function
					var formValues = getFormValues();
					
					// Make AJAX call for export with all data
					jQuery.ajax({
						url: ahc_ajax.ajax_url + '?action=recent_visitor_by_ip&page=all',
						type: 'GET',
						data: {
							year: formValues.year,
							month: formValues.month,
							ip: formValues.ip
						},
						success: function (res) {
							try {
								var response = typeof res === 'string' ? JSON.parse(res) : res;
								processExportData(response.data || []);
							} catch (error) {
								alert('Export failed. Please try again.');
								jQuery("#recent_visit_by_ip").parents(".panelcontent").find(".dataTables_processing").hide();
							}
						},
						error: function(xhr, status, error) {
							alert('Export failed. Please try again.');
							jQuery("#recent_visit_by_ip").parents(".panelcontent").find(".dataTables_processing").hide();
						}
					});
					
					function processExportData(data) {
						try {
							var columnsToExport = ["hit_ip_address", "ctr_name", "time", "duration", "day_hits"];
							var columnHeaders = ["IP Address", "Location", "Time", "Duration", "Day Hits"];
	
							var values = data.map(function (item) {
								return columnsToExport.map(function (column) {
									if (column === 'day_hits') {
										if (typeof item[column] === 'string' && item[column].includes('<button')) {
											var match = item[column].match(/>(\d+)</);
											return match ? match[1] : '0';
										}
										return item[column] || '0';
									}
									if (column === 'ctr_name') {
										if (typeof item[column] === 'string') {
											return item[column].replace(/<[^>]*>/g, '');
										}
										return item[column] || '';
									}
									if (column === 'duration') {
										if (typeof item[column] === 'string' && item[column].includes(':')) {
											return item[column];
										}
										if (typeof item[column] === 'number' || !isNaN(item[column])) {
											var totalSeconds = parseInt(item[column]) || 0;
											var hours = Math.floor(totalSeconds / 3600);
											var minutes = Math.floor((totalSeconds % 3600) / 60);
											var seconds = totalSeconds % 60;
											return String(hours).padStart(2, '0') + ':' + 
												   String(minutes).padStart(2, '0') + ':' + 
												   String(seconds).padStart(2, '0');
										}
										return item[column] || '00:00:01';
									}
									return item[column] || '';
								});
							});
	
							var workbook = XLSX.utils.book_new();
							var worksheet = XLSX.utils.aoa_to_sheet([columnHeaders].concat(values));
							
							worksheet['!cols'] = [
								{wch: 15}, // IP Address
								{wch: 30}, // Location
								{wch: 20}, // Time
								{wch: 12}, // Duration
								{wch: 10}  // Day Hits
							];
							
							XLSX.utils.book_append_sheet(workbook, worksheet, 'Recent Visitors');
							XLSX.writeFile(workbook, 'recent_visitors_by_ip.xlsx');
	
						} catch (error) {
							alert('Export failed. Please check console for details.');
						} finally {
							jQuery("#recent_visit_by_ip").parents(".panelcontent").find(".dataTables_processing").hide();
						}
					}
				}
			}]
		});
	
		// Function to reset form values
		function resetFormValues() {
			var currentYear = new Date().getFullYear();
			var currentMonth = (new Date().getMonth() + 1).toString().padStart(2, '0');
			
			// Try multiple selectors to find and reset form elements
			var yearElements = jQuery("#ahc_visitor_year, #year, select[name='year'], .search_frm select").first();
			var monthElements = jQuery("#ahc_visitor_month, #month, select[name='month'], .search_frm select").eq(1);
			var ipElements = jQuery("#ahc_visitor_ip_addr, #ip_addr, input[name='ip_addr'], .search_frm input[type='text']").first();
			
			if (yearElements.length) yearElements.val(currentYear);
			if (monthElements.length) monthElements.val(currentMonth);
			if (ipElements.length) ipElements.val('');
		}
	
		// Use event delegation for form submission - cast a wider net
		jQuery(document).on('submit', '#ahc_visitor_search_form, .search_frm, form', function(e) {
			// Only handle forms related to our table
			if (jQuery(this).closest('.panel').find('#recent_visit_by_ip').length === 0) {
				return; // Not our form, let it proceed normally
			}
			
			e.preventDefault();
			
			var formValues = getFormValues();
			
			// Reload the DataTable with new parameters
			table.ajax.reload(null, false);
			
			return false;
		});
	
		// Backup: Handle submit button click directly
		jQuery(document).on('click', 'input[type="submit"], button[type="submit"]', function(e) {
			// Only handle buttons in forms related to our table
			if (jQuery(this).closest('.panel').find('#recent_visit_by_ip').length === 0) {
				return; // Not our button, let it proceed normally
			}
			
			e.preventDefault();
			
			var formValues = getFormValues();
			
			// Reload the DataTable directly
			table.ajax.reload(null, false);
			
			return false;
		});
	
		// Handle clear button with multiple selectors
		jQuery(document).on('click', '.ahc_visitor_clear_form, .clear_form, input[value="Clear"], button[value="Clear"]', function(e) {
			// Only handle clear buttons related to our table
			if (jQuery(this).closest('.panel').find('#recent_visit_by_ip').length === 0) {
				return; // Not our button, let it proceed normally
			}
			
			e.preventDefault();
			
			resetFormValues();
			
			// Reload table with cleared filters
			table.ajax.reload(null, false);
			
			// Close the search panel
			jQuery('.search-panel').removeClass('open');
		});
	
		// Handle search panel toggle - make it specific to this table's search icon
		jQuery('#recent_visit_by_ip').closest('.panel').find('.search_data a').on('click', function(e) {
			e.preventDefault();
			var searchPanel = jQuery(this).closest('.panel').find('.search-panel');
			searchPanel.toggleClass('open');
		});
	
		// Modal functionality (keeping your existing modal code)
		var modalDataCache = {};
	
		jQuery(document).on('click', '[data-target="#DayHitsModal"]', function (event) {
			event.preventDefault();
		
			var button = jQuery(this);
			var modal = jQuery('#DayHitsModal');
			var table = jQuery('#recent_visit_by_ip').DataTable();
			var row = table.row(button.closest('tr'));
			var rowData = row.data();
			
			var ip = button.data('hitipaddress') || '';
			var duration = rowData.duration || '00:00:00';
			var time = button.data('time') || '';
			var hitdate = button.data('hitdate') || '';
			var hitcountry = button.data('hitcountry') || '';
			var ctrCode = button.data('ctr-code') || 'eg';
			var ctrName = button.data('ctr-name') || '';
			var city = button.data('city') || '';
			var region = button.data('region') || '';
		
			var country = 'Unknown';
			var cityName = 'Unknown';
			var flag = ctrCode.toLowerCase() || 'eg';
		
			if (hitcountry) {
				var parts = hitcountry.split('-');
				if (parts.length >= 2) {
					country = parts[0].trim();
					cityName = parts[1].trim();
				}
			} else if (ctrName) {
				var cleanText = ctrName.replace(/<[^>]*>/g, '');
				var locationParts = cleanText.split(',');
				if (locationParts.length >= 2) {
					country = locationParts[0].trim();
					cityName = locationParts[1].trim();
				}
			}
		
			if (cityName === 'Unknown' && city) {
				cityName = city;
			}
		
			modal.modal('show');
			modal.find('.modal-title').text('IP Tracking - ' + ip);
		
			var loadingHtml = `
				<div class="loading-container" style="text-align: center; padding: 40px;">
					<div class="spinner" style="border: 4px solid #f3f3f3; border-top: 4px solid #3498db; border-radius: 50%; width: 50px; height: 50px; animation: spin 1s linear infinite; margin: 0 auto 20px;"></div>
					<p>Loading visitor data...</p>
					<style>
						@keyframes spin {
							0% { transform: rotate(0deg); }
							100% { transform: rotate(360deg); }
						}
					</style>
				</div>
			`;
		
			modal.find('.modal-body').html(loadingHtml);
		
			var cacheKey = ip + '_' + hitdate;
		
			if (modalDataCache[cacheKey]) {
				displayModalContent(modalDataCache[cacheKey], ip, duration, cityName, country, flag);
				return;
			}
		
			jQuery.ajax({
				url: ahc_ajax.ajax_url + '?action=ahcpro_get_visitor_path&_cb=' + Date.now(),
				type: 'post',
				dataType: 'json',
				data: {
					hitipaddress: ip,
					hitdate: hitdate
				},
				timeout: 15000,
				success: function (response) {
					modalDataCache[cacheKey] = response;
					displayModalContent(response, ip, duration, cityName, country, flag);
				},
				error: function (xhr, status, error) {
					var errorHtml = `
						<div class="error-container" style="text-align: center; padding: 40px; color: #dc3545;">
							<i class="dashicons dashicons-warning" style="font-size: 48px; margin-bottom: 20px;"></i>
							<h4>Failed to load visitor data</h4>
							<p>Error: ${error || 'Network timeout or server error'}</p>
							<button class="btn btn-secondary retry-btn" style="margin-top: 10px;" onclick="jQuery(this).closest('.modal').modal('hide');">Close</button>
						</div>
					`;
					modal.find('.modal-body').html(errorHtml);
				}
			});
		});
		
		function displayModalContent(response, ip, duration, city, country, flag) {
			var modal = jQuery('#DayHitsModal');
		
			var deviceHtml = '';
			if (response.os && response.browser) {
				deviceHtml = `<i class="dashicons dashicons-desktop"></i> ${response.os}, ${response.browser}`;
			} else if (response.browser) {
				deviceHtml = `<i class="dashicons dashicons-desktop"></i> ${response.browser}`;
			} else {
				deviceHtml = `<i class="dashicons dashicons-desktop"></i> Unknown Device`;
			}
		
			var timelineHtml = '';
			if (response.pages && response.pages.length) {
				response.pages.forEach(function (page, idx) {
					var pageTitle = page.title || 'Untitled Page';
					var pageUrl = page.url || '#';
					var pageTime = page.time || '';
		
					timelineHtml += `
						<div class="timeline-item">
							<div class="step-info">
								<div class="step-number">${idx + 1}</div>
								<span class="step-arrow">→</span>
								<span class="visit-time">${pageTime}</span>
								<a href="${pageUrl}" target="_blank" class="page-title">
									${pageTitle}
									<svg class="external-link-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
										<path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"></path>
										<polyline points="15,3 21,3 21,9"></polyline>
										<line x1="10" y1="14" x2="21" y2="3"></line>
									</svg>
								</a>
							</div>
							<div class="page-url">${pageUrl}</div>
						</div>`;
				});
			} else {
				timelineHtml = '<div style="color:#888; text-align: center; padding: 20px;">No page visits found for this session.</div>';
			}
		
			var modalContent = `
				<style>
					.modal-dialog {
						max-width: 900px !important;
						width: 85vw !important;
						margin: 30px auto !important;
						transition: box-shadow 0.3s cubic-bezier(.4,2,.6,1), transform 0.3s cubic-bezier(.4,2,.6,1);
					}
					
					@media (max-width: 768px) {
						.modal-dialog {
							width: 95vw !important;
							margin: 10px auto !important;
						}
					}
					
					.modal-content {
						border-radius: 12px !important;
						box-shadow: 0 8px 32px rgba(40,60,120,0.18) !important;
					}
					
					.visitor-header-enhanced {
						display: flex; gap: 10px; align-items: center; margin-bottom: 14px; 
						background: #f8fafc; border-radius: 10px; padding: 8px 12px; 
						box-shadow: 0 2px 8px rgba(0,0,0,0.04); 
						font-family: 'Segoe UI', 'Arial', sans-serif; font-size: 0.97em;
						transition: box-shadow 0.3s, background 0.3s;
					}
					
					.visitor-header-enhanced:hover {
						background: #e0e7ef;
						box-shadow: 0 4px 16px rgba(40,60,120,0.10);
					}
					
					.visitor-header-enhanced img.flag { 
						border-radius: 4px; box-shadow: 0 1px 4px rgba(0,0,0,0.10); 
						border: 1px solid #e2e8f0; 
					}
					
					.visitor-header-enhanced .city-country { 
						font-weight: bold; font-size: 1em; color: #222; 
					}
					
					.visitor-header-enhanced .ip { 
						color: #444; font-size: 0.95em; background: #f1f5f9; 
						border-radius: 4px; padding: 1px 5px; margin-left: 2px; 
					}
					
					.visitor-header-enhanced .duration { 
						color: #2563eb; font-size: 0.95em; background: #e0e7ef; 
						border-radius: 4px; padding: 1px 7px; margin-left: 2px; 
						font-weight: 500; transition: background 0.3s, color 0.3s; 
					}
					
					.visitor-header-enhanced .duration:hover { 
						background: #2563eb; color: #fff; 
					}
					
					.visitor-header-enhanced .device { 
						background: #e0e7ef; color: #2563eb; border-radius: 16px; 
						padding: 2px 8px 2px 6px; font-size: 0.93em; 
						display: flex; align-items: center; gap: 3px; margin-left: 2px; 
						transition: background 0.3s, color 0.3s; 
					}
					
					.visitor-header-enhanced .device:hover { 
						background: #2563eb; color: #fff; 
					}
					
					.visit-timeline-enhanced { 
						font-family: 'Fira Mono', 'Consolas', 'monospace'; 
						border-left: 3px solid #e0e7ef; 
						margin-left: 10px; 
						padding-left: 18px; 
					}
					
					.visit-timeline-enhanced .timeline-item { 
						position: relative; 
						margin-bottom: 20px; 
						padding-left: 8px; 
						transition: background 0.2s; 
						border-radius: 6px; 
						padding-top: 8px;
						padding-bottom: 8px;
					}
					
					.visit-timeline-enhanced .timeline-item:hover { 
						background: #f1f5fb; 
					}
					
					.visit-timeline-enhanced .timeline-item:before { 
						content: ''; 
						position: absolute; 
						left: -18px; 
						top: 12px; 
						width: 10px; 
						height: 10px; 
						background: #2563eb; 
						border-radius: 50%; 
						border: 2px solid #fff; 
						box-shadow: 0 0 0 2px #e0e7ef; 
					}
					
					.visit-timeline-enhanced .step-info {
						display: flex;
						align-items: center;
						gap: 8px;
						margin-bottom: 6px;
						flex-wrap: wrap;
					}
					
					.visit-timeline-enhanced .step-number { 
						background: #2563eb;
						color: white;
						border-radius: 50%;
						width: 24px;
						height: 24px;
						display: flex;
						align-items: center;
						justify-content: center;
						font-size: 12px;
						font-weight: bold;
						flex-shrink: 0;
					}
					
					.visit-timeline-enhanced .visit-time { 
						color: #2563eb; 
						font-weight: bold; 
						margin-right: 10px; 
						font-size: 0.9em;
					}
					
					.visit-timeline-enhanced .step-arrow {
						color: #666;
						font-size: 16px;
						margin: 0 5px;
						font-weight: bold;
					}
					
					.visit-timeline-enhanced .page-title { 
						color: #0073aa; 
						text-decoration: none; 
						font-weight: 500;
						transition: color 0.2s; 
						flex: 1;
						display: flex;
						align-items: center;
						gap: 6px;
					}
					
					.visit-timeline-enhanced .page-title:hover { 
						color: #2563eb; 
						text-decoration: underline; 
					}
					
					.visit-timeline-enhanced .external-link-icon {
						width: 12px;
						height: 12px;
						opacity: 0.6;
						transition: opacity 0.2s;
						flex-shrink: 0;
					}
					
					.visit-timeline-enhanced .page-title:hover .external-link-icon {
						opacity: 1;
					}
					
					.visit-timeline-enhanced .page-url { 
						color: #888; 
						font-size: 11px; 
						margin-top: 4px;
						word-break: break-all; 
						line-height: 1.4;
						padding-left: 32px;
						background: #f8f9fa;
						padding: 4px 8px;
						border-radius: 4px;
						border-left: 3px solid #e0e7ef;
						margin-left: 32px;
					}
				</style>
				<div class="visitor-header-enhanced">
					<img class="flag" src="https://flagcdn.com/w40/${flag}.png" alt="flag" width="32" height="24" onerror="this.src='https://flagcdn.com/w40/xx.png';" />
					<div class="city-country">${city}, ${country}</div>
					<div class="ip">IP: ${ip}</div>
					<div class="duration">Duration: ${duration}</div>
					<div class="device">${deviceHtml}</div>
				</div>
				<div class="visit-timeline-enhanced">${timelineHtml}</div>
			`;
		
			modal.find('.modal-body').html(modalContent);
		}
		
		jQuery('#DayHitsModal').on('hide.bs.modal', function (event) {
			jQuery('.modal-body').html('');
		});
	
		setInterval(function () {
			if (Object.keys(modalDataCache).length > 100) {
				var keys = Object.keys(modalDataCache);
				var keysToDelete = keys.slice(0, keys.length - 50);
				keysToDelete.forEach(function (key) {
					delete modalDataCache[key];
				});
			}
		}, 300000);
	}
	function visitTimeGraphTable() {
		// Get current hour to calculate the starting page
		const currentHour = new Date().getHours();
		const pageLength = 10;
		const startingPage = Math.floor(currentHour / pageLength);

		const table = jQuery('#visit_time_graph_table').DataTable({
			"pageLength": pageLength,
			"searching": false,
			"ordering": false,
			"bLengthChange": false,
			"bFilter": true,
			"bInfo": false,
			"bAutoWidth": false,
			"bJQueryUI": true,
			"processing": true,
			"serverSide": true,
			"displayStart": startingPage * pageLength, // Start at the page containing current hour
			ajax: {
				url: ahc_ajax.ajax_url + '?action=visits_time_graph&fdt=' + jQuery("#vfrom_dt").val() + "&tdt=" + jQuery("#vto_dt").val(),
				data: function (d) {
					// Add current hour info to the request
					d.current_hour = currentHour;
					return d;
				}
			},
			dataSrc: 'data',
			columns: [
				{ data: 'time' },
				{ data: 'graph' },
				{ data: 'vtm_visitors', render: function(d) { return ahcProNumFormat(d); } },
				{ data: 'vtm_visits', render: function(d) { return ahcProNumFormat(d); } }
			],
			language: {
				processing: "<span class='loader'>&nbsp;</span>",
				"zeroRecords": "No data available.",
				paginate: {
					next: '<i class="dashicons dashicons-arrow-right-alt2"></i>',
					previous: '<i class="dashicons dashicons-arrow-left-alt2"></i>'
				}
			},
			"fnDrawCallback": function (oSettings) {
				if (oSettings._iDisplayLength > oSettings.fnRecordsDisplay()) {
					jQuery(oSettings.nTableWrapper).find('.dataTables_paginate').hide();
				}

				// Highlight current hour row after each draw
				highlightCurrentHourRow();
			},
			"fnInitComplete": function (oSettings) {
				// Scroll to current hour row after initial load
				setTimeout(function () {
					highlightCurrentHourRow();
				}, 500);
			},
			dom: 'Bfrtip',
			buttons: [{
				extend: 'excelHtml5',
				title: "",
				action: function (e, dt, node, config) {
					jQuery("#visit_time_graph_table").parents(".panelcontent").find(".dataTables_processing").show();
					jQuery.ajax({
						url: ahc_ajax.ajax_url + '?action=visits_time_graph&page=all&fdt=' + jQuery("#vfrom_dt").val() + "&tdt=" + jQuery("#vto_dt").val(),
						data: dt.ajax.params(),
						success: function (res, status, xhr) {
							var createXLSLFormatObj = [];
							var xlsHeader = ["Time", "Visitors", "Visits", "Graph"];
							var xlsRows = JSON.parse(res);

							createXLSLFormatObj.push(xlsHeader);
							jQuery.each(xlsRows, function (index, value) {
								var innerRowData = [];
								jQuery.each(value, function (ind, val) {
									innerRowData.push(val);
								});
								createXLSLFormatObj.push(innerRowData);
							});
							jQuery("#visit_time_graph_table").parents(".panelcontent").find(".dataTables_processing").hide();

							var filename = "visits_time_graph.xlsx";
							var ws_name = "sheet1";
							if (typeof console !== 'undefined') console.log(new Date());
							var wb = XLSX.utils.book_new(),
								ws = XLSX.utils.aoa_to_sheet(createXLSLFormatObj);
							XLSX.utils.book_append_sheet(wb, ws, ws_name);
							if (typeof console !== 'undefined') console.log(new Date());
							XLSX.writeFile(wb, filename);
							if (typeof console !== 'undefined') console.log(new Date());
						}
					})
				},
			}]
		});

		return table;
	}

	// Function to highlight current hour row
	function highlightCurrentHourRow() {
		const currentHour = new Date().getHours();
		const currentTimeString = (currentHour < 10 ? '0' + currentHour : currentHour) + ':00 - ' + (currentHour < 10 ? '0' + currentHour : currentHour) + ':59';

		// Remove previous highlighting
		jQuery('#visit_time_graph_table tbody tr').removeClass('current-hour-row');

		// Find and highlight current hour row
		jQuery('#visit_time_graph_table tbody tr').each(function () {
			const timeCell = jQuery(this).find('td:first-child').text().trim();
			if (timeCell === currentTimeString) {
				jQuery(this).addClass('current-hour-row');
				// Make the entire row text bold
				jQuery(this).css('font-weight', 'bold');
			}
		});
	}


	// Update current time display every minute
	function updateCurrentTimeDisplay() {
		const now = new Date();
		const timeString = now.getHours().toString().padStart(2, '0') + ':' + now.getMinutes().toString().padStart(2, '0');

		// Update the time display in header if it exists
		const timeDisplay = jQuery('.current-time-display');
		if (timeDisplay.length) {
			timeDisplay.text('Current Time: ' + timeString);
		}

		// Re-highlight current hour row in case hour changed
		highlightCurrentHourRow();
	}

	// Set up auto-refresh for time display
	setInterval(updateCurrentTimeDisplay, 60000); // Update every minute
	if (jQuery('#today_traffic_index_by_country').length) {
		trafficByIndexCountryTable();
	}
	function trafficByIndexCountryTable() {
		jQuery('#today_traffic_index_by_country').DataTable({
			"pageLength": 10,
			"searching": false,
			"ordering": false,
			"bLengthChange": false,
			"bFilter": true,
			"bInfo": false,
			"bAutoWidth": false,
			"bJQueryUI": true,
			"processing": true,
			"serverSide": true,
			ajax: ahc_ajax.ajax_url + '?action=today_traffic_index&fdt=' + jQuery("#t_from_dt").val() + "&tdt=" + jQuery("#t_to_dt").val(),
			dataSrc: 'data',
			columns: [
				{ data: 'no' },
				{ data: 'country' },
				{ data: 'ctr_name' },
				{ data: 'total', render: function(d) { return ahcProNumFormat(d); } },
			],
			language: {
				processing: "<span class='loader'>&nbsp;</span>",
				"zeroRecords": "No data available.",
				paginate: {
					next: '<i class="dashicons dashicons-arrow-right-alt2"></i>',
					previous: '<i class="dashicons dashicons-arrow-left-alt2"></i>'
				}
			},
			"fnDrawCallback": function (oSettings) {
				if (oSettings._iDisplayLength > oSettings.fnRecordsDisplay()) {
					jQuery(oSettings.nTableWrapper).find('.dataTables_paginate').hide();
				}
			},
			dom: 'Bfrtip',
			buttons: [{
				extend: 'excelHtml5',
				title: "",
				action: function (e, dt, node, config) {
					jQuery("#today_traffic_index_by_country").parents(".panelcontent").find(".dataTables_processing").show();
					jQuery.ajax({
						url: ahc_ajax.ajax_url + '?action=today_traffic_index&page=all&fdt=' + jQuery("#t_from_dt").val() + "&tdt=" + jQuery("#t_to_dt").val(),
						data: dt.ajax.params(),
						success: function (res, status, xhr) {
							//console.log(res);

							var createXLSLFormatObj = [];

							/* XLS Head Columns */
							var xlsHeader = ["No", "Country", "Total"];

							/* XLS Rows Data */
							var xlsRows = JSON.parse(res);

							createXLSLFormatObj.push(xlsHeader);
							jQuery.each(xlsRows, function (index, value) {
								var innerRowData = [];
								jQuery.each(value, function (ind, val) {
									innerRowData.push(val);
								});
								createXLSLFormatObj.push(innerRowData);
							});
							jQuery("#today_traffic_index_by_country").parents(".panelcontent").find(".dataTables_processing").hide();

							/* File Name */
							var filename = "today_traffic_index.xlsx";

							/* Sheet Name */
							var ws_name = "sheet1";

							if (typeof console !== 'undefined') console.log(new Date());
							var wb = XLSX.utils.book_new(),
								ws = XLSX.utils.aoa_to_sheet(createXLSLFormatObj);

							/* Add worksheet to workbook */
							XLSX.utils.book_append_sheet(wb, ws, ws_name);

							/* Write workbook and Download */
							if (typeof console !== 'undefined') console.log(new Date());
							XLSX.writeFile(wb, filename);
							if (typeof console !== 'undefined') console.log(new Date());

						}
					})
				},
				exportOptions: {
					columns: [0, 2, 3]
				},
			}]
		});

	}
	if (jQuery('#summary_statistics').find("tr").length > 1) {
		jQuery('#summary_statistics').DataTable({
			"pageLength": 100,
			"searching": false,
			"ordering": false,
			"bPaginate": false,
			"bLengthChange": false,
			"bFilter": true,
			"bInfo": false,
			"bAutoWidth": false,
			"fnDrawCallback": function (oSettings) {
				if (oSettings._iDisplayLength > oSettings.fnRecordsDisplay()) {
					jQuery(oSettings.nTableWrapper).find('.dataTables_paginate').hide();
				}
			},
			dom: 'Bfrtip',
			buttons: [{
				extend: 'excelHtml5',
				title: "summary_statistics", // This will be the sheet name
				filename: "summary_statistics" // This will be the file name
			}]
		});

	}
	if (jQuery('#search_engine').find("tr").length > 1) {
		jQuery('#search_engine').DataTable({
			"pageLength": 100,
			"searching": false,
			"ordering": false,
			"bPaginate": false,
			"bLengthChange": false,
			"bFilter": true,
			"bInfo": false,
			"bAutoWidth": false,
			"fnDrawCallback": function (oSettings) {
				if (oSettings._iDisplayLength > oSettings.fnRecordsDisplay()) {
					jQuery(oSettings.nTableWrapper).find('.dataTables_paginate').hide();
				}
			},
			dom: 'Bfrtip',
			buttons: [{
				extend: 'excelHtml5',
				title: ""
			}]
		});

	}

	jQuery(".export_data a").click(function (e) {
		e.preventDefault();
		jQuery(this).parents(".panel").find(".dt-buttons").find(".dt-button").trigger("click");

	})

	var dateFormat = "mm-dd-yy";
	if (jQuery("#from_dt").length && jQuery("#to_dt").length) {
		var from = jQuery("#from_dt").datepicker({
			defaultDate: 0,
			dateFormat: "mm-dd-yy",
			numberOfMonths: 1
		});


		var to = jQuery("#to_dt").datepicker({
			defaultDate: 0,
			dateFormat: "mm-dd-yy",
			numberOfMonths: 1
		});
	}


	if (jQuery("#summary_from_dt").length && jQuery("#summary_to_dt").length) {
		var from = jQuery("#summary_from_dt").datepicker({
			defaultDate: 0,
			dateFormat: "yy-mm-dd",
			numberOfMonths: 1
		});


		var to = jQuery("#summary_to_dt").datepicker({
			defaultDate: 0,
			dateFormat: "yy-mm-dd",
			numberOfMonths: 1
		});
	}


	jQuery("#to_dt").on("change", function () {
		from.datepicker("option", "maxDate", getDate(this));
	});

	jQuery("#from_dt").on("change", function () {
		to.datepicker("option", "minDate", getDate(this));
	});

	if (jQuery("#t_from_dt").length && jQuery("#t_to_dt").length) {
		var t_from_dt = jQuery("#t_from_dt").datepicker({
			defaultDate: 0,
			dateFormat: "mm-dd-yy",
			numberOfMonths: 1
		});


		var t_to_dt = jQuery("#t_to_dt").datepicker({
			defaultDate: 0,
			dateFormat: "mm-dd-yy",
			numberOfMonths: 1
		});
	}

	jQuery("#t_to_dt").on("change", function () {
		t_from_dt.datepicker("option", "maxDate", getDate(this));
	});

	jQuery("#t_from_dt").on("change", function () {
		t_to_dt.datepicker("option", "minDate", getDate(this));
	});

	if (jQuery("#vfrom_dt").length && jQuery("#vto_dt").length) {
		var vfrom = jQuery("#vfrom_dt").datepicker({
			defaultDate: 0,
			dateFormat: "mm-dd-yy",
			numberOfMonths: 1
		});

		var vto = jQuery("#vto_dt").datepicker({
			defaultDate: 0,
			dateFormat: "mm-dd-yy",
			numberOfMonths: 1
		});
	}

	jQuery("#vto_dt").on("change", function () {
		vfrom.datepicker("option", "maxDate", getDate(this));
	});

	jQuery("#vfrom_dt").on("change", function () {
		vto.datepicker("option", "minDate", getDate(this));
	});

	if (jQuery("#r_from_dt").length && jQuery("#r_to_dt").length) {
		var vfrom = jQuery("#r_from_dt").datepicker({
			defaultDate: 0,
			dateFormat: "mm-dd-yy",
			numberOfMonths: 1
		});

		var vto = jQuery("#r_to_dt").datepicker({
			defaultDate: 0,
			dateFormat: "mm-dd-yy",
			numberOfMonths: 1
		});
	}

	jQuery("#r_to_dt").on("change", function () {
		vfrom.datepicker("option", "maxDate", getDate(this));
	});

	jQuery("#r_from_dt").on("change", function () {
		vto.datepicker("option", "minDate", getDate(this));
	});


	function getDate(element) {
		var date;
		try {
			date = jQuery.datepicker.parseDate(dateFormat, element.value);
		} catch (error) {
			date = null;
		}
		return date;
	}
	jQuery(".search-panel .search_frm").submit(function (e) {
		e.preventDefault();
		var tableID = jQuery(this).parents(".panel").find(".panelcontent").find("table").attr("id");


		if (tableID == "recent_visit_by_ip") {
			jQuery('#' + tableID).DataTable().destroy();
			recentVisitorByIPTable();
			return false;
		}
		else if (tableID == "today_traffic_index_by_country") {
			jQuery('#' + tableID).DataTable().destroy();
			trafficByIndexCountryTable();
			return false;
		}
		else if (tableID == "lasest_search_words") {
			jQuery('#' + tableID).DataTable().destroy();
			latestSearchTable();
			return false;
		}
		else if (tableID == "visit_time_graph_table") {
			jQuery('#' + tableID).DataTable().destroy();
			visitTimeGraphTable();
			return false;
		}
		else
			return true;


	});
	jQuery(".clear_form").click(function (e) {
		jQuery(this).parents("form").find(".ahc_clear").val("");
		jQuery(this).parents("form").submit();
	});

	jQuery(".search_data a").click(function (e) {
		e.preventDefault();
		if (jQuery(this).parents(".panel").find(".search-panel").length)
			jQuery(this).parents(".panel").find(".search-panel").slideToggle();
		if (jQuery(this).parents(".panel").find(".dataTables_filter").length)
			jQuery(this).parents(".panel").find(".dataTables_filter").slideToggle();
	});
});