/* global window, document, jQuery */
(function (window, document, $) {
	'use strict';

	const app = window.MailDoctorAdminApp;

	if (!app) {
		return;
	}

	const formatNumber = app.utils && typeof app.utils.formatNumber === 'function' ? app.utils.formatNumber : (value) => String(value || 0);

	const dnsStatusClasses = {
		ok: 'is-ok',
		warn: 'is-warn',
		fail: 'is-fail',
	};

	function getChartsService() {
		return app.resolve('charts');
	}

	function getPalette(chartsService) {
		if (chartsService && chartsService.palette) {
			return chartsService.palette;
		}

		return {
			accent: '#2271b1',
			danger: '#d63638',
			success: '#1d7a1d',
			warning: '#8a4b1f',
		};
	}


	function markCardReady(selector) {
		const $card = $(selector);
		if ($card.length) {
			$card.attr('aria-busy', 'false').find('.spinner').remove();
		}
	}

	function renderDnsItems(dnsItems) {
		const map = {};
		(dnsItems || []).forEach((item) => {
			if (!item || !item.key) {
				return;
			}
			map[item.key] = item;
		});

		$('#mail-doctor-status-dns [data-signal]').each(function () {
			const key = $(this).data('signal');
			const badge = $(this).find('.mail-doctor-badge');
			const item = map[key] || {};
			const classes = ['mail-doctor-badge'];
			const stateClass = dnsStatusClasses[item.status] || dnsStatusClasses.warn;

			if (stateClass) {
				classes.push(stateClass);
			}

			badge.attr('class', classes.join(' '));

			if (item.message) {
				badge.attr('title', item.message);
			} else {
				badge.removeAttr('title');
			}
		});

		markCardReady('#mail-doctor-status-dns');
	}

	function renderQueueCard(queueFormatted, queueRaw, chartsService, palette, i18n) {
		const hasFormatted = queueFormatted && typeof queueFormatted === 'object';
		const hasRaw = queueRaw && typeof queueRaw === 'object';

		const queuedDisplay = hasFormatted ? queueFormatted.queued ?? '0' : '—';
		const failedDisplay = hasFormatted ? queueFormatted.failed ?? '0' : '—';
		const quarantinedDisplay = hasFormatted ? queueFormatted.quarantined ?? '0' : '—';
		const nextLabel = hasFormatted ? queueFormatted.next || '' : '';

		const queued = hasRaw ? Number(queueRaw.queued || 0) : 0;
		const failed = hasRaw ? Number(queueRaw.failed || 0) : 0;
		const quarantined = hasRaw ? Number(queueRaw.quarantined || 0) : 0;
		const total = queued + failed + quarantined;

		$('#mail-doctor-status-queue [data-field="queueQueued"]').text(queuedDisplay);
		$('#mail-doctor-status-queue [data-field="queueFailed"]').text(failedDisplay);
		$('#mail-doctor-status-queue [data-field="queueQuarantined"]').text(quarantinedDisplay);
		$('#mail-doctor-status-queue [data-field="next"]').text(nextLabel);

		if (chartsService && typeof chartsService.update === 'function') {
			chartsService.update(
				'queue',
				[
					{ value: queued, color: palette.accent },
					{ value: failed, color: palette.danger },
					{ value: quarantined, color: palette.warning },
				],
				{
					centerText: hasRaw ? formatNumber(total) : '—',
				}
			);
		}

		let narrative = '';
		if (hasRaw) {
			if (i18n.queueNarrative) {
				narrative = i18n.queueNarrative
					.replace('%TOTAL%', formatNumber(total))
					.replace('%FAILED%', formatNumber(failed))
					.replace('%QUARANTINED%', formatNumber(quarantined));
			} else {
				narrative = `Total: ${formatNumber(total)}. Failed: ${formatNumber(failed)}. Quarantined: ${formatNumber(quarantined)}.`;
			}
		} else if (i18n.queueNarrative) {
			narrative = i18n.queueNarrative.replace('%TOTAL%', '0').replace('%FAILED%', '0').replace('%QUARANTINED%', '0');
		}

		$('#mail-doctor-status-queue [data-field="queueNarrative"]').text(narrative);
		markCardReady('#mail-doctor-status-queue');
	}

	function renderTrendSparkline(series) {
		const svg = document.querySelector('[data-field="trendChart"]');
		if (!svg) {
			return;
		}

		if (!Array.isArray(series) || !series.length) {
			svg.innerHTML = '';
			return;
		}

		const width = 160;
		const height = 60;
		let maxValue = -Infinity;
		let minValue = Infinity;
		const values = [];
		let validCount = 0;

		series.forEach((bucket) => {
			if (!bucket) {
				return;
			}
			let rate = bucket.success_rate;
			if (typeof rate !== 'number' || Number.isNaN(rate)) {
				rate = null;
			}
			if (rate === null) {
				values.push(null);
				return;
			}
			maxValue = Math.max(maxValue, rate);
			minValue = Math.min(minValue, rate);
			validCount++;
			values.push(rate);
		});

		if (!validCount) {
			svg.innerHTML = '';
			return;
		}

		if (!Number.isFinite(maxValue) || !Number.isFinite(minValue)) {
			svg.innerHTML = '';
			return;
		}

		const isFlatSeries = maxValue === minValue;
		if (isFlatSeries) {
			maxValue = minValue + 1;
		}

		const points = values.map((value, index) => {
			const x = values.length === 1 ? width : (index / (values.length - 1)) * width;
			const safeValue = value === null ? minValue : value;
			const normalized = isFlatSeries ? 0.5 : (safeValue - minValue) / (maxValue - minValue);
			const y = height - normalized * height;
			return { x, y };
		});

		let path = '';
		points.forEach((point, index) => {
			if (index === 0) {
				path = `M${point.x},${point.y}`;
			} else {
				path += ` L${point.x},${point.y}`;
			}
		});

		svg.innerHTML = '';
		const fill = document.createElementNS('http://www.w3.org/2000/svg', 'path');
		const fillPath = `${path} L${width},${height} L0,${height} Z`;
		fill.setAttribute('d', fillPath);
		fill.setAttribute('fill', 'rgba(34, 113, 177, 0.12)');
		svg.appendChild(fill);

		const stroke = document.createElementNS('http://www.w3.org/2000/svg', 'path');
		stroke.setAttribute('d', path);
		stroke.setAttribute('fill', 'none');
		stroke.setAttribute('stroke', '#2271b1');
		stroke.setAttribute('stroke-width', '2');
		svg.appendChild(stroke);
	}

	function renderTrendMeta(trend, i18n) {
		const currentEl = document.querySelector('[data-field="trendCurrent"]');
		if (currentEl) {
			if (trend && trend.current !== null && trend.current !== undefined) {
				currentEl.textContent = `${Number(trend.current).toFixed(1)}%`;
			} else {
				currentEl.textContent = '—';
			}
		}

		const deltaEl = document.querySelector('[data-field="trendDelta"]');
		if (deltaEl) {
			if (!trend || trend.delta === null || trend.delta === undefined) {
				deltaEl.textContent = '—';
				deltaEl.setAttribute('data-direction', 'flat');
			} else {
				const deltaValue = Number(trend.delta).toFixed(1);
				const sign = Number(trend.delta) > 0 ? '+' : '';
				deltaEl.textContent = `${sign}${deltaValue}%`;
				deltaEl.setAttribute('data-direction', trend.direction || 'flat');
			}
		}

		const captionEl = document.querySelector('[data-field="trendCaption"]');
		if (captionEl) {
			if (trend && trend.previous !== null && trend.previous !== undefined) {
				captionEl.textContent = i18n.trendVsPrevious || 'vs previous hour';
			} else {
				captionEl.textContent = i18n.trendNoData || 'Not enough data yet.';
			}
		}
	}

	function renderDeliveryCard(stats, statsRaw, chartsService, palette, series, trend, i18n) {
		const sentCount = Number((statsRaw && statsRaw.sent) || 0);
		const failedCount = Number((statsRaw && statsRaw.failed) || 0);
		const totalCount = Number((statsRaw && statsRaw.total) || sentCount + failedCount);
		const successRate = Number(
			stats && Object.prototype.hasOwnProperty.call(stats, 'successRate')
				? stats.successRate
				: totalCount > 0
					? (sentCount / totalCount) * 100
					: NaN
		);
		const medianLatency = Number(stats && stats.medianLatency);

		const totalDisplay = statsRaw ? formatNumber(totalCount) : '—';
		const sentDisplay = statsRaw ? formatNumber(sentCount) : '—';
		const failedDisplay = statsRaw ? formatNumber(failedCount) : '—';

		let successDisplay = '—';
		if (Number.isFinite(successRate) && successRate >= 0) {
			const decimals = successRate % 1 === 0 ? 0 : 1;
			successDisplay = `${successRate.toFixed(decimals)}%`;
		}

		let medianDisplay = '—';
		if (Number.isFinite(medianLatency) && medianLatency > 0) {
			medianDisplay = `${formatNumber(Math.round(medianLatency))} ms`;
		}

		$('#mail-doctor-status-stats [data-field="successRate"]').text(successDisplay);
		$('#mail-doctor-status-stats [data-field="medianLatency"]').text(medianDisplay);
		$('#mail-doctor-status-stats [data-field="totalCount"]').text(totalDisplay);
		$('#mail-doctor-status-stats [data-field="sentCount"]').text(sentDisplay);
		$('#mail-doctor-status-stats [data-field="failedCount"]').text(failedDisplay);

		if (chartsService && typeof chartsService.update === 'function') {
			chartsService.update(
				'delivery',
				[
					{ value: sentCount, color: palette.success },
					{ value: failedCount, color: palette.danger },
				],
				{
					centerText: successDisplay,
				}
			);
		}

		let narrative = '';
		if (statsRaw) {
			if (i18n.deliveryNarrative) {
				narrative = i18n.deliveryNarrative
					.replace('%TOTAL%', totalDisplay)
					.replace('%SENT%', sentDisplay)
					.replace('%FAILED%', failedDisplay);
			} else {
				narrative = `Total emails: ${totalDisplay}. Sent: ${sentDisplay}. Failed: ${failedDisplay}.`;
			}
		} else if (i18n.deliveryNarrative) {
			narrative = i18n.deliveryNarrative.replace('%TOTAL%', '0').replace('%SENT%', '0').replace('%FAILED%', '0');
		}

		$('#mail-doctor-status-stats [data-field="deliveryNarrative"]').text(narrative);

		renderTrendSparkline(series || []);
		renderTrendMeta(trend || {}, i18n);

		markCardReady('#mail-doctor-status-stats');
	}

	function renderQueueHealth(health, i18n) {
		const metrics = health || {};
		const avgAttempts = metrics.avgAttemptsLabel || metrics.avgAttempts || '—';
		const queuedCount = metrics.queuedCountLabel || metrics.queuedCount || '0';
		const queuedAge = metrics.oldestQueuedLabel || '';
		const quarantineCount = metrics.quarantineCountLabel || metrics.quarantineCount || '0';
		const quarantineAge = metrics.oldestQuarantineLabel || '';
		const nextRetry = metrics.nextRetryLabel || (i18n.queueNoNextRetry || 'Not scheduled');

		const avgEl = document.querySelector('[data-field="queueAvgAttempts"]');
		if (avgEl) {
			avgEl.textContent = avgAttempts;
		}

		const queuedCountEl = document.querySelector('[data-field="queueQueuedCount"]');
		if (queuedCountEl) {
			queuedCountEl.textContent = queuedCount;
		}

		const queuedAgeEl = document.querySelector('[data-field="queueQueuedAge"]');
		if (queuedAgeEl) {
			queuedAgeEl.textContent = queuedAge;
		}

		const quarantineCountEl = document.querySelector('[data-field="queueQuarantineCount"]');
		if (quarantineCountEl) {
			quarantineCountEl.textContent = quarantineCount;
		}

		const quarantineAgeEl = document.querySelector('[data-field="queueQuarantineAge"]');
		if (quarantineAgeEl) {
			quarantineAgeEl.textContent = quarantineAge;
		}

		const nextRetryEl = document.querySelector('[data-field="queueNextRetry"]');
		if (nextRetryEl) {
			nextRetryEl.textContent = nextRetry;
		}

		markCardReady('#mail-doctor-status-queue-health');
	}

	const failureSeverityClasses = {
		warning: 'is-warning',
		error: 'is-error',
		critical: 'is-critical',
		info: 'is-info',
	};

	const failureSeverityColors = {
		warning: 'rgba(255, 159, 67, 0.9)',
		error: 'rgba(214, 54, 56, 0.9)',
		critical: 'rgba(136, 0, 27, 0.9)',
		info: 'rgba(34, 113, 177, 0.85)',
	};

	function renderFailures(list, i18n) {
		const $list = $('#mail-doctor-status-failures .mail-doctor-failure-list');
		const $empty = $('#mail-doctor-status-failures [data-field="failuresEmpty"]');
		$list.empty();

		if (!Array.isArray(list) || !list.length) {
			if ($empty.length) {
				$empty.text(i18n.failuresNone || 'No recent failures detected.');
			}
			markCardReady('#mail-doctor-status-failures');
			return;
		}

		if ($empty.length) {
			$empty.text('');
		}

		list.forEach((item) => {
			if (!item) {
				return;
			}
			const severity = item.severity || 'error';
			const countLabelTemplate = i18n.failuresCount || '%s events';
			const severityLabelMap = {
				warning: i18n.failureSeverityWarning || 'Warn',
				error: i18n.failureSeverityError || 'Error',
				critical: i18n.failureSeverityCritical || 'Critical',
				info: i18n.failureSeverityInfo || 'Info',
			};

			const $item = $('<li/>', { class: 'mail-doctor-failure-item' });
			const $header = $('<div/>', { class: 'mail-doctor-failure-item__header' });
			$header.append(
				$('<span/>', {
					class: 'mail-doctor-failure-item__provider',
					text: item.provider || (i18n.failuresUnknownProvider || 'Unknown'),
				})
			);

			const badgeClasses = ['mail-doctor-failure-item__badge'];
			if (failureSeverityClasses[severity]) {
				badgeClasses.push(failureSeverityClasses[severity]);
			}

			const countLabel = countLabelTemplate.replace('%s', formatNumber(item.count || 0));
			const badgeLabel = `${severityLabelMap[severity] || severity} · ${countLabel}`;
			$header.append(
				$('<span/>', {
					class: badgeClasses.join(' '),
					text: badgeLabel,
				})
			);
			$item.append($header);

			if (item.message) {
				$item.append(
					$('<p/>', {
						class: 'mail-doctor-failure-item__message',
						text: item.message,
					})
				);
			}

			if (item.hint) {
				$item.append(
					$('<p/>', {
						class: 'mail-doctor-failure-item__hint',
						text: item.hint,
					})
				);
			}

			$list.append($item);
		});

		markCardReady('#mail-doctor-status-failures');
	}

	function renderProviders(list, i18n) {
		const $body = $('#mail-doctor-status-providers .mail-doctor-provider-table__body');
		const $empty = $('#mail-doctor-status-providers [data-field="providersEmpty"]');
		$body.empty();

		if (!Array.isArray(list) || !list.length) {
			if ($empty.length) {
				$empty.text(i18n.providersNone || 'No provider activity recorded.');
			}
			markCardReady('#mail-doctor-status-providers');
			return;
		}

		if ($empty.length) {
			$empty.text('');
		}

		list.forEach((provider) => {
			const $row = $('<tr/>');
			const $labelCell = $('<td/>');
			const $labelWrap = $('<span/>', {
				class: 'mail-doctor-provider-table__label',
				text: provider.label || '—',
			});

			if (provider.status_label) {
				const statusClasses = ['mail-doctor-provider-table__status'];
				if (provider.status) {
					statusClasses.push(`is-${provider.status}`);
				}
				$labelWrap.append(
					$('<span/>', {
						class: statusClasses.join(' '),
						text: provider.status_label,
					})
				);
			}

			$labelCell.append($labelWrap);
			$row.append($labelCell);
			$row.append($('<td/>').text(provider.success_rate_label || '—'));
			$row.append($('<td/>').text(provider.latency_label || '—'));
			$row.append($('<td/>').text(provider.volume_label || '—'));
			$body.append($row);
		});

		markCardReady('#mail-doctor-status-providers');
	}

	function renderFailureMix(list, i18n) {
		const bar = document.querySelector('[data-field="failureMixBar"]');
		const legend = document.querySelector('[data-field="failureMixLegend"]');
		const empty = document.querySelector('[data-field="failureMixEmpty"]');
		const container = document.querySelector('#mail-doctor-status-failure-mix .mail-doctor-failure-bar');

		if (!bar || !legend) {
			return;
		}

		bar.innerHTML = '';
		legend.innerHTML = '';

		if (!Array.isArray(list) || !list.length) {
			if (empty) {
				empty.textContent = i18n.failuresNone || 'No recent failures detected in the last 24 hours.';
			}
			if (container) {
				container.setAttribute('aria-label', i18n.failuresNone || 'No recent failures detected in the last 24 hours.');
			}
			markCardReady('#mail-doctor-status-failure-mix');
			return;
		}

		if (empty) {
			empty.textContent = '';
		}
		if (container) {
			const top = list[0];
			let shareLabel = '';
			if (top && top.count) {
				const shareValue = safeTotal > 0
					? (top.share !== undefined ? Number(top.share) : (Number(top.count) / safeTotal) * 100)
					: 0;
				shareLabel = `${formatNumber(Number(top.count) || 0)} (${shareValue.toFixed(1)}%)`;
			}
			const summaryLabel = top
				? `${top.provider || (i18n.failuresUnknownProvider || 'Unknown provider')} accounts for ${shareLabel || 'recent failures'}`
				: 'Failure breakdown';
			container.setAttribute('aria-label', summaryLabel);
		}

		const totalCount = list.reduce((acc, item) => acc + (item && item.count ? Number(item.count) : 0), 0);
		const safeTotal = totalCount > 0 ? totalCount : list.length;

		list.forEach((item) => {
			if (!item) {
				return;
			}
			const severity = item.severity || 'error';
			const count = Number(item.count || 0);
			const share = safeTotal > 0 ? (count / safeTotal) * 100 : 0;
			const segment = document.createElement('div');
			segment.className = 'mail-doctor-failure-bar__segment';
			segment.style.width = `${Math.max(share, 0)}%`;
			segment.style.background = failureSeverityColors[severity] || 'rgba(214, 54, 56, 0.9)';
			const label = `${item.provider || ''} — ${formatNumber(count)} (${share.toFixed(1)}%)`;
			segment.setAttribute('title', label.trim());

			if (share > 12) {
				const span = document.createElement('span');
				span.textContent = `${share.toFixed(0)}%`;
				segment.appendChild(span);
			}

			bar.appendChild(segment);

			const legendItem = document.createElement('li');
			legendItem.className = 'mail-doctor-failure-legend__item';
			const swatch = document.createElement('span');
			swatch.className = 'mail-doctor-failure-legend__swatch';
			swatch.style.background = failureSeverityColors[severity] || 'rgba(214, 54, 56, 0.9)';
			legendItem.appendChild(swatch);
			const text = document.createElement('span');
			const shareLabel = `${formatNumber(count)} · ${share.toFixed(1)}%`;
			text.textContent = `${item.provider || (i18n.failuresUnknownProvider || 'Unknown')} — ${shareLabel}`;
			legendItem.appendChild(text);
			legend.appendChild(legendItem);
		});

		markCardReady('#mail-doctor-status-failure-mix');
	}

	function renderWarnings(warnings) {
		const $warnings = $('#mail-doctor-status-warnings .mail-doctor-warning-list');
		$warnings.empty();
		(warnings || []).forEach((warning) => {
			$warnings.append($('<li/>').text(warning));
		});
		markCardReady('#mail-doctor-status-warnings');
	}

	function updateStatusCards(data) {
		const chartsService = getChartsService();
		const palette = getPalette(chartsService);
		const i18n = app.i18n || {};

		renderDnsItems(data.dns || []);
		renderQueueCard(data.queue || {}, data.queueRaw || {}, chartsService, palette, i18n);
		renderDeliveryCard(data.stats || {}, data.statsRaw || {}, chartsService, palette, data.metricsSeries && data.metricsSeries.series, data.metricsTrend, i18n);
		renderWarnings(data.warnings || []);
		renderQueueHealth(data.queueHealth || {}, i18n);
		renderFailureMix(data.failures || [], i18n);
		renderFailures(data.failures || [], i18n);
		renderProviders(data.providers || [], i18n);
	}

	function fetchStatusCards() {
		if (!$('#mail-doctor-status-dns').length || !app.ajaxUrl) {
			return;
		}

		$.post(app.ajaxUrl, {
			action: 'mail_doctor_get_status_cards',
			_wpnonce: app.nonces ? app.nonces.status : '',
		})
			.done((response) => {
				if (response && response.success) {
					updateStatusCards(response.data);
				}
			})
			.fail(() => {
				updateStatusCards({});
			});
	}

	app.provide('status', {
		refresh: fetchStatusCards,
		update: updateStatusCards,
	});

	app.register(() => {
		fetchStatusCards();
	});
})(window, document, jQuery);
