(function () {
	'use strict';

	var admin = window.naveencodesAdmin || {};
	var numberFormatter = new window.Intl.NumberFormat();

	function request(action, data) {
		var body = new window.URLSearchParams();
		body.append('action', action);
		body.append('nonce', admin.nonce || '');

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

		return window.fetch(admin.ajaxUrl, {
			method: 'POST',
			credentials: 'same-origin',
			headers: {
				'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
			},
			body: body.toString()
		}).then(function (response) {
			return response.json();
		});
	}

	function formatBytes(bytes) {
		var value = Number(bytes || 0);
		var units = ['B', 'KB', 'MB', 'GB', 'TB'];
		var index = 0;

		while (value >= 1024 && index < units.length - 1) {
			value /= 1024;
			index += 1;
		}

		return value.toFixed(index === 0 ? 0 : 2) + ' ' + units[index];
	}

	function formatPercent(value) {
		return Number(value || 0).toFixed(2) + '%';
	}

	function updateQueueBadges(counts) {
		var mapping = {
			pending: '[data-naveencodes-count-pending]',
			processing: '[data-naveencodes-count-processing]',
			completed: '[data-naveencodes-count-completed]',
			failed: '[data-naveencodes-count-failed]'
		};

		Object.keys(mapping).forEach(function (status) {
			var node = document.querySelector(mapping[status]);

			if (!node) {
				return;
			}

			node.textContent = status.charAt(0).toUpperCase() + status.slice(1) + ': ' + Number(counts[status] || 0);
		});

		document.querySelectorAll('[data-naveencodes-status-panel-count]').forEach(function (node) {
			var status = node.getAttribute('data-naveencodes-status-panel-count');

			if (!status) {
				return;
			}

			node.textContent = Number(counts[status] || 0);
		});

		var queueTotal = document.querySelector('[data-naveencodes-queue-total]');

		if (queueTotal) {
			queueTotal.textContent = numberFormatter.format(Number(counts.pending || 0) + Number(counts.processing || 0));
		}
	}

	function updateStats(stats) {
		document.querySelectorAll('[data-naveencodes-stat]').forEach(function (node) {
			var key = node.getAttribute('data-naveencodes-stat');
			var format = node.getAttribute('data-naveencodes-stat-format');
			var value = stats && Object.prototype.hasOwnProperty.call(stats, key) ? stats[key] : 0;

			if (format === 'bytes') {
				node.textContent = formatBytes(value);
				return;
			}

			if (format === 'percent') {
				node.textContent = formatPercent(value);
				return;
			}

			node.textContent = numberFormatter.format(Number(value || 0));
		});
	}

	function setProgress(percent, counts) {
		var bar = document.querySelector('[data-naveencodes-progress-bar]');
		var percentNode = document.querySelector('[data-naveencodes-progress-percent]');
		var countsNode = document.querySelector('[data-naveencodes-progress-counts]');

		if (bar) {
			bar.style.width = Math.max(0, Math.min(100, percent)) + '%';
		}

		if (percentNode) {
			percentNode.textContent = Number(percent || 0).toFixed(2) + '%';
		}

		if (countsNode && counts) {
			countsNode.textContent = [
				'Pending: ' + Number(counts.pending || 0),
				'Processing: ' + Number(counts.processing || 0),
				'Completed: ' + Number(counts.completed || 0),
				'Failed: ' + Number(counts.failed || 0)
			].join(' | ');
		}

		updateQueueBadges(counts || {});
	}

	function setStatus(message, isError) {
		var node = document.querySelector('[data-naveencodes-status]');

		if (!node) {
			return;
		}

		node.textContent = message;
		node.classList.toggle('naveencodes-inline-error', Boolean(isError));
	}

	function updateQueueSections(sectionHtml) {
		if (!sectionHtml) {
			return;
		}

		Object.keys(sectionHtml).forEach(function (status) {
			var node = document.querySelector('[data-naveencodes-queue-section="' + status + '"]');

			if (!node) {
				return;
			}

			node.innerHTML = sectionHtml[status] || '';
		});
	}

	function setActiveStatusPanel(status) {
		document.querySelectorAll('[data-naveencodes-status-tab]').forEach(function (node) {
			var isActive = node.getAttribute('data-naveencodes-status-tab') === status;
			node.classList.toggle('is-active', isActive);
			node.setAttribute('aria-pressed', isActive ? 'true' : 'false');
		});

		document.querySelectorAll('[data-naveencodes-status-panel]').forEach(function (node) {
			var isActive = node.getAttribute('data-naveencodes-status-panel') === status;
			node.hidden = !isActive;
			node.classList.toggle('is-active', isActive);
		});
	}

	function wireStatusTabs() {
		var tabs = document.querySelectorAll('[data-naveencodes-status-tab]');

		if (!tabs.length) {
			return;
		}

		tabs.forEach(function (tab) {
			tab.addEventListener('click', function () {
				setActiveStatusPanel(tab.getAttribute('data-naveencodes-status-tab'));
			});
		});
	}

	function applyProgressPayload(payload) {
		if (!payload) {
			return;
		}

		setProgress(payload.percent || 0, payload.queue_counts || {});
		updateStats(payload.stats || {});
		updateQueueSections(payload.queue_sections_html || {});
	}

	function pollProgress() {
		if (!document.querySelector('[data-naveencodes-live-progress]')) {
			return;
		}

		window.setInterval(function () {
			request('naveencodes_get_progress', {}).then(function (response) {
				if (!response.success) {
					return;
				}

				applyProgressPayload(response.data);
			}).catch(function () {
				return null;
			});
		}, 10000);
	}

	function runBulkOptimization() {
		var button = document.querySelector('[data-naveencodes-run-bulk]');
		var running = false;

		if (!button) {
			return;
		}

		var session = admin.bulkSession || {};
		var currentCounts = admin.initialQueueCounts || {};

		function getResumeMode() {
			var scanDone = Boolean(session.scan_complete);
			var lastPage = Number(session.last_page || 0);
			var totalPages = Number(session.total_pages || 0);
			var pendingCount = Number(currentCounts.pending || 0);

			if (scanDone && pendingCount > 0) {
				return 'resume-process';
			}

			if (!scanDone && lastPage > 0 && lastPage < totalPages) {
				return 'resume-scan';
			}

			return 'fresh';
		}

		function updateButtonLabel() {
			var mode = getResumeMode();
			var labels = {
				'resume-process': admin.strings.resumeOptimization || 'Resume Optimization',
				'resume-scan': admin.strings.resumeScan || 'Resume Scan',
				'fresh': admin.strings.startBulk || 'Start Bulk Optimization'
			};

			button.textContent = labels[mode] || labels['fresh'];
		}

		function showSessionInfo() {
			var infoNode = document.querySelector('[data-naveencodes-session-info]');

			if (!infoNode) {
				return;
			}

			var mode = getResumeMode();
			var pendingCount = Number(currentCounts.pending || 0);
			var lastPage = Number(session.last_page || 0);
			var totalPages = Number(session.total_pages || 0);

			if (mode === 'resume-process') {
				infoNode.textContent = pendingCount + ' image' + (pendingCount !== 1 ? 's' : '') + ' pending from a previous run — click Resume to continue from where it stopped.';
				infoNode.hidden = false;
			} else if (mode === 'resume-scan') {
				infoNode.textContent = 'Previous scan stopped at page ' + lastPage + ' of ' + totalPages + ' — click Resume Scan to continue.';
				infoNode.hidden = false;
			} else {
				infoNode.hidden = true;
			}
		}

		function finish(message, isError) {
			running = false;
			button.disabled = false;
			button.classList.remove('naveencodes-is-loading');
			setStatus(message, isError);
			updateButtonLabel();
		}

		function processQueue() {
			request('naveencodes_process_queue_batch', {}).then(function (response) {
				if (!response.success) {
					var processError = new Error((response.data && response.data.message) || admin.strings.error);
					processError.data = response.data || {};
					throw processError;
				}

				var progress = response.data.progress || {};
				applyProgressPayload(progress);

				if ((progress.queue_counts.pending || 0) > 0 || (progress.queue_counts.processing || 0) > 0) {
					setStatus(admin.strings.processing, false);
					window.setTimeout(processQueue, 500);
					return;
				}

				finish(admin.strings.completed, false);
			}).catch(function (error) {
				finish(error.message || admin.strings.error, true);
			});
		}

		function queuePage(page) {
			request('naveencodes_start_bulk_queue', { page: page }).then(function (response) {
				if (!response.success) {
					var queueError = new Error((response.data && response.data.message) || admin.strings.error);
					queueError.data = response.data || {};
					throw queueError;
				}

				var data = response.data || {};
				applyProgressPayload(data.progress || {});

				if (data.session) {
					session = data.session;
				}

				if (!data.completed) {
					setStatus(admin.strings.queueing, false);
					queuePage(data.next_page);
					return;
				}

				setStatus(admin.strings.processing, false);
				processQueue();
			}).catch(function (error) {
				finish(error.message || admin.strings.error, true);
			});
		}

		updateButtonLabel();
		showSessionInfo();

		button.addEventListener('click', function () {
			if (running) {
				return;
			}

			var infoNode = document.querySelector('[data-naveencodes-session-info]');
			if (infoNode) {
				infoNode.hidden = true;
			}

			running = true;
			button.disabled = true;
			button.classList.add('naveencodes-is-loading');

			var mode = getResumeMode();

			if (mode === 'resume-process') {
				setStatus(admin.strings.processing, false);
				processQueue();
			} else if (mode === 'resume-scan') {
				setStatus(admin.strings.queueing, false);
				queuePage(Number(session.last_page || 0) + 1);
			} else {
				setStatus(admin.strings.queueing, false);
				queuePage(1);
			}
		});
	}

	function wirePresetCards() {
		var cards = document.querySelectorAll('[data-naveencodes-preset]');

		if (!cards.length) {
			return;
		}

		var qualityInput = document.getElementById('naveencodes-quality');
		var modeSelect = document.getElementById('naveencodes-mode');
		var smartCheckbox = document.getElementById('naveencodes-smart_compression');

		function detectPreset() {
			if (!qualityInput || !modeSelect || !smartCheckbox) {
				return 'custom';
			}

			var q = parseInt(qualityInput.value, 10);
			var m = modeSelect.value;
			var s = smartCheckbox.checked;

			if (q === 75 && m === 'lossy' && s) { return 'lossy'; }
			if (q === 82 && m === 'lossy' && s) { return 'balanced'; }
			if (q === 95 && m === 'lossless' && !s) { return 'pixel-perfect'; }

			return 'custom';
		}

		function setActiveCard(key) {
			cards.forEach(function (card) {
				card.classList.toggle('is-active', card.getAttribute('data-naveencodes-preset') === key);
			});
		}

		setActiveCard(detectPreset());

		if (qualityInput) {
			qualityInput.addEventListener('input', function () { setActiveCard(detectPreset()); });
		}

		if (modeSelect) {
			modeSelect.addEventListener('change', function () { setActiveCard(detectPreset()); });
		}

		if (smartCheckbox) {
			smartCheckbox.addEventListener('change', function () { setActiveCard(detectPreset()); });
		}

		cards.forEach(function (card) {
			card.addEventListener('click', function () {
				var key = card.getAttribute('data-naveencodes-preset');
				var quality = parseInt(card.getAttribute('data-quality'), 10);
				var mode = card.getAttribute('data-mode');
				var smart = card.getAttribute('data-smart') === '1';

				if (qualityInput) { qualityInput.value = quality; }
				if (modeSelect) { modeSelect.value = mode; }
				if (smartCheckbox) { smartCheckbox.checked = smart; }

				setActiveCard(key);
			});
		});
	}

	function wireSingleOptimize() {
		document.addEventListener('click', function (event) {
			var button = event.target.closest('[data-naveencodes-optimize-attachment]');

			if (!button) {
				return;
			}

			var attachmentId = button.getAttribute('data-attachment-id');
			var cell = button.closest('[data-naveencodes-media-cell]');
			var originalText = button.textContent;

			button.disabled = true;
			button.classList.add('naveencodes-is-loading');
			button.textContent = admin.strings.processingAttachment;

			request('naveencodes_optimize_attachment', { attachment_id: attachmentId }).then(function (response) {
				if (!response.success) {
					var attachmentError = new Error((response.data && response.data.message) || admin.strings.error);
					attachmentError.data = response.data || {};
					throw attachmentError;
				}

				if (cell && response.data && response.data.cell_html) {
					cell.innerHTML = response.data.cell_html;
				}

				applyProgressPayload(response.data.progress || {});
			}).catch(function (error) {
				if (cell && error && error.data && error.data.cell_html) {
					cell.innerHTML = error.data.cell_html;
				}

				window.alert(error.message || admin.strings.error);
				button.disabled = false;
				button.classList.remove('naveencodes-is-loading');
				button.textContent = originalText;
			});
		});
	}

	function wireSiteRegistration() {
		var button = document.querySelector('[data-naveencodes-register-site]');

		if (!button) {
			return;
		}

		button.addEventListener('click', function () {
			var originalText = button.textContent;
			var labelNode = document.querySelector('[data-naveencodes-registration-label]');
			var messageNode = document.querySelector('[data-naveencodes-registration-message]');

			button.disabled = true;
			button.classList.add('naveencodes-is-loading');
			button.textContent = admin.strings.registering;

			request('naveencodes_register_site', {}).then(function (response) {
				if (!response.success) {
					var registrationError = new Error((response.data && response.data.message) || admin.strings.error);
					registrationError.data = response.data || {};
					throw registrationError;
				}

				if (labelNode && response.data.registration) {
					labelNode.textContent = response.data.registration.status_label;
				}

				if (messageNode && response.data.registration) {
					messageNode.textContent = response.data.registration.message;
				}

				button.textContent = admin.strings.registered;
				window.setTimeout(function () {
					button.disabled = false;
					button.classList.remove('naveencodes-is-loading');
					button.textContent = 'Refresh Registration';
				}, 1200);
			}).catch(function (error) {
				button.disabled = false;
				button.classList.remove('naveencodes-is-loading');
				button.textContent = originalText;
				window.alert(error.message || admin.strings.error);
			});
		});
	}

	function wireLogClear() {
		var button = document.querySelector('[data-naveencodes-clear-logs]');

		if (!button) {
			return;
		}

		button.addEventListener('click', function () {
			if (!window.confirm(admin.strings.confirmClearLogs)) {
				return;
			}

			request('naveencodes_clear_logs', {}).then(function (response) {
				if (!response.success) {
					throw new Error(admin.strings.error);
				}

				window.location.reload();
			}).catch(function (error) {
				window.alert(error.message || admin.strings.error);
			});
		});
	}

	function wireNoticeDismiss() {
		document.addEventListener('click', function (event) {
			var notice = event.target.closest('[data-naveencodes-dismiss]');

			if (!notice || !event.target.classList.contains('notice-dismiss')) {
				return;
			}

			request('naveencodes_dismiss_notice', {
				notice_type: notice.getAttribute('data-naveencodes-dismiss') || 'donation'
			}).catch(function () {
				return null;
			});
		});
	}

	document.addEventListener('DOMContentLoaded', function () {
		runBulkOptimization();
		pollProgress();
		wireStatusTabs();
		wireSingleOptimize();
		wireSiteRegistration();
		wireLogClear();
		wireNoticeDismiss();
		wirePresetCards();
	});
}());
