/**
 * Relatedly Admin — Advanced Statistics Page JS
 *
 * Handles: KPI cards, Chart.js charts, DataTables, date pickers,
 * AJAX data refresh, post analytics modal, and period comparison.
 *
 * Depends on: relatedly-vendor (Chart, DataTable, flatpickr, Swal)
 *
 * @package Relatedly
 * @since   2.0.0
 * @since   2.3.0 Rewritten as vanilla JS with advanced analytics features.
 */

( function () {
	'use strict';

	var activityChart = null;
	var ctrChart      = null;
	var topPostsTable = null;
	var topSourcesTable = null;

	// DOM references.
	var startInput   = document.getElementById( 'relatedly-start-date' );
	var endInput     = document.getElementById( 'relatedly-end-date' );
	var applyButton  = document.getElementById( 'relatedly-apply-date-filter' );
	var resetButton  = document.getElementById( 'relatedly-reset-date-filter' );
	var exportLink   = document.getElementById( 'relatedly-export-csv' );
	var compareButton= document.getElementById( 'relatedly-compare-periods' );
	var loading      = document.getElementById( 'relatedly-stats-loading' );
	var modal        = document.getElementById( 'relatedly-post-analytics-modal' );
	var modalClose   = document.getElementById( 'relatedly-close-analytics-modal' );
	var modalContent = document.getElementById( 'relatedly-post-analytics-content' );
	var modalTitle   = document.getElementById( 'relatedly-post-analytics-title' );

	/**
	 * Format a number with locale separators.
	 *
	 * @param {number} value Number to format.
	 * @return {string} Formatted number.
	 */
	function formatNumber( value ) {
		return Number( value ).toLocaleString();
	}

	/**
	 * Show or hide the loading spinner.
	 *
	 * @param {boolean} show Whether to show the spinner.
	 */
	function setLoading( show ) {
		if ( loading ) {
			loading.classList.toggle( 'relatedly-is-hidden', ! show );
		}
	}

	/**
	 * Initialize Flatpickr date pickers if available.
	 */
	function initDatePickers() {
		if ( typeof window.flatpickr === 'undefined' ) {
			return;
		}

		var opts = { dateFormat: 'Y-m-d', allowInput: true };

		if ( startInput ) {
			window.flatpickr( startInput, opts );
		}
		if ( endInput ) {
			window.flatpickr( endInput, opts );
		}

		// Comparison date pickers.
		[
			'relatedly-period1-start',
			'relatedly-period1-end',
			'relatedly-period2-start',
			'relatedly-period2-end',
		].forEach( function ( id ) {
			var el = document.getElementById( id );
			if ( el ) {
				window.flatpickr( el, opts );
			}
		} );
	}

	/**
	 * Perform an AJAX POST request.
	 *
	 * @param {string}   action   WordPress action name.
	 * @param {object}   payload  Request payload.
	 * @param {Function} callback Success callback.
	 */
	function ajaxPost( action, payload, callback ) {
		var data = new FormData();
		data.append( 'action', action );
		data.append( 'nonce', window.relatedlyStats.nonce );

		Object.keys( payload ).forEach( function ( key ) {
			data.append( key, payload[ key ] );
		} );

		var request = new XMLHttpRequest();
		request.open( 'POST', window.relatedlyStats.ajaxUrl, true );
		request.onload = function () {
			if ( request.status >= 200 && request.status < 400 ) {
				try {
					var response = JSON.parse( request.responseText );
					if ( response.success && typeof callback === 'function' ) {
						callback( response.data );
					}
				} catch ( e ) {
					// Silently ignore malformed JSON.
				}
			}
		};
		request.send( data );
	}

	/**
	 * Render the activity chart.
	 *
	 * @param {Array} daily Daily counts array.
	 */
	function renderActivityChart( daily ) {
		var canvas = document.getElementById( 'relatedly-chart' );
		if ( ! canvas || typeof window.Chart === 'undefined' ) {
			return;
		}

		var labels      = daily.map( function ( r ) { return r.date; } );
		var clicks      = daily.map( function ( r ) { return r.clicks; } );
		var impressions = daily.map( function ( r ) { return r.impressions; } );

		if ( activityChart ) {
			activityChart.destroy();
		}

		activityChart = new window.Chart( canvas, {
			type: 'line',
			data: {
				labels: labels,
				datasets: [
					{
						label: 'Clicks',
						data: clicks,
						borderColor: '#e11d48',
						backgroundColor: 'rgba(225,29,72,0.08)',
						tension: 0.3,
						fill: true,
					},
					{
						label: 'Impressions',
						data: impressions,
						borderColor: '#2563eb',
						backgroundColor: 'rgba(37,99,235,0.08)',
						tension: 0.3,
						fill: true,
					},
				],
			},
			options: {
				responsive: true,
				maintainAspectRatio: false,
				plugins: { legend: { position: 'top' } },
				scales: { y: { beginAtZero: true } },
			},
		} );
	}

	/**
	 * Render the CTR trend chart.
	 *
	 * @param {Array} daily Daily counts array.
	 */
	function renderCtrChart( daily ) {
		var canvas = document.getElementById( 'relatedly-ctr-chart' );
		if ( ! canvas || typeof window.Chart === 'undefined' ) {
			return;
		}

		var labels = daily.map( function ( r ) { return r.date; } );
		var ctr    = daily.map( function ( r ) {
			return r.impressions > 0 ? ( ( r.clicks / r.impressions ) * 100 ).toFixed( 2 ) : 0;
		} );

		if ( ctrChart ) {
			ctrChart.destroy();
		}

		ctrChart = new window.Chart( canvas, {
			type: 'line',
			data: {
				labels: labels,
				datasets: [
					{
						label: 'CTR %',
						data: ctr,
						borderColor: '#059669',
						backgroundColor: 'rgba(5,150,105,0.08)',
						tension: 0.3,
						fill: true,
					},
				],
			},
			options: {
				responsive: true,
				maintainAspectRatio: false,
				plugins: { legend: { position: 'top' } },
				scales: { y: { beginAtZero: true } },
			},
		} );
	}

	/**
	 * Escape HTML entities.
	 *
	 * @param {string} text Raw text.
	 * @return {string} Escaped text.
	 */
	function escapeHtml( text ) {
		var div = document.createElement( 'div' );
		div.textContent = text;
		return div.innerHTML;
	}

	/**
	 * Render a DataTable for top posts or sources.
	 *
	 * @param {string} tableId Table element ID.
	 * @param {Array}  rows    Data rows.
	 * @param {object} existingTable Existing DataTable instance.
	 * @return {object} DataTable instance.
	 */
	function renderDataTable( tableId, rows, existingTable ) {
		var table = document.getElementById( tableId );
		if ( ! table || typeof window.DataTable === 'undefined' ) {
			return existingTable;
		}

		if ( existingTable ) {
			existingTable.destroy();
		}

		var tbody = table.querySelector( 'tbody' );
		if ( ! tbody ) {
			return existingTable;
		}

		tbody.innerHTML = rows.map( function ( r ) {
			var url = window.relatedlyStats.editPostUrl.replace( 'POST_ID', r.post_id );
			return '<tr>' +
				'<td><a href="' + escapeHtml( url ) + '">' + escapeHtml( r.title ) + '</a></td>' +
				'<td class="relatedly-num">' + formatNumber( r.clicks ) + '</td>' +
				'<td class="relatedly-num">' + formatNumber( r.impressions ) + '</td>' +
				'<td class="relatedly-num">' + escapeHtml( r.ctr ) + '%</td>' +
				'<td><button type="button" class="button button-small relatedly-view-post-analytics" data-post-id="' + r.post_id + '">' +
				escapeHtml( window.relatedlyStats.strings.view ) +
				'</button></td>' +
				'</tr>';
		} ).join( '' );

		return new window.DataTable( table, {
			pageLength: 10,
			order: [ [ 1, 'desc' ] ],
		} );
	}

	/**
	 * Update KPI cards from summary data.
	 *
	 * @param {object} summary Summary payload.
	 */
	function updateKpiCards( summary ) {
		var totalClicksEl = document.getElementById( 'relatedly-total-clicks' );
		var totalImpressionsEl = document.getElementById( 'relatedly-total-impressions' );
		var ctrEl = document.getElementById( 'relatedly-ctr' );
		var inlineCtrEl = document.getElementById( 'relatedly-inline-ctr' );
		var endContentCtrEl = document.getElementById( 'relatedly-end-content-ctr' );
		var floatingCtrEl = document.getElementById( 'relatedly-floating-ctr' );

		if ( totalClicksEl ) {
			totalClicksEl.textContent = formatNumber( summary.total_clicks );
		}
		if ( totalImpressionsEl ) {
			totalImpressionsEl.textContent = formatNumber( summary.total_impressions );
		}
		if ( ctrEl ) {
			ctrEl.textContent = summary.ctr + '%';
		}
		if ( inlineCtrEl ) {
			inlineCtrEl.textContent = ( summary.breakdown.inline ? summary.breakdown.inline.ctr : 0 ) + '%';
		}
		if ( endContentCtrEl ) {
			endContentCtrEl.textContent = ( summary.breakdown.end_content ? summary.breakdown.end_content.ctr : 0 ) + '%';
		}
		if ( floatingCtrEl ) {
			floatingCtrEl.textContent = ( summary.breakdown.floating ? summary.breakdown.floating.ctr : 0 ) + '%';
		}
	}

	/**
	 * Update the CSV export link with the current date range.
	 */
	function updateExportLink() {
		if ( ! exportLink ) {
			return;
		}

		var base = exportLink.getAttribute( 'href' );
		base = base.replace( /start_date=[^&]*/, 'start_date=' + encodeURIComponent( startInput.value ) );
		base = base.replace( /end_date=[^&]*/, 'end_date=' + encodeURIComponent( endInput.value ) );
		exportLink.setAttribute( 'href', base );
	}

	/**
	 * Load and render all dashboard data for the current date range.
	 */
	function loadStats() {
		if ( ! startInput || ! endInput ) {
			return;
		}

		setLoading( true );

		ajaxPost(
			'relatedly_get_statistics',
			{
				start_date: startInput.value,
				end_date: endInput.value,
				dataset: 'summary',
			},
			function ( data ) {
				setLoading( false );
				updateKpiCards( data.summary );
				renderActivityChart( data.daily );
				renderCtrChart( data.daily );
				topPostsTable = renderDataTable( 'relatedly-top-posts-table', data.top_posts, topPostsTable );
				topSourcesTable = renderDataTable( 'relatedly-top-sources-table', data.top_sources, topSourcesTable );
				updateExportLink();
			}
		);
	}

	/**
	 * Reset date range to the last 30 days.
	 */
	function resetDates() {
		if ( startInput ) {
			startInput.value = window.relatedlyStats.defaultStart;
		}
		if ( endInput ) {
			endInput.value = window.relatedlyStats.defaultEnd;
		}
		loadStats();
	}

	/**
	 * Validate a date range.
	 *
	 * @param {string} start Start date.
	 * @param {string} end   End date.
	 * @return {boolean} True if valid.
	 */
	function isValidRange( start, end ) {
		if ( ! start || ! end ) {
			return false;
		}
		return new Date( start ) <= new Date( end );
	}

	/**
	 * Show a SweetAlert toast/warning.
	 *
	 * @param {string} message Message text.
	 */
	function showWarning( message ) {
		if ( typeof window.Swal === 'undefined' ) {
			window.alert( message );
			return;
		}
		window.Swal.fire( {
			icon: 'warning',
			title: window.relatedlyStats.strings.attention,
			text: message,
			confirmButtonColor: '#0073aa',
		} );
	}

	/**
	 * Handle period comparison.
	 */
	function comparePeriods() {
		var p1Start = document.getElementById( 'relatedly-period1-start' ).value;
		var p1End   = document.getElementById( 'relatedly-period1-end' ).value;
		var p2Start = document.getElementById( 'relatedly-period2-start' ).value;
		var p2End   = document.getElementById( 'relatedly-period2-end' ).value;

		if ( ! isValidRange( p1Start, p1End ) || ! isValidRange( p2Start, p2End ) ) {
			showWarning( window.relatedlyStats.strings.invalidRange );
			return;
		}

		if ( typeof window.Swal !== 'undefined' ) {
			window.Swal.fire( {
				title: window.relatedlyStats.strings.comparing,
				text: window.relatedlyStats.strings.pleaseWait,
				allowOutsideClick: false,
				allowEscapeKey: false,
				showConfirmButton: false,
				willOpen: function () { window.Swal.showLoading(); },
			} );
		}

		ajaxPost(
			'relatedly_get_comparison',
			{
				period1_start: p1Start,
				period1_end: p1End,
				period2_start: p2Start,
				period2_end: p2End,
			},
			function ( data ) {
				if ( typeof window.Swal !== 'undefined' ) {
					window.Swal.close();
				}
				renderComparisonResults( data );
			}
		);
	}

	/**
	 * Render comparison results table.
	 *
	 * @param {object} data Comparison response.
	 */
	function renderComparisonResults( data ) {
		var container = document.getElementById( 'relatedly-comparison-results' );
		if ( ! container ) {
			return;
		}

		var diff = data.differences;
		var p1   = data.period1.summary;
		var p2   = data.period2.summary;

		function sign( value ) {
			if ( value > 0 ) { return '+'; }
			return '';
		}

		container.innerHTML =
			'<table class="widefat striped">' +
			'<thead><tr>' +
			'<th>' + escapeHtml( window.relatedlyStats.strings.metric ) + '</th>' +
			'<th>' + escapeHtml( data.period1.label ) + '</th>' +
			'<th>' + escapeHtml( data.period2.label ) + '</th>' +
			'<th>' + escapeHtml( window.relatedlyStats.strings.difference ) + '</th>' +
			'</tr></thead>' +
			'<tbody>' +
			'<tr>' +
			'<td><strong>' + escapeHtml( window.relatedlyStats.strings.clicks ) + '</strong></td>' +
			'<td>' + formatNumber( p1.total_clicks ) + '</td>' +
			'<td>' + formatNumber( p2.total_clicks ) + '</td>' +
			'<td>' + sign( diff.clicks ) + formatNumber( diff.clicks ) + ' (' + sign( diff.clicks_percent ) + diff.clicks_percent + '%)</td>' +
			'</tr>' +
			'<tr>' +
			'<td><strong>' + escapeHtml( window.relatedlyStats.strings.impressions ) + '</strong></td>' +
			'<td>' + formatNumber( p1.total_impressions ) + '</td>' +
			'<td>' + formatNumber( p2.total_impressions ) + '</td>' +
			'<td>' + sign( diff.impressions ) + formatNumber( diff.impressions ) + ' (' + sign( diff.impressions_percent ) + diff.impressions_percent + '%)</td>' +
			'</tr>' +
			'<tr>' +
			'<td><strong>' + escapeHtml( window.relatedlyStats.strings.ctr ) + '</strong></td>' +
			'<td>' + p1.ctr + '%</td>' +
			'<td>' + p2.ctr + '%</td>' +
			'<td>' + sign( diff.ctr ) + diff.ctr.toFixed( 2 ) + '%</td>' +
			'</tr>' +
			'</tbody>' +
			'</table>';

		container.classList.remove( 'relatedly-is-hidden' );
	}

	/**
	 * Load and display post analytics in the modal.
	 *
	 * @param {number} postId Post ID.
	 */
	function loadPostAnalytics( postId ) {
		if ( ! startInput || ! endInput ) {
			return;
		}

		modalTitle.textContent = window.relatedlyStats.strings.analyticsTitle + ' #' + postId;
		modalContent.innerHTML = '<p class="relatedly-modal-loading"><span class="spinner is-active relatedly-inline-spinner"></span> ' + escapeHtml( window.relatedlyStats.strings.loading ) + '</p>';
		modal.classList.add( 'open' );

		ajaxPost(
			'relatedly_get_post_analytics',
			{
				post_id: postId,
				start_date: startInput.value,
				end_date: endInput.value,
			},
			function ( data ) {
				renderPostAnalytics( postId, data );
			}
		);
	}

	/**
	 * Render post analytics content.
	 *
	 * @param {number} postId Post ID.
	 * @param {object} data   Analytics data.
	 */
	function renderPostAnalytics( postId, data ) {
		var title = data.clicked.title || ( window.relatedlyStats.strings.post + ' #' + postId );
		modalTitle.textContent = window.relatedlyStats.strings.analyticsTitle + ': ' + title;

		var clicked = data.clicked;
		var source  = data.source;

		var html = '<div class="relatedly-post-stats-grid">' +
			'<div class="relatedly-post-stat">' +
			'<h4>' + escapeHtml( window.relatedlyStats.strings.asClicked ) + '</h4>' +
			'<p><strong>' + escapeHtml( window.relatedlyStats.strings.clicks ) + ':</strong> ' + formatNumber( clicked.clicks ) + '</p>' +
			'<p><strong>' + escapeHtml( window.relatedlyStats.strings.impressions ) + ':</strong> ' + formatNumber( clicked.impressions ) + '</p>' +
			'<p><strong>' + escapeHtml( window.relatedlyStats.strings.ctr ) + ':</strong> ' + clicked.ctr + '%</p>' +
			'</div>' +
			'<div class="relatedly-post-stat">' +
			'<h4>' + escapeHtml( window.relatedlyStats.strings.asSource ) + '</h4>' +
			'<p><strong>' + escapeHtml( window.relatedlyStats.strings.clicksGenerated ) + ':</strong> ' + formatNumber( source.clicks ) + '</p>' +
			'<p><strong>' + escapeHtml( window.relatedlyStats.strings.impressions ) + ':</strong> ' + formatNumber( source.impressions ) + '</p>' +
			'<p><strong>' + escapeHtml( window.relatedlyStats.strings.ctr ) + ':</strong> ' + source.ctr + '%</p>' +
			'</div>' +
			'</div>';

		if ( data.top_related && data.top_related.length > 0 ) {
			html += '<h3>' + escapeHtml( window.relatedlyStats.strings.topRelated ) + '</h3>' +
				'<table class="widefat striped"><thead><tr>' +
				'<th>' + escapeHtml( window.relatedlyStats.strings.post ) + '</th>' +
				'<th class="relatedly-num">' + escapeHtml( window.relatedlyStats.strings.clicks ) + '</th>' +
				'<th class="relatedly-num">' + escapeHtml( window.relatedlyStats.strings.impressions ) + '</th>' +
				'<th class="relatedly-num">' + escapeHtml( window.relatedlyStats.strings.ctr ) + '</th>' +
				'</tr></thead><tbody>';

			data.top_related.forEach( function ( item ) {
				html += '<tr>' +
					'<td>' + escapeHtml( item.title ) + '</td>' +
					'<td class="relatedly-num">' + formatNumber( item.clicks ) + '</td>' +
					'<td class="relatedly-num">' + formatNumber( item.impressions ) + '</td>' +
					'<td class="relatedly-num">' + escapeHtml( item.ctr ) + '%</td>' +
					'</tr>';
			} );

			html += '</tbody></table>';
		}

		modalContent.innerHTML = html;
	}

	/**
	 * Close the post analytics modal.
	 */
	function closeModal() {
		if ( modal ) {
			modal.classList.remove( 'open' );
		}
	}

	/**
	 * Initialize event listeners and initial load.
	 */
	function init() {
		initDatePickers();

		if ( applyButton ) {
			applyButton.addEventListener( 'click', function ( e ) {
				e.preventDefault();
				if ( ! isValidRange( startInput.value, endInput.value ) ) {
					showWarning( window.relatedlyStats.strings.invalidRange );
					return;
				}
				loadStats();
			} );
		}

		if ( resetButton ) {
			resetButton.addEventListener( 'click', function ( e ) {
				e.preventDefault();
				resetDates();
			} );
		}

		if ( compareButton ) {
			compareButton.addEventListener( 'click', function ( e ) {
				e.preventDefault();
				comparePeriods();
			} );
		}

		if ( modalClose ) {
			modalClose.addEventListener( 'click', closeModal );
		}

		if ( modal ) {
			modal.addEventListener( 'click', function ( e ) {
				if ( e.target === modal ) {
					closeModal();
				}
			} );
		}

		document.addEventListener( 'click', function ( e ) {
			var button = e.target.closest( '.relatedly-view-post-analytics' );
			if ( button ) {
				e.preventDefault();
				loadPostAnalytics( parseInt( button.getAttribute( 'data-post-id' ), 10 ) );
			}
		} );

		// Initial render: prefer server-rendered chart data to avoid an extra AJAX round trip.
		if ( document.getElementById( 'relatedly-chart' ) ) {
			if ( typeof window.relatedlyChartData !== 'undefined' && window.relatedlyChartData.length > 0 ) {
				renderActivityChart( window.relatedlyChartData );
				renderCtrChart( window.relatedlyChartData );
			} else {
				loadStats();
			}
		}
	}

	document.addEventListener( 'DOMContentLoaded', init );
} )();
