/**
 * Broken Image Fallback - High Performance Script with Freemius Integration
 * FREE version: Basic image replacement with default fallback
 * PRO version: Advanced methods, WordPress features, fade effects
 * 
 * @version 1.0.0
 * @author Nikunj Hatkar
 */

(function() {
	'use strict';
	
	// Configuration from WordPress with FREE/PRO differentiation
	const config = window.brokimfaOptions || {
		fallbackMethod: 'default_image', // FREE: Only default image method
		defaultImageUrl: '',
		enableFade: false, // PRO feature
		fadeDuration: 300,
		lazyLoadingCompat: true,
		hideCompletely: false,
		enableFeaturedImageFallback: false, // PRO feature
		enableGutenbergSupport: false, // PRO feature
		isPro: false
	};
	
	
	// Performance optimizations
	const processedImages = new WeakSet();
	const imageCache = new Map();
	const pendingImages = new Set();
	
	// Contextual fallbacks (PRO feature)
	const contextualFallbacks = {
		'featured-image': config.featuredImageUrl || config.defaultImageUrl,
		'featured-image-placeholder': config.featuredPlaceholderUrl || config.defaultImageUrl,
		'gutenberg': config.defaultImageUrl,
		'default': config.defaultImageUrl
	};
	
	// Debounce helper for performance
	function debounce(func, wait) {
		let timeout;
		return function executedFunction(...args) {
			const later = () => {
				clearTimeout(timeout);
				func(...args);
			};
			clearTimeout(timeout);
			timeout = setTimeout(later, wait);
		};
	}
	
	// Throttle helper for scroll events
	function throttle(func, limit) {
		let inThrottle;
		return function() {
			const args = arguments;
			const context = this;
			if (!inThrottle) {
				func.apply(context, args);
				inThrottle = true;
				setTimeout(() => inThrottle = false, limit);
			}
		};
	}
	
	/**
	 * Check if image URL is accessible with caching
	 */
	function isImageAccessible(src) {
		if (imageCache.has(src)) {
			return Promise.resolve(imageCache.get(src));
		}
		
		return new Promise((resolve) => {
			const testImage = new Image();
			
			const cleanup = () => {
				testImage.onload = null;
				testImage.onerror = null;
				testImage.ontimeout = null;
			};
			
			testImage.onload = () => {
				cleanup();
				imageCache.set(src, true);
				resolve(true);
			};
			
			testImage.onerror = () => {
				cleanup();
				imageCache.set(src, false);
				resolve(false);
			};
			
			// Timeout after 5 seconds
			setTimeout(() => {
				cleanup();
				imageCache.set(src, false);
				resolve(false);
			}, 5000);
			
			testImage.src = src;
		});
	}
	
	/**
	 * Extract URL from CSS background-image property
	 */
	function extractBackgroundImageUrl(backgroundImage) {
		if (!backgroundImage || backgroundImage === 'none') {
			return null;
		}
		
		const urlMatch = backgroundImage.match(/url\(['"]?([^'")]+)['"]?\)/);
		return urlMatch ? urlMatch[1] : null;
	}
	
	

	/**
	 * Clear srcset and sizes attributes to ensure fallback image loads properly
	 */
	function clearResponsiveAttributes(img) {
		// Remove srcset to prevent browser from loading other images
		if (img.hasAttribute('srcset')) {
			img.removeAttribute('srcset');
		}
		// Remove sizes attribute as it's not needed without srcset
		if (img.hasAttribute('sizes')) {
			img.removeAttribute('sizes');
		}
		// Store original attributes for potential restoration
		if (!img.hasAttribute('data-brokimfa-original-srcset') && img.srcset) {
			img.setAttribute('data-brokimfa-original-srcset', img.srcset);
		}
		if (!img.hasAttribute('data-brokimfa-original-sizes') && img.sizes) {
			img.setAttribute('data-brokimfa-original-sizes', img.sizes);
		}
	}
	
	
	
	/**
	 * Get image context (PRO feature for advanced context detection)
	 */
	function getImageContext(img) {
		// Basic context detection for free version
		const context = img.getAttribute('data-brokimfa-context');
		if (context) {
			return context;
		}

		
		
		
		return 'default';
	}
	
	/**
	 * Handle broken image with selected method
	 */
	async function handleBrokenImage(img) {
		if (processedImages.has(img) || pendingImages.has(img)) {
			return;
		}
		
		pendingImages.add(img);
		processedImages.add(img);
		img.setAttribute('data-brokimfa-processed', 'true');
		
		try {
			const method = config.fallbackMethod;
			const context = getImageContext(img);
			
			// FREE version: Only default image method
			if (!config.isPro && method !== 'default_image') {
				console.warn('Broken Image Fallback: Advanced fallback methods are PRO features. Using default image fallback.');
				await handleDefaultImageFallback(img, context);
				return;
			}
			
			switch (method) {
				case 'default_image':
					await handleDefaultImageFallback(img, context);
					break;

				
			}
		} catch (error) {
			console.warn('Broken Image Fallback: Error processing image', error);
		} finally {
			pendingImages.delete(img);
		}
	}
	
	/**
	 * Handle default image fallback with context
	 */
	async function handleDefaultImageFallback(img, context = 'default') {
		let fallbackUrl = config.defaultImageUrl;
		
		
		
		if (!fallbackUrl) {
			return false;
		}
		
		const isAccessible = await isImageAccessible(fallbackUrl);
		if (isAccessible) {
			// Clear responsive attributes before setting new src
			clearResponsiveAttributes(img);

			img.src = fallbackUrl;
			img.setAttribute('data-brokimfa-fallback', 'default-image');
			img.setAttribute('data-brokimfa-context', context);
			img.classList.add('brokimfa-fallback-image', `brokimfa-${context}-fallback`);
			
			return true;
		}
		return false;
	}
	
	
	
	/**
	 * Handle hide fallback (PRO only)
	 */
	function handleHideFallback(img) {
		img.style.display = 'none';
		img.setAttribute('data-brokimfa-fallback', 'hidden');
	}
	
	/**
	 * Check if image is broken
	 */
	function isImageBroken(img) {
		return !img.complete || 
			   img.naturalWidth === 0 || 
			   img.naturalHeight === 0 ||
			   img.src === '' ||
			   img.src === window.location.href;
	}
	
	/**
	 * Process single image
	 */
	function processImage(img) {
		if (processedImages.has(img)) {
			return;
		}
		
		// Skip Gutenberg block images if Gutenberg support is disabled
		if (!config.enableGutenbergSupport && !config.isPro) {
			// For free version, skip all Gutenberg blocks
			if (img.closest('.wp-block-image, .wp-block-gallery, .wp-block-media-text')) {
				return;
			}
		} else if (config.isPro && !config.enableGutenbergSupport) {
			// For Pro version, skip Gutenberg blocks if the feature is disabled
			if (img.closest('.wp-block-image, .wp-block-gallery, .wp-block-media-text')) {
				return;
			}
		}
		
		if (isImageBroken(img)) {
			handleBrokenImage(img);
		} else {
			const errorHandler = (event) => {
				event.preventDefault();
				handleBrokenImage(img);
				img.removeEventListener('error', errorHandler);
			};
			
			img.addEventListener('error', errorHandler, { 
				once: true, 
				passive: false 
			});
		}
	}
	
	/**
	 * Process images in container with performance optimization
	 */
	const processImages = throttle((container = document) => {
		const images = container.querySelectorAll('img:not([data-brokimfa-processed])');
		
		if (images.length === 0) {
			return;
		}
		
		const batchSize = 10;
		let currentBatch = 0;
		
		function processBatch() {
			const start = currentBatch * batchSize;
			const end = Math.min(start + batchSize, images.length);
			
			for (let i = start; i < end; i++) {
				processImage(images[i]);
			}
			
			currentBatch++;
			
			if (end < images.length) {
				requestAnimationFrame(processBatch);
			}
		}
		
		processBatch();
	}, 100);

	
	
	/**
	 * Setup MutationObserver for dynamic content
	 */
	function setupMutationObserver() {
		if (!config.lazyLoadingCompat || !window.MutationObserver) {
			return;
		}
		
		const debouncedProcess = debounce((mutations) => {
			let hasNewImages = false;
			
			mutations.forEach(mutation => {
				if (mutation.type === 'childList') {
					mutation.addedNodes.forEach(node => {
						if (node.nodeType === Node.ELEMENT_NODE) {
							if (node.tagName === 'IMG') {
								processImage(node);
								hasNewImages = true;
							} else if (node.querySelectorAll) {
								const imgs = node.querySelectorAll('img:not([data-brokimfa-processed])');
								if (imgs.length > 0) {
									hasNewImages = true;
								}
							}
						}
					});
				} else if (mutation.type === 'attributes' && 
						  mutation.target.tagName === 'IMG' && 
						  (mutation.attributeName === 'src' || mutation.attributeName === 'data-src')) {
					
					const img = mutation.target;
					processedImages.delete(img);
					img.removeAttribute('data-brokimfa-processed');
					processImage(img);
				}
			});
			
			if (hasNewImages) {
				processImages();
				
			}
		}, 250);
		
		const observer = new MutationObserver(debouncedProcess);
		
		observer.observe(document.body, {
			childList: true,
			subtree: true,
			attributes: true,
			attributeFilter: ['src', 'data-src']
		});
		
		return observer;
	}
	
	
	
	/**
	 * Initialize the plugin
	 */
	function init() {
		try {
			// Process existing images
			processImages();
			
			
			
			// Setup observer for dynamic content
			setupMutationObserver();
			
			// Handle page visibility changes
			if (typeof document.addEventListener === 'function') {
				document.addEventListener('visibilitychange', () => {
					if (!document.hidden) {
						processImages();
						
					}
				});
			}
			
			
			
			const versionText = config.isPro ? 'Pro' : 'Free';
			console.log(`Broken Image Fallback ${versionText}: Initialized successfully`);
			
			// Show upgrade prompt for free users (non-intrusive)
			if (!config.isPro && typeof console.info === 'function') {
				console.info('🚀 Broken Image Fallback Pro: Upgrade for WordPress features, advanced methods, and fade effects!');
			}
			
		} catch (error) {
			console.error('Broken Image Fallback: Initialization failed', error);
		}
	}
	
	// Initialize when DOM is ready (non-blocking)
	if (document.readyState === 'loading') {
		document.addEventListener('DOMContentLoaded', init);
	} else {
		setTimeout(init, 0);
	}
	
	// Expose API for manual triggering (for developers)
	window.brokimfaFallback = {
		processImages: processImages,
		processImage: processImage,
		config: config,
		version: config.isPro ? 'Pro' : 'Free',
		upgrade: function() {
			if (!config.isPro) {
				console.log('Visit your WordPress admin → Image Fallback → Upgrade to Pro for advanced features!');
			}
		}
	};
	
})();