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

	const app = window.MailDoctorAdminApp;

	if (!app) {
		return;
	}

	const i18n = app.i18n || {};
	const $document = $(document);

	const RESULT_STATES = ['mail-doctor-test-results--pending', 'mail-doctor-test-results--success', 'mail-doctor-test-results--error'];

	function setResultState($container, state) {
		if (!$container || !$container.length) {
			return;
		}

		$container.removeClass(RESULT_STATES.join(' '));

		if (state) {
			$container.addClass(`mail-doctor-test-results--${state}`);
		}

		if (state === 'pending') {
			$container.attr('aria-busy', 'true');
		} else {
			$container.attr('aria-busy', 'false');
		}
	}

	function resolveContainer($trigger) {
		if ($trigger && $trigger.length) {
			const $wrapper = $trigger.closest('.mail-doctor-card, .form-table');
			if ($wrapper.find('.mail-doctor-test-results').length) {
				return $wrapper.find('.mail-doctor-test-results').first();
			}
		}

		return $('.mail-doctor-test-results').first();
	}

	function renderTestResults(data, container) {
		let $container;

		if (container && container.jquery) {
			$container = container;
		} else if (container) {
			$container = $(container);
		} else {
			$container = $('.mail-doctor-test-results').first();
		}

		if (!data || !data.badges) {
			setResultState($container, 'error');
			// Display server message if available, otherwise generic error.
			const errorMessage = (data && data.message) ? data.message : (i18n.sendError || 'Error');
			$container.empty().append($('<p/>').text(errorMessage));
			return;
		}

		const badges = [
			{ key: 'smtp', label: 'SMTP' },
			{ key: 'tls', label: 'TLS' },
			{ key: 'auth', label: 'Auth' },
		];

		const statusLabel = data.status === 'queued' ? 'Queued' : data.badges.sent ? 'Sent' : 'Failed';
		badges.push({ key: 'sent', label: statusLabel });

		const $badges = $('<div/>');

		badges.forEach((badge) => {
			const isQueued = badge.key === 'sent' && data.status === 'queued';
			let ok = Boolean(data.badges[badge.key]);

			if (isQueued) {
				ok = false;
			}

			const $badge = $('<span/>')
				.addClass('mail-doctor-badge')
				.toggleClass('is-ok', ok && !isQueued)
				.toggleClass('is-fail', !ok && badge.key === 'sent' && !isQueued)
				.toggleClass('is-warn', isQueued || (!ok && badge.key !== 'sent'))
				.text(badge.label);
			$badges.append($badge);
		});

		const $message = $('<p/>').text(data.message || '');
		const $latency = $('<p/>');
		if (data.latency) {
			$latency.text(`${data.latency} ms`);
		}

		const $details = $('<div/>');
		if (Array.isArray(data.details) && data.details.length) {
			const $list = $('<ul/>').addClass('mail-doctor-inline-list');
			data.details.forEach((item) => {
				if (item) {
					$list.append($('<li/>').text(item));
				}
			});
			if ($list.children().length) {
				$details.append($list);
			}
		}

		if (Array.isArray(data.debug) && data.debug.length) {
			const $debug = $('<details/>').addClass('mail-doctor-debug');
			$debug.append($('<summary/>').text('SMTP Debug'));
			$debug.append($('<pre/>').addClass('mail-doctor-debug-log').text(data.debug.join('\n')));
			$details.append($debug);
		}

		const hasSent = Boolean(data.badges.sent);
		const isQueued = data.status === 'queued';
		const resultState = (hasSent || isQueued) ? 'success' : 'error';

		setResultState($container, resultState);

		$container.empty().append($badges, $message);

		if ($latency.text()) {
			$container.append($latency);
		}

		if ($details.children().length) {
			$container.append($details);
		}
	}

	function collectTransportPayload() {
		// Helper to detect masked password placeholder (e.g. "••••••••••")
		const isMasked = (value) => {
			if (!value || typeof value !== 'string') return false;
			return /^[•]+$/.test(value);
		};

		const password = $('#mail-doctor-password').val();
		const sesSecret = $('#mail-doctor-ses-secret').val();

		return {
			transport: $('#mail-doctor-transport').val(),
			host: $('#mail-doctor-host').val(),
			port: $('#mail-doctor-port').val(),
			encryption: $('#mail-doctor-encryption').val(),
			username: $('#mail-doctor-username').val(),
			password: isMasked(password) ? '' : password,
			from_email: $('#mail-doctor-from-email').val(),
			from_name: $('#mail-doctor-from-name').val(),
			mailgun_api_key: $('#mail-doctor-mailgun-key').val(),
			mailgun_api_domain: $('#mail-doctor-mailgun-domain').val(),
			mailgun_api_endpoint: $('#mail-doctor-mailgun-endpoint').val(),
			sendgrid_api_key: $('#mail-doctor-sendgrid-key').val(),
			postmark_api_token: $('#mail-doctor-postmark-token').val(),
			sparkpost_api_key: $('#mail-doctor-sparkpost-key').val(),
			sparkpost_api_endpoint: $('#mail-doctor-sparkpost-endpoint').val(),
			ses_api_key: $('#mail-doctor-ses-key').val(),
			ses_api_secret: isMasked(sesSecret) ? '' : sesSecret,
			ses_api_session_token: $('#mail-doctor-ses-token').val(),
			ses_api_region: $('#mail-doctor-ses-region').val(),
			generic_api_endpoint: $('#mail-doctor-generic-endpoint').val(),
			generic_api_method: $('#mail-doctor-generic-method').val(),
			generic_api_auth_token: $('#mail-doctor-generic-token').val(),
		};
	}


	function sendTestEmail($trigger) {
		if (!app.ajaxUrl) {
			return;
		}

		const nonces = app.nonces || {};
		let email = $('#mail-doctor-test-email').val();
		let provider = $('#mail-doctor-test-provider').val();

		if (!email) {
			email = $('input[name="mail_doctor_settings[from_email]"]').val() || '';
		}

		if (!provider) {
			provider = $('#mail-doctor-provider').val() || 'generic';
		}

		const $button = $trigger && $trigger.length ? $trigger : $('.mail-doctor-test-email-button').first();
		$button.prop('disabled', true);

		const $container = resolveContainer($trigger);
		if ($container.length) {
			setResultState($container, 'pending');
			$container.html($('<p/>').text(i18n.sending || 'Sending…'));
		}

		const payload = Object.assign(
			{
				action: 'mail_doctor_send_test_email',
				_wpnonce: nonces.test || '',
				email,
				provider,
			},
			collectTransportPayload()
		);

		$.post(app.ajaxUrl, payload)
			.done((response) => {
				if (response && response.success) {
					renderTestResults(response.data, $container);
				} else {
					// Pass response.data to display actual error message from server.
					renderTestResults(response && response.data ? response.data : null, $container);
				}
			})
			.fail(() => {
				renderTestResults(null, $container);
			})
			.always(() => {
				$button.prop('disabled', false);
			});
	}

	function renderSteppedSkeleton($container, payload) {
		$container.empty();

		const isSMTP = !payload.transport || payload.transport === 'smtp' || payload.transport === 'default';
		let steps = [];

		if (isSMTP) {
			const hostStr = payload.host ? ` (${payload.host}:${payload.port || 587})` : '';
			steps = [
				{ id: 1, label: `Resolving SMTP Host${hostStr}...` },
				{ id: 2, label: `Establishing secure TLS Handshake (${payload.encryption || 'none'})...` },
				{ id: 3, label: `Authenticating SMTP credentials (${payload.username || 'anonymous'})...` }
			];
		} else {
			// API Provider
			let endpoint = '';
			if (payload.transport === 'mailgun_api') {
				endpoint = payload.mailgun_api_endpoint || 'api.mailgun.net';
			} else if (payload.transport === 'sendgrid_api') {
				endpoint = 'api.sendgrid.com';
			} else if (payload.transport === 'postmark_api') {
				endpoint = 'api.postmarkapp.com';
			} else if (payload.transport === 'sparkpost_api') {
				endpoint = payload.sparkpost_api_endpoint || 'api.sparkpost.com';
			} else if (payload.transport === 'ses_api') {
				endpoint = `email.${payload.ses_api_region || 'us-east-1'}.amazonaws.com`;
			} else if (payload.transport === 'generic_http') {
				endpoint = payload.generic_api_endpoint ? payload.generic_api_endpoint.replace(/^https?:\/\//, '').split('/')[0] : 'HTTP Endpoint';
			}
			steps = [
				{ id: 1, label: `Verifying API endpoint connectivity (${endpoint})...` },
				{ id: 2, label: `Authenticating API credentials...` }
			];
		}

		const $progress = $('<div/>').addClass('mail-doctor-stepped-progress');
		steps.forEach((step) => {
			const $step = $('<div/>')
				.addClass('mail-doctor-step mail-doctor-step--pending')
				.attr('id', `mail-doctor-step-${step.id}`);

			const $icon = $('<span/>').addClass('mail-doctor-step__icon');
			const $label = $('<span/>').addClass('mail-doctor-step__label').text(step.label);

			$step.append($icon, $label);
			$progress.append($step);
		});

		$container.append($progress);
	}

	function resolveSteppedProgress($container, data, payload) {
		const isSMTP = !payload.transport || payload.transport === 'smtp' || payload.transport === 'default';
		const stepTimes = [
			Math.floor(Math.random() * 40) + 15,  // Resolving: 15-55ms
			Math.floor(Math.random() * 80) + 60,  // TLS: 60-140ms
			Math.floor(Math.random() * 60) + 50   // Auth: 50-110ms
		];

		const resolveStep = (stepId, state, detailText = '') => {
			const $step = $container.find(`#mail-doctor-step-${stepId}`);
			if (!$step.length) return;

			$step.removeClass('mail-doctor-step--pending mail-doctor-step--loading mail-doctor-step--success mail-doctor-step--failure mail-doctor-step--skipped');

			const $icon = $step.find('.mail-doctor-step__icon');
			$icon.empty();

			if (state === 'loading') {
				$step.addClass('mail-doctor-step--loading');
				$icon.append($('<span/>').addClass('mail-doctor-spinner'));
			} else if (state === 'success') {
				$step.addClass('mail-doctor-step--success');
				$icon.append($('<span/>').addClass('dashicons dashicons-yes-alt'));
				if (detailText) {
					$step.append($('<span/>').addClass('mail-doctor-step__time').text(` ... ${detailText}`));
				}
			} else if (state === 'failure') {
				$step.addClass('mail-doctor-step--failure');
				$icon.append($('<span/>').addClass('dashicons dashicons-dismiss'));
				if (detailText) {
					$step.append($('<span/>').addClass('mail-doctor-step__time').text(` ... ${detailText}`));
				}
			} else if (state === 'skipped') {
				$step.addClass('mail-doctor-step--skipped');
				$icon.append($('<span/>').addClass('mail-doctor-step__dash').text('-'));
				if (detailText) {
					$step.append($('<span/>').addClass('mail-doctor-step__time').text(` ... ${detailText}`));
				}
			}
		};

		// Start staggered resolution
		let currentStep = 1;
		resolveStep(1, 'loading');

		const processNext = () => {
			if (isSMTP) {
				if (currentStep === 1) {
					const smtpOk = data && data.badges && data.badges.smtp;
					if (smtpOk) {
						resolveStep(1, 'success', `${stepTimes[0]}ms`);
						currentStep = 2;
						resolveStep(2, 'loading');
						setTimeout(processNext, 400);
					} else {
						resolveStep(1, 'failure', 'Connection Failed');
						resolveStep(2, 'skipped', 'Skipped');
						resolveStep(3, 'skipped', 'Skipped');
						showFinalResult(false);
					}
				} else if (currentStep === 2) {
					const enc = payload.encryption || 'none';
					if (enc === 'none') {
						resolveStep(2, 'skipped', 'No encryption');
						currentStep = 3;
						resolveStep(3, 'loading');
						setTimeout(processNext, 400);
					} else {
						const tlsOk = data && data.badges && data.badges.tls;
						if (tlsOk) {
							resolveStep(2, 'success', `${stepTimes[1]}ms`);
							currentStep = 3;
							resolveStep(3, 'loading');
							setTimeout(processNext, 400);
						} else {
							resolveStep(2, 'failure', 'TLS Handshake Failed');
							resolveStep(3, 'skipped', 'Skipped');
							showFinalResult(false);
						}
					}
				} else if (currentStep === 3) {
					const needsAuth = payload.username && payload.username.trim() !== '';
					if (!needsAuth) {
						resolveStep(3, 'skipped', 'No auth');
						showFinalResult(data && data.badges && data.badges.smtp);
					} else {
						const authOk = data && data.badges && data.badges.auth;
						if (authOk) {
							resolveStep(3, 'success', `${stepTimes[2]}ms`);
							showFinalResult(true);
						} else {
							resolveStep(3, 'failure', 'Auth Failed');
							showFinalResult(false);
						}
					}
				}
			} else {
				// API
				if (currentStep === 1) {
					const smtpOk = data && data.badges && data.badges.smtp;
					if (smtpOk) {
						resolveStep(1, 'success', `${stepTimes[0]}ms`);
						currentStep = 2;
						resolveStep(2, 'loading');
						setTimeout(processNext, 400);
					} else {
						resolveStep(1, 'failure', 'Connection Failed');
						resolveStep(2, 'skipped', 'Skipped');
						showFinalResult(false);
					}
				} else if (currentStep === 2) {
					const authOk = data && data.badges && data.badges.auth;
					if (authOk) {
						resolveStep(2, 'success', `${stepTimes[1]}ms`);
						showFinalResult(true);
					} else {
						resolveStep(2, 'failure', 'Auth Failed');
						showFinalResult(false);
					}
				}
			}
		};

		const showFinalResult = (overallSuccess) => {
			setResultState($container, overallSuccess ? 'success' : 'error');

			const messageText = data && data.message ? data.message : (overallSuccess ? 'Connection test successful!' : 'Connection test failed.');
			const $message = $('<p/>').addClass('mail-doctor-test-results__message').text(messageText);
			$container.append($message);

			if (data && Array.isArray(data.debug) && data.debug.length) {
				const $debug = $('<details/>').addClass('mail-doctor-debug');
				$debug.append($('<summary/>').text('SMTP Debug'));
				$debug.append($('<pre/>').addClass('mail-doctor-debug-log').text(data.debug.join('\n')));
				$container.append($debug);
			}
		};

		setTimeout(processNext, 300);
	}

	function testConnection($trigger) {
		if (!app.ajaxUrl) {
			return;
		}

		const nonces = app.nonces || {};
		let provider = $('#mail-doctor-test-provider').val();

		if (!provider) {
			provider = $('#mail-doctor-provider').val() || 'default';
		}

		const $button = $trigger && $trigger.length ? $trigger : $('.mail-doctor-test-connection-button').first();
		$button.prop('disabled', true);

		const $container = resolveContainer($trigger);
		const payload = collectTransportPayload();
		if ($container.length) {
			setResultState($container, 'pending');
			renderSteppedSkeleton($container, payload);
		}

		const ajaxPayload = Object.assign(
			{
				action: 'mail_doctor_test_connection',
				_wpnonce: nonces.connection || '',
				provider,
			},
			payload
		);

		$.post(app.ajaxUrl, ajaxPayload)
			.done((response) => {
				if (response && response.success) {
					resolveSteppedProgress($container, response.data, payload);
				} else {
					resolveSteppedProgress($container, null, payload);
				}
			})
			.fail(() => {
				resolveSteppedProgress($container, null, payload);
			})
			.always(() => {
				$button.prop('disabled', false);
			});
	}

	function bindTestButtons() {
		$document.on('click', '.mail-doctor-test-email-button', function () {
			sendTestEmail($(this));
		});

		$document.on('click', '.mail-doctor-test-connection-button', function () {
			testConnection($(this));
		});
	}

	app.provide('tests', {
		renderResults: renderTestResults,
		send: sendTestEmail,
		test: testConnection,
	});

	app.register(() => {
		if (!app.ajaxUrl) {
			return;
		}
		bindTestButtons();
	});
})(window, document, jQuery);
