jQuery(function($) {

	// Legacy tab handling for member pulse panel
	var $mostRecent = $('#peepso_dashboard_most_recent');
	$mostRecent.on('click', '[data-toggle=tab]', function(e) {
		var $a   = $(this),
			$tab = $a.closest('li'),
			$div = $mostRecent.find($a.attr('href'));
		e.preventDefault();
		e.stopPropagation();
		if ($div.length) {
			$tab.siblings().removeClass('active');
			$tab.addClass('active');
			$div.siblings().removeClass('active');
			$div.addClass('active');
		}
	});

	// ── Guards ────────────────────────────────────────────────────────────────

	if (typeof Chart === 'undefined' || typeof peepso === 'undefined') return;
	if (!document.getElementById('ps-activity-chart')) return;

	// ── Shared state ──────────────────────────────────────────────────────────

	var STORAGE_KEY  = 'peepso_activity_range';
	var activeRange  = 'this_month';
	var hiddenSeries = {};

	function saveRange() {
		try { localStorage.setItem(STORAGE_KEY, activeRange); } catch(e) {}
	}

	function setActiveBtn(range) {
		$('.ps-chart-range-btn').removeClass('ps-chart-range-btn--active');
		$('.ps-chart-range-btn[data-range="' + range + '"]').addClass('ps-chart-range-btn--active');
	}

	function restoreRange() {
		try {
			var saved = localStorage.getItem(STORAGE_KEY);
			if (!saved) return;

			if (/^custom:(\d{4}-\d{2}-\d{2}):(\d{4}-\d{2}-\d{2})$/.test(saved)) {
				var parts = saved.split(':');
				activeRange = saved;
				$('#ps-range-from').val(parts[1]);
				$('#ps-range-to').val(parts[2]);
				setActiveBtn('custom');
				$('#ps-custom-range').addClass('is-visible');
			} else if (/^(this_week|last_week|this_month|last_month)$/.test(saved)) {
				activeRange = saved;
				setActiveBtn(saved);
			}
		} catch(e) {}
	}

	// Translated strings + WP locale/format data (see admindashboardmodern.php).
	// English fallbacks keep the chart working if the object is absent.
	var I18N = window.psDashboardI18n || {};
	var i18nSeries = I18N.series || {};
	var i18nDonut  = I18N.donut  || {};

	var seriesConfig = {
		'peepso-post':    { label: i18nSeries['peepso-post']    || 'Posts',     color: '#FC832C' },
		'peepso-comment': { label: i18nSeries['peepso-comment'] || 'Comments',  color: '#4F97D9' },
		'likes':          { label: i18nSeries['likes']          || 'Reactions', color: '#7BC968' }
	};

	// ── Utilities ─────────────────────────────────────────────────────────────

	function pad(n) { return n < 10 ? '0' + n : String(n); }

	function toLocalDateKey(tsMs) {
		var d = new Date(tsMs);
		return d.getFullYear() + '-' + pad(d.getMonth() + 1) + '-' + pad(d.getDate());
	}

	var MONTHS = I18N.months ||
		['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];

	function formatAxisLabel(d) {
		// Compact day + translated short month (e.g. "13 May").
		return d.getDate() + ' ' + MONTHS[d.getMonth()];
	}

	// Format an hour-of-day (0–23) following the site's WordPress time format:
	// 24-hour as "HH:00", otherwise 12-hour with the translated meridiem.
	function formatHour(h) {
		if (I18N.is24h) return pad(h) + ':00';
		var h12 = h % 12 || 12;
		return h12 + (h < 12 ? (I18N.am || 'am') : (I18N.pm || 'pm'));
	}

	function hexToRgba(hex, alpha) {
		var r = parseInt(hex.slice(1, 3), 16);
		var g = parseInt(hex.slice(3, 5), 16);
		var b = parseInt(hex.slice(5, 7), 16);
		return 'rgba(' + r + ',' + g + ',' + b + ',' + alpha + ')';
	}

	// ── External tooltip (escapes overflow/canvas clipping) ──────────────────

	// Track whether the most-recent interaction was touch so we can skip
	// auto-hide (touchend fires right after touchstart and would close the
	// tooltip immediately; on touch we rely on the outside-tap handler below).
	var lastTouchTime    = 0;
	function isTouch() { return (Date.now() - lastTouchTime) < 500; }
	$(document).on('touchstart.pstt', function() { lastTouchTime = Date.now(); });

	var $chartTooltip  = $('<div class="ps-chart-tooltip"></div>').appendTo('body');
	var tooltipHideTimer = null;

	function externalTooltip(context) {
		var tooltip = context.tooltip;

		if (!tooltip || tooltip.opacity === 0) {
			// On touch: don't auto-hide — the outside-tap handler below takes care of it.
			if (isTouch()) return;
			tooltipHideTimer = setTimeout(function() { $chartTooltip.hide(); }, 180);
			return;
		}

		// Cancel any pending hide before we re-position
		if (tooltipHideTimer) { clearTimeout(tooltipHideTimer); tooltipHideTimer = null; }

		var title  = tooltip.title && tooltip.title.length ? tooltip.title[0] : '';
		var lines  = (tooltip.body || []).map(function(b) { return b.lines.join(''); });
		var colors = tooltip.labelColors || [];

		var html = '';
		if (title) {
			html += '<div class="ps-chart-tooltip__title">' + title + '</div>';
		}
		lines.forEach(function(line, i) {
			var bg = colors[i] ? colors[i].backgroundColor : 'rgba(255,255,255,0.5)';
			if (typeof bg !== 'string') bg = 'rgba(255,255,255,0.5)';
			html += '<div class="ps-chart-tooltip__row">'
				+ '<span class="ps-chart-tooltip__dot" style="background:' + bg + '"></span>'
				+ line + '</div>';
		});

		$chartTooltip.html(html).show();

		// Use absolute positioning so the tooltip scrolls with the page and
		// stays anchored to its data point instead of floating free on scroll.
		var rect    = context.chart.canvas.getBoundingClientRect();
		var scrollX = window.scrollX || window.pageXOffset || 0;
		var scrollY = window.scrollY || window.pageYOffset || 0;
		var elW     = $chartTooltip.outerWidth();
		var elH     = $chartTooltip.outerHeight();
		var posX    = rect.left + scrollX + tooltip.caretX + 14;
		var posY    = rect.top  + scrollY + tooltip.caretY - elH / 2;

		// Flip left if it would overflow the right edge of the visible area
		if (posX + elW > scrollX + window.innerWidth)  posX = rect.left + scrollX + tooltip.caretX - elW - 14;
		if (posY < scrollY + 4)                        posY = scrollY + 4;
		if (posY + elH > scrollY + window.innerHeight) posY = scrollY + window.innerHeight - elH - 4;

		$chartTooltip.css({ top: posY, left: posX });
	}

	// Hide tooltips when tapping/clicking anywhere outside their trigger elements
	$(document).on('click touchstart', function(e) {
		var $t = $(e.target);
		if (!$t.closest('#ps-activity-chart, #ps-content-donut').length) {
			if (tooltipHideTimer) { clearTimeout(tooltipHideTimer); tooltipHideTimer = null; }
			$chartTooltip.hide();
		}
		if (!$t.closest('.ps-heatmap__cell').length) {
			if (heatmapHideTimer) { clearTimeout(heatmapHideTimer); heatmapHideTimer = null; }
			$heatmapTooltip.hide();
		}
	});

	// ── Line chart ────────────────────────────────────────────────────────────

	var lineChart = null;
	var lineCtx   = document.getElementById('ps-activity-chart').getContext('2d');

	function buildLineChart(response) {
		var minMs    = response.min;
		var maxMs    = response.max;
		var labels   = [];
		var dateKeys = [];
		var d        = new Date(minMs);
		d.setHours(0, 0, 0, 0);
		var end = new Date(maxMs);
		end.setHours(23, 59, 59, 999);

		while (d <= end) {
			dateKeys.push(toLocalDateKey(d.getTime()));
			labels.push(formatAxisLabel(new Date(d)));
			d.setDate(d.getDate() + 1);
		}

		var datasets = response.series.map(function(series) {
			var cfg = seriesConfig[series.type] || { label: series.type, color: '#999999' };
			var map = {};
			series.data.forEach(function(pt) { map[toLocalDateKey(pt[0])] = pt[1]; });
			var values = dateKeys.map(function(k) { return map[k] || 0; });

			$('.ps-chart-toggle[data-series="' + series.type + '"] .ps-chart-toggle__total')
				.text(series.total > 0 ? '· ' + series.total : '');

			return {
				label:                 cfg.label,
				data:                  values,
				borderColor:           cfg.color,
				backgroundColor:       hexToRgba(cfg.color, 0.07),
				pointBackgroundColor:  cfg.color,
				pointBorderColor:      '#fff',
				pointBorderWidth:      2,
				pointRadius:           3,
				pointHoverRadius:      7,
				pointHoverBorderWidth: 2,
				tension:               0.4,
				fill:                  true,
				borderWidth:           2,
				hidden:                !!hiddenSeries[series.type]
			};
		});

		if (lineChart) { lineChart.destroy(); lineChart = null; }

		lineChart = new Chart(lineCtx, {
			type: 'line',
			data: { labels: labels, datasets: datasets },
			options: {
				responsive:          true,
				maintainAspectRatio: false,
				interaction: { mode: 'index', intersect: false },
				plugins: {
					legend: { display: false },
					tooltip: {
						enabled:  false,
						external: externalTooltip,
						callbacks: {
							label: function(ctx) {
								return '  ' + ctx.dataset.label + ': ' + ctx.parsed.y;
							}
						}
					}
				},
				scales: {
					x: {
						grid:   { color: '#f0f0f1' },
						border: { display: false },
						ticks:  { color: '#646970', font: { size: 11 }, maxRotation: 0, autoSkip: true, maxTicksLimit: 10 }
					},
					y: {
						min:    0,
						grid:   { color: '#f0f0f1' },
						border: { display: false },
						ticks:  { color: '#646970', font: { size: 11 }, precision: 0, stepSize: 1 }
					}
				}
			}
		});
	}

	// ── Donut chart ───────────────────────────────────────────────────────────

	var donutChart   = null;
	var donutCanvas  = document.getElementById('ps-content-donut');
	var donutOrder   = ['posts', 'comments', 'reactions'];
	var donutColors  = { posts: '#FC832C', comments: '#4F97D9', reactions: '#7BC968' };
	var donutLabels  = {
		posts:     i18nDonut.posts     || 'Posts',
		comments:  i18nDonut.comments  || 'Comments',
		reactions: i18nDonut.reactions || 'Reactions'
	};

	function buildDonut(breakdown) {
		if (!breakdown || !donutCanvas) return;

		var total  = breakdown.posts + breakdown.comments + breakdown.reactions;
		var values = donutOrder.map(function(k) { return breakdown[k]; });

		$('#ps-donut-center strong').text(total);

		donutOrder.forEach(function(key) {
			var val = breakdown[key];
			var pct = total > 0 ? Math.round(val / total * 100) : 0;
			$('#ps-donut-legend li[data-type="' + key + '"] .ps-donut-legend__value').text(val);
			$('#ps-donut-legend li[data-type="' + key + '"] .ps-donut-legend__pct').text(pct + '%');
		});

		if (donutChart) {
			donutChart.data.datasets[0].data = values;
			donutChart.update();
			return;
		}

		donutChart = new Chart(donutCanvas.getContext('2d'), {
			type: 'doughnut',
			data: {
				labels:   donutOrder.map(function(k) { return donutLabels[k]; }),
				datasets: [{
					data:            values,
					backgroundColor: donutOrder.map(function(k) { return donutColors[k]; }),
					borderWidth:     2,
					borderColor:     '#ffffff',
					hoverOffset:     6
				}]
			},
			options: {
				responsive:          true,
				maintainAspectRatio: false,
				cutout:              '62%',
				plugins: {
					legend: { display: false },
					tooltip: {
						enabled:  false,
						external: externalTooltip,
						callbacks: {
							label: function(ctx) {
								var t   = ctx.dataset.data.reduce(function(a, b) { return a + b; }, 0);
								var pct = t > 0 ? Math.round(ctx.raw / t * 100) : 0;
								return '  ' + ctx.label + ': ' + ctx.raw + ' (' + pct + '%)';
							}
						}
					}
				}
			}
		});
	}

	// ── Heatmap ───────────────────────────────────────────────────────────────

	var $heatmapWrap    = $('#ps-activity-heatmap');
	var $heatmapTooltip = $('<div class="ps-heatmap-tooltip"></div>').appendTo('body');
	var days            = I18N.days || ['Mon','Tue','Wed','Thu','Fri','Sat','Sun'];
	var hourLabels      = { 0: formatHour(0), 6: formatHour(6), 12: formatHour(12), 18: formatHour(18) };

	function buildHeatmap(matrix) {
		if (!matrix || !$heatmapWrap.length) return;

		var max = 1;
		for (var d = 0; d < 7; d++) {
			for (var h = 0; h < 24; h++) {
				if (matrix[d] && matrix[d][h] > max) max = matrix[d][h];
			}
		}

		var html = '';

		// Corner + hour labels
		html += '<div class="ps-heatmap__corner"></div>';
		for (var h = 0; h < 24; h++) {
			html += '<div class="ps-heatmap__hour-label">' + (hourLabels[h] || '') + '</div>';
		}

		// Rows
		for (var d = 0; d < 7; d++) {
			html += '<div class="ps-heatmap__day-label">' + days[d] + '</div>';
			for (var h = 0; h < 24; h++) {
				var cnt       = (matrix[d] && matrix[d][h]) ? matrix[d][h] : 0;
				var intensity = parseFloat((cnt / max).toFixed(4));
				var cls       = cnt === 0 ? 'ps-heatmap__cell ps-heatmap__cell--empty' : 'ps-heatmap__cell';
				html += '<div class="' + cls + '"'
					+ ' style="--intensity:' + intensity + '"'
					+ ' data-count="' + cnt + '"'
					+ ' data-day="' + days[d] + '"'
					+ ' data-hour="' + h + '">'
					+ '</div>';
			}
		}

		$heatmapWrap.html(html);
	}

	var heatmapHideTimer = null;

	function positionHeatmapTooltip(e) {
		var scrollX = window.scrollX || window.pageXOffset || 0;
		var scrollY = window.scrollY || window.pageYOffset || 0;
		var elW     = $heatmapTooltip.outerWidth();
		var elH     = $heatmapTooltip.outerHeight();
		var posX    = e.clientX + scrollX + 14;
		var posY    = e.clientY + scrollY - elH - 10;

		if (posX + elW > scrollX + window.innerWidth)  posX = e.clientX + scrollX - elW - 14;
		if (posY < scrollY + 4)                        posY = e.clientY + scrollY + 10;

		$heatmapTooltip.css({ top: posY, left: posX });
	}

	$(document).on('mouseenter touchstart', '.ps-heatmap__cell', function(e) {
		var rawEvent = e.originalEvent.touches ? e.originalEvent.touches[0] : e;
		var count = parseInt($(this).data('count'), 10) || 0;
		var day   = $(this).data('day');
		var hour  = parseInt($(this).data('hour'), 10);
		var start = formatHour(hour);
		var end   = formatHour((hour + 1) % 24);
		var tpl   = count === 1 ? (I18N.actionOne || '1 action') : (I18N.actionMany || '%d actions');
		var label = tpl.replace('%d', count);

		if (heatmapHideTimer) { clearTimeout(heatmapHideTimer); heatmapHideTimer = null; }

		$heatmapTooltip
			.html('<strong>' + label + '</strong><br>' + day + ' · ' + start + '–' + end)
			.show();
		positionHeatmapTooltip(rawEvent);

	}).on('mousemove', '.ps-heatmap__cell', function(e) {
		positionHeatmapTooltip(e);

	}).on('mouseleave', '.ps-heatmap__cell', function() {
		if (isTouch()) return;
		heatmapHideTimer = setTimeout(function() { $heatmapTooltip.hide(); }, 180);
	});

	// ── Shared load: one AJAX call, all range-aware panels ───────────────────

	var $topContentWrap   = $('#ps-top-content-wrap');
	var $contributorsWrap = $('#ps-contributors-wrap');

	function loadAll() {
		var stats = Object.keys(seriesConfig).filter(function(t) { return !hiddenSeries[t]; });
		if (!stats.length) {
			if (lineChart) { lineChart.destroy(); lineChart = null; }
			return;
		}

		// Show loading state on range-aware panels
		$topContentWrap.addClass('ps-range-loading');
		$contributorsWrap.addClass('ps-range-loading');

		peepso.postJson('adminEngagementDashboard.get_graph_data', {
			date_range: activeRange,
			stats:      stats.join(',')
		}, function(response) {
			if (!response.success) return;
			buildLineChart(response.data);
			buildDonut(response.data.breakdown);
			buildHeatmap(response.data.heatmap);

			if (response.data.top_content_html) {
				$topContentWrap.html(response.data.top_content_html);
			}
			if (response.data.contributors_html) {
				$contributorsWrap.html(response.data.contributors_html);
			}

			$topContentWrap.removeClass('ps-range-loading');
			$contributorsWrap.removeClass('ps-range-loading');
		});
	}

	// ── Controls ──────────────────────────────────────────────────────────────

	$(document).on('click', '.ps-chart-range-btn', function() {
		var range = $(this).data('range');
		setActiveBtn(range);

		if (range === 'custom') {
			$('#ps-custom-range').addClass('is-visible');
			// Pre-fill with last 30 days if inputs are empty
			if (!$('#ps-range-from').val()) {
				var to   = new Date();
				var from = new Date(to.getTime() - 29 * 24 * 60 * 60 * 1000);
				$('#ps-range-from').val(toLocalDateKey(from.getTime()));
				$('#ps-range-to').val(toLocalDateKey(to.getTime()));
			}
			return; // wait for Apply
		}

		$('#ps-custom-range').removeClass('is-visible');
		activeRange = range;
		saveRange();
		loadAll();
	});

	$(document).on('click', '#ps-range-apply', function() {
		var from = $('#ps-range-from').val();
		var to   = $('#ps-range-to').val();
		if (!from || !to) return;
		activeRange = 'custom:' + from + ':' + to;
		saveRange();
		loadAll();
	});

	$(document).on('keydown', '.ps-range-input', function(e) {
		if (e.which === 13) $('#ps-range-apply').trigger('click');
	});

	$(document).on('click', '.ps-chart-toggle', function() {
		var type = $(this).data('series');
		hiddenSeries[type] = !hiddenSeries[type];
		$(this).toggleClass('ps-chart-toggle--active', !hiddenSeries[type]);
		loadAll();
	});

	restoreRange();
	loadAll();

	// ── Tab groups (Top content, At-risk, etc.) ──────────────────────────────
	// Scope to the parent <section> so switching tabs in one card doesn't
	// affect panes in another card that shares the same ps-tc-* classes.

	$(document).on('click', '.ps-tc-tab', function() {
		var $btn  = $(this);
		var pane  = $btn.data('pane');
		var $card = $btn.closest('section');

		$card.find('.ps-tc-tab').removeClass('ps-tc-tab--active');
		$btn.addClass('ps-tc-tab--active');
		$card.find('.ps-tc-pane').hide();
		$card.find('#ps-tc-' + pane).show();
	});
});
