/**
 * Media Library Optimization JavaScript
 *
 * Handles client-side interactions for image optimization in Media Library
 *
 * @package ProRank\SEO
 * @since   1.0.0
 */

(function($) {
	'use strict';

	// Settings from localized script
	const settings = window.prorankMediaOptimization || {};
	const i18n = settings.i18n || {};
	const badgeQueue = [];
	const badgePendingIds = new Set();
	let badgeBatchTimer = null;

	/**
	 * Initialize media library optimization features
	 */
	function init() {
		// Bind events for list view buttons
		bindListViewEvents();

		// Bind events for attachment edit page (metabox)
		bindMetaboxEvents();

		// Bind events for media modal
		bindMediaModalEvents();

		// Watch for media library grid mode changes
		observeGridView();
	}

	/**
	 * Bind events for list view optimization buttons
	 */
	function bindListViewEvents() {
		// Optimize now button in list view column
		$(document).on('click', '.prorank-optimize-now-btn', function(e) {
			e.preventDefault();
			const $btn = $(this);
			const attachmentId = $btn.data('attachment-id');

			if ($btn.hasClass('processing')) {
				return;
			}

			optimizeImage(attachmentId, 'optimize', $btn, function(response) {
				// Refresh the column content
				refreshColumnStatus($btn.closest('td'), attachmentId, response.stats);
			});
		});
	}

	/**
	 * Bind events for metabox on attachment edit page
	 */
	function bindMetaboxEvents() {
		const $metabox = $('#prorank-attachment-optimization');

		if (!$metabox.length) {
			return;
		}

		const attachmentId = $metabox.data('attachment-id');

		// Optimize button
		$metabox.on('click', '.prorank-optimize-btn, .prorank-reoptimize-btn', function(e) {
			e.preventDefault();
			const $btn = $(this);

			if ($btn.hasClass('processing')) {
				return;
			}

			optimizeImage(attachmentId, 'optimize', $btn, function(response) {
				// Reload the page to show updated metabox
				window.location.reload();
			});
		});

		// Generate WebP only
		$metabox.on('click', '.prorank-generate-webp-btn', function(e) {
			e.preventDefault();
			const $btn = $(this);

			if ($btn.hasClass('processing')) {
				return;
			}

			optimizeImage(attachmentId, 'generate_webp', $btn, function(response) {
				window.location.reload();
			});
		});

		// Generate AVIF only
		$metabox.on('click', '.prorank-generate-avif-btn', function(e) {
			e.preventDefault();
			const $btn = $(this);

			if ($btn.hasClass('processing')) {
				return;
			}

			optimizeImage(attachmentId, 'generate_avif', $btn, function(response) {
				window.location.reload();
			});
		});

		// Restore button
		$metabox.on('click', '.prorank-restore-btn', function(e) {
			e.preventDefault();
			const $btn = $(this);

			if ($btn.hasClass('processing')) {
				return;
			}

			if (!confirm(i18n.confirmRestore || 'Are you sure you want to restore the original image?')) {
				return;
			}

			restoreImage(attachmentId, $btn, function(response) {
				window.location.reload();
			});
		});
	}

	/**
	 * Bind events for media modal
	 */
	function bindMediaModalEvents() {
		// Handle optimize button in attachment details modal
		$(document).on('click', '.prorank-optimize-modal-btn', function(e) {
			e.preventDefault();
			const $btn = $(this);
			const attachmentId = $btn.data('attachment-id');
			const $spinner = $btn.siblings('.prorank-modal-spinner');
			const $status = $btn.siblings('.prorank-modal-status');

			if ($btn.hasClass('processing')) {
				return;
			}

			$btn.addClass('processing');
			$spinner.addClass('is-active').show();
			$status.text('').removeClass('success error');

			$.ajax({
				url: settings.ajaxUrl,
				type: 'POST',
				data: {
					action: 'prorank_optimize_single_image',
					nonce: settings.nonce,
					attachment_id: attachmentId,
					action_type: 'optimize'
				},
				success: function(response) {
					if (response.success) {
						$status
							.addClass('success')
							.css('color', '#46b450')
							.text(i18n.success || 'Success!');

						// Replace button with success status
						const stats = response.data.stats || {};
						const percent = stats.percent_saved || 0;
						const saved = stats.bytes_saved_formatted || '0 KB';

						$btn.replaceWith(
							'<span class="prorank-status-optimized">' +
							'<span class="dashicons dashicons-yes-alt" style="color: #46b450;"></span> ' +
							(i18n.optimized || 'Optimized') +
							'</span> ' +
							'<span class="prorank-savings" style="color: #666;">(' + saved + ' / ' + percent + '% ' + (i18n.saved || 'saved') + ')</span>'
						);

						// Update attachment model if available
						if (wp.media && wp.media.frame) {
							const attachment = wp.media.frame.state().get('selection').get(attachmentId);
							if (attachment) {
								attachment.set('prorank_optimized', true);
							}
						}
					} else {
						$status
							.addClass('error')
							.css('color', '#dc3232')
							.text(response.data || (i18n.error || 'Error'));
						$btn.removeClass('processing');
					}
				},
				error: function(xhr, status, error) {
					$status
						.addClass('error')
						.css('color', '#dc3232')
						.text(i18n.error || 'Error');
					$btn.removeClass('processing');
				},
				complete: function() {
					$spinner.removeClass('is-active').hide();
				}
			});
		});
	}

	/**
	 * Optimize an image via AJAX
	 *
	 * @param {number} attachmentId - Attachment ID
	 * @param {string} actionType - Action type (optimize, generate_webp, generate_avif)
	 * @param {jQuery} $btn - Button element
	 * @param {Function} callback - Success callback
	 */
	function optimizeImage(attachmentId, actionType, $btn, callback) {
		const originalText = $btn.html();
		const $metabox = $btn.closest('#prorank-attachment-optimization');
		const $spinner = $metabox.find('.prorank-opt-spinner');

		$btn.addClass('processing').prop('disabled', true);

		if ($spinner.length) {
			$spinner.show();
			$spinner.find('.prorank-opt-spinner-text').text(i18n.optimizing || 'Optimizing...');
		}

		$.ajax({
			url: settings.ajaxUrl,
			type: 'POST',
			data: {
				action: 'prorank_optimize_single_image',
				nonce: settings.nonce,
				attachment_id: attachmentId,
				action_type: actionType
			},
			success: function(response) {
				if (response.success) {
					if (typeof callback === 'function') {
						callback(response.data);
					}
				} else {
					alert(response.data || (i18n.error || 'Error'));
				}
			},
			error: function(xhr, status, error) {
				alert(i18n.error || 'Error');
			},
			complete: function() {
				$btn.removeClass('processing').prop('disabled', false).html(originalText);
				if ($spinner.length) {
					$spinner.hide();
				}
			}
		});
	}

	/**
	 * Restore an image to original via AJAX
	 *
	 * @param {number} attachmentId - Attachment ID
	 * @param {jQuery} $btn - Button element
	 * @param {Function} callback - Success callback
	 */
	function restoreImage(attachmentId, $btn, callback) {
		const originalText = $btn.html();
		const $metabox = $btn.closest('#prorank-attachment-optimization');
		const $spinner = $metabox.find('.prorank-opt-spinner');

		$btn.addClass('processing').prop('disabled', true);

		if ($spinner.length) {
			$spinner.show();
			$spinner.find('.prorank-opt-spinner-text').text(i18n.restoring || 'Restoring...');
		}

		$.ajax({
			url: settings.ajaxUrl,
			type: 'POST',
			data: {
				action: 'prorank_restore_single_image',
				nonce: settings.nonce,
				attachment_id: attachmentId
			},
			success: function(response) {
				if (response.success) {
					if (typeof callback === 'function') {
						callback(response.data);
					}
				} else {
					alert(response.data || (i18n.error || 'Error'));
				}
			},
			error: function(xhr, status, error) {
				alert(i18n.error || 'Error');
			},
			complete: function() {
				$btn.removeClass('processing').prop('disabled', false).html(originalText);
				if ($spinner.length) {
					$spinner.hide();
				}
			}
		});
	}

	/**
	 * Refresh column status after optimization
	 *
	 * @param {jQuery} $cell - Table cell element
	 * @param {number} attachmentId - Attachment ID
	 * @param {Object} stats - Optimization stats
	 */
	function refreshColumnStatus($cell, attachmentId, stats) {
		if (!stats || !stats.optimized) {
			return;
		}

		let html = '<span class="prorank-badge prorank-badge-success" title="' +
			'Saved ' + stats.percent_saved + '% (' + stats.bytes_saved_formatted + ')">' +
			'<span class="dashicons dashicons-yes-alt"></span> ' + stats.percent_saved + '%';

		const formats = [];
		if (stats.webp_generated) {
			formats.push('WebP');
		}
		if (stats.avif_generated) {
			formats.push('AVIF');
		}

		if (formats.length > 0) {
			html += '<small style="display:block;font-size:10px;margin-top:2px;">' + formats.join(' · ') + '</small>';
		}

		html += '</span>';

		$cell.html(html);
	}

	/**
	 * Observe grid view for dynamically loaded images
	 */
	function observeGridView() {
		const attachmentsBrowser = document.querySelector('.attachments-browser');

		if (!attachmentsBrowser) {
			return;
		}

		// MutationObserver to watch for new attachments in grid view
		const observer = new MutationObserver(function(mutations) {
			mutations.forEach(function(mutation) {
				if (mutation.addedNodes.length > 0) {
					// Debounce badge additions
					clearTimeout(window.prorankGridBadgeTimeout);
					window.prorankGridBadgeTimeout = setTimeout(function() {
						addGridViewBadges();
					}, 500);
				}
			});
		});

		observer.observe(attachmentsBrowser, {
			childList: true,
			subtree: true
		});

		// Initial badge check
		setTimeout(addGridViewBadges, 1000);
	}

	/**
	 * Add optimization badges to grid view images
	 */
	function addGridViewBadges() {
		const $attachments = $('.attachment:not(.prorank-badge-added)');

		$attachments.each(function() {
			const $attachment = $(this);
			const attachmentId = $attachment.data('id');

			if (!attachmentId) {
				return;
			}

			if (!isImageGridAttachment($attachment)) {
				$attachment.addClass('prorank-badge-added');
				return;
			}

			queueBadgeRequest($attachment, attachmentId);
		});
	}

	/**
	 * Check whether the current grid item is an image attachment.
	 *
	 * @param {jQuery} $attachment Attachment element.
	 * @returns {boolean}
	 */
	function isImageGridAttachment($attachment) {
		return $attachment.find('.attachment-preview.type-image').length > 0;
	}

	/**
	 * Queue a stats request for a grid item.
	 * Requests are batched into a single API call after a short debounce.
	 *
	 * @param {jQuery} $attachment Attachment element.
	 * @param {number|string} attachmentId Attachment ID.
	 */
	function queueBadgeRequest($attachment, attachmentId) {
		const id = String(attachmentId);

		if (badgePendingIds.has(id)) {
			return;
		}

		badgePendingIds.add(id);
		badgeQueue.push({
			attachmentId: id,
			$attachment: $attachment
		});

		// Debounce: wait 300ms to collect all visible IDs, then fetch in one batch
		clearTimeout(badgeBatchTimer);
		badgeBatchTimer = setTimeout(flushBadgeBatch, 300);
	}

	/**
	 * Flush all queued badge requests as a single batch API call.
	 */
	function flushBadgeBatch() {
		if (badgeQueue.length === 0) {
			return;
		}

		// Take all pending jobs
		const jobs = badgeQueue.splice(0, badgeQueue.length);
		const ids = jobs.map(function(j) { return j.attachmentId; });
		const jobMap = {};
		jobs.forEach(function(j) {
			jobMap[j.attachmentId] = j.$attachment;
		});

		wp.apiFetch({
			path: '/prorank-seo/v1/images/batch-stats?ids=' + ids.join(',')
		}).then(function(response) {
			if (response && response.results) {
				Object.keys(response.results).forEach(function(id) {
					var data = response.results[id];
					var $el = jobMap[id];
					if ($el && data && data.optimized && data.stats) {
						addBadgeToGridItem($el, data.stats);
					}
					if ($el) {
						$el.addClass('prorank-badge-added');
					}
				});
			}
		}).catch(function() {
			// Ignore batch failure — badges are optional UI
		}).finally(function() {
			jobs.forEach(function(j) {
				j.$attachment.addClass('prorank-badge-added');
				badgePendingIds.delete(j.attachmentId);
			});
		});
	}

	/**
	 * Add badge to a grid view item
	 *
	 * @param {jQuery} $attachment - Attachment element
	 * @param {Object} stats - Optimization stats
	 */
	function addBadgeToGridItem($attachment, stats) {
		const $thumbnail = $attachment.find('.thumbnail');

		if (!$thumbnail.length || $thumbnail.find('.prorank-grid-optimization-badge').length) {
			return;
		}

		$thumbnail.css('position', 'relative');

		const $badge = $('<div class="prorank-grid-optimization-badge">' +
			'<span class="dashicons dashicons-yes-alt"></span> ' +
			stats.percent_saved + '%' +
			'</div>');

		$thumbnail.append($badge);
	}

	// Initialize when DOM is ready
	$(document).ready(init);

	// Also reinitialize when media modal is opened
	$(document).on('click', '.media-modal-content', function() {
		setTimeout(bindMediaModalEvents, 100);
	});

})(jQuery);
