/* eslint-disable */
/**
 * PeachPay Field Editor - Custom Field Types JavaScript
 * Handles scrollable text acknowledgment and signature pad functionality
 */

(function() {
	'use strict';

	// Store signature pad instances
	const signaturePads = new Map();
	
	// Track which fields have been viewed
	let viewedFields = new Set();
	
	// Track initialized elements to prevent duplicate listeners
	let initializedElements = new WeakSet();

	/**
	 * Simple debounce utility to limit function execution frequency
	 */
	function debounce(func, wait) {
		let timeout;
		return function executedFunction(...args) {
			clearTimeout(timeout);
			timeout = setTimeout(() => func.apply(this, args), wait);
		};
	}

	/**
	 * Initialize all custom field types when DOM is ready
	 */
	function init() {
		initScrollableTextFields();
		initSignatureFields();
	}

	// ===== Scrollable Text Field =====

	/**
	 * Initialize all scrollable text fields
	 * Always visible, read-only, validates on scroll to bottom
	 */
	function initScrollableTextFields() {
		const scrollableWrappers = document.querySelectorAll('.pp-scrollable-text-wrapper');

		scrollableWrappers.forEach(wrapper => {
			// Skip if already initialized
			if (initializedElements.has(wrapper)) {
				return;
			}
			initializedElements.add(wrapper);
			
			const contentWrapper = wrapper.querySelector('.pp-scrollable-content-wrapper');
			const content = wrapper.querySelector('.pp-scrollable-content');
			const indicator = wrapper.querySelector('.pp-scroll-indicator');
			const scrollableInput = wrapper.querySelector('.pp-scrollable-input');

			if (!contentWrapper || !content || !scrollableInput || !indicator) {
				return;
			}
			
			// Track user interaction per field instance
			let hasUserInteracted = false;
			
			// Mark field as interacted when user scrolls
			content.addEventListener('scroll', () => {
				hasUserInteracted = true;
				checkScrollCompletion(content, wrapper, scrollableInput, indicator);
			});
			
			// For non-scrollable content, mark as interacted on click/focus
			content.addEventListener('click', () => {
				hasUserInteracted = true;
				checkScrollCompletion(content, wrapper, scrollableInput, indicator);
			});
			
			content.addEventListener('focus', () => {
				hasUserInteracted = true;
				checkScrollCompletion(content, wrapper, scrollableInput, indicator);
			});
			
			// Check on initial load only to set initial state (no validation)
			// Use setTimeout to ensure DOM is fully rendered
			setTimeout(() => {
				// Only validate if user has interacted, otherwise just check state
				if (hasUserInteracted) {
					checkScrollCompletion(content, wrapper, scrollableInput, indicator);
				}
			}, 200);
			
			// Check on window resize (only if user has interacted)
			window.addEventListener('resize', debounce(() => {
				if (hasUserInteracted) {
					checkScrollCompletion(content, wrapper, scrollableInput, indicator);
				}
			}, 200));
		});
	}

	/**
	 * Check if user has scrolled to the bottom and mark as acknowledged
	 * This function is idempotent - calling it multiple times won't change state once validated
	 * 
	 * @param {HTMLElement} content - The scrollable content element
	 * @param {HTMLElement} wrapper - The field wrapper
	 * @param {HTMLInputElement} scrollableInput - The hidden input for validation state
	 * @param {HTMLElement} indicator - The scroll indicator element
	 */
	function checkScrollCompletion(content, wrapper, scrollableInput, indicator) {
		if (!content || !indicator || !scrollableInput) {
			return;
		}

		// Resolve input from wrapper to ensure we have the correct instance for this field
		const input = wrapper.querySelector('.pp-scrollable-input');
		if (!input || input !== scrollableInput) {
			return;
		}

		// If already validated, ensure indicator state is correct and return (idempotent)
		if (input.value === '1') {
			indicator.classList.add('pp-scroll-complete');
			indicator.innerHTML = '<span class="pp-scroll-check">✓</span><span class="pp-scroll-text">Viewed</span>';
			return;
		}

		// Calculate scroll state
		const scrollTop = Math.ceil(content.scrollTop);
		const scrollHeight = Math.ceil(content.scrollHeight);
		const clientHeight = Math.ceil(content.clientHeight);

		// Check if content is scrollable (with small tolerance for rounding)
		const isScrollable = scrollHeight > clientHeight + 1;
		
		// Allow 5px tolerance for scroll detection
		const scrollDifference = scrollHeight - (scrollTop + clientHeight);
		const isAtBottom = scrollDifference <= 5;

		// Single validation path: validate if content is not scrollable OR user scrolled to bottom
		if (!isScrollable || isAtBottom) {
			input.value = '1';
			indicator.classList.add('pp-scroll-complete');
			indicator.innerHTML = '<span class="pp-scroll-check">✓</span><span class="pp-scroll-text">Viewed</span>';
			
			// Trigger validation event for WooCommerce
			if (typeof jQuery !== 'undefined' && jQuery.fn.trigger) {
				jQuery(wrapper).trigger('update_checkout');
			}
		}
	}

	// ===== Signature Field =====

	/**
	 * Initialize all signature fields
	 */
	function initSignatureFields() {
		const signatureWrappers = document.querySelectorAll('.pp-signature-wrapper');

		signatureWrappers.forEach(wrapper => {
			// Skip if already initialized
			if (initializedElements.has(wrapper)) {
				return;
			}
			initializedElements.add(wrapper);
			
			initSignatureField(wrapper);
		});
	}

	/**
	 * Initialize a single signature field
	 * Draw-only mode - no tabs, no type mode
	 */
	function initSignatureField(wrapper) {
		const canvas = wrapper.querySelector('.pp-signature-canvas');
		const hiddenInput = wrapper.querySelector('.pp-signature-data');
		const clearBtn = wrapper.querySelector('.pp-signature-clear');

		if (!canvas || !hiddenInput) {
			return;
		}

		// Wait for SignaturePad to be available (retry mechanism for Express Checkout)
		let retryCount = 0;
		const maxRetries = 50; // 5 seconds max wait time (50 * 100ms)
		
		function tryInitSignaturePad() {
			retryCount++;
			
			// Check if SignaturePad is available
			if (typeof SignaturePad === 'undefined') {
				if (retryCount < maxRetries) {
					setTimeout(tryInitSignaturePad, 100);
				} else {
					console.warn('SignaturePad library not loaded after maximum retries');
				}
				return;
			}

			// Ensure canvas has dimensions before initializing
			const rect = canvas.getBoundingClientRect();
			if (rect.width === 0 || rect.height === 0) {
				if (retryCount < maxRetries) {
					setTimeout(tryInitSignaturePad, 100);
				} else {
					console.warn('Signature canvas has no dimensions after maximum retries');
				}
				return;
			}

			// Ensure canvas is actually in the DOM and visible
			if (!canvas.isConnected || canvas.offsetParent === null) {
				if (retryCount < maxRetries) {
					setTimeout(tryInitSignaturePad, 100);
				} else {
					console.warn('Signature canvas not in DOM or hidden after maximum retries');
				}
				return;
			}

			// Initialize SignaturePad
			const signaturePad = new SignaturePad(canvas, {
				backgroundColor: 'rgb(255, 255, 255)',
				penColor: 'rgb(0, 0, 0)'
			});

			// Store reference for later use
			const fieldName = wrapper.dataset.field;
			signaturePads.set(fieldName, signaturePad);

			// Resize canvas on init
			resizeCanvas(canvas, signaturePad);

			// Handle canvas resize (with debouncing to avoid conflicts)
			let resizeTimeout;
			const handleResize = () => {
				clearTimeout(resizeTimeout);
				resizeTimeout = setTimeout(() => {
					resizeCanvas(canvas, signaturePad);
				}, 200);
			};
			window.addEventListener('resize', handleResize);

			// Update hidden input when signature changes
			signaturePad.addEventListener('endStroke', () => {
				updateSignatureData(signaturePad, hiddenInput, canvas);
				
				// Trigger validation event for WooCommerce
				if (typeof jQuery !== 'undefined' && jQuery.fn.trigger) {
					jQuery(wrapper).trigger('update_checkout');
				}
			});

			// Clear button handler
			if (clearBtn) {
				clearBtn.addEventListener('click', () => {
					signaturePad.clear();
					hiddenInput.value = '';
					canvas.classList.remove('pp-has-signature');
					
					// Trigger validation event for WooCommerce
					if (typeof jQuery !== 'undefined' && jQuery.fn.trigger) {
						jQuery(wrapper).trigger('update_checkout');
					}
				});
			}
		}

		// Start initialization with retry mechanism
		tryInitSignaturePad();
	}

	/**
	 * Resize canvas to fit container while maintaining quality
	 */
	function resizeCanvas(canvas, signaturePad) {
		// Skip if canvas has no dimensions
		const rect = canvas.getBoundingClientRect();
		if (rect.width === 0 || rect.height === 0) {
			return;
		}

		// Save current signature data if it exists
		let savedData = null;
		if (signaturePad && !signaturePad.isEmpty()) {
			savedData = signaturePad.toDataURL('image/png');
		}

		const ratio = Math.max(window.devicePixelRatio || 1, 1);
		canvas.width = rect.width * ratio;
		canvas.height = rect.height * ratio;
		canvas.getContext('2d').scale(ratio, ratio);

		// Restore signature data if it existed, otherwise clear
		if (signaturePad) {
			if (savedData) {
				// Restore the signature after resize
				const img = new Image();
				img.onload = () => {
					const ctx = canvas.getContext('2d');
					ctx.drawImage(img, 0, 0, rect.width, rect.height);
					signaturePad.fromDataURL(savedData);
				};
				img.src = savedData;
			} else {
				// Clear only if there was no signature
				signaturePad.clear();
			}
		}
	}

	/**
	 * Update hidden input with signature data
	 */
	function updateSignatureData(signaturePad, hiddenInput, canvas) {
		if (!signaturePad.isEmpty()) {
			hiddenInput.value = signaturePad.toDataURL('image/png');
			canvas.classList.add('pp-has-signature');
		} else {
			hiddenInput.value = '';
			canvas.classList.remove('pp-has-signature');
		}
	}


	// ===== Express Checkout Support =====

	/**
	 * Reinitialize fields when express checkout modal opens
	 * This is called when Express Checkout page loads, clearing all state
	 */
	function reinitForExpressCheckout() {
		// Clear existing signature pad instances
		signaturePads.clear();
		
		// Clear viewed fields state for fresh start
		viewedFields = new Set();
		
		// Clear initialized elements tracking (create new WeakSet)
		initializedElements = new WeakSet();

		// Reinitialize all fields
		initScrollableTextFields();
		initSignatureFields();
	}

	/**
	 * Setup observers for dynamic content and WooCommerce events
	 * Must wait for document.body to exist
	 */
	function setupDynamicObserver() {
		// Only run if document.body exists
		if (!document.body) {
			// Try again after a short delay
			setTimeout(setupDynamicObserver, 50);
			return;
		}
		
		// Also initialize when WooCommerce updates checkout
		document.body.addEventListener('updated_checkout', init);

		// Support for dynamically loaded content
		const observer = new MutationObserver((mutations) => {
			mutations.forEach((mutation) => {
				if (mutation.addedNodes.length) {
					mutation.addedNodes.forEach((node) => {
						if (node.nodeType === 1) {
							if (node.classList && (
								node.classList.contains('pp-scrollable-text-wrapper') ||
								node.classList.contains('pp-signature-wrapper')
							)) {
								init();
							} else if (node.querySelector) {
								const customFields = node.querySelectorAll('.pp-scrollable-text-wrapper, .pp-signature-wrapper');
								if (customFields.length) {
									init();
								}
							}
						}
					});
				}
			});
		});

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

	// Expose for express checkout integration
	window.peachpayFieldTypes = {
		init: init,
		reinit: reinitForExpressCheckout
	};

	// Initialize on DOM ready
	if (document.readyState === 'loading') {
		document.addEventListener('DOMContentLoaded', function() {
			init();
			setupDynamicObserver();
		});
	} else {
		init();
		setupDynamicObserver();
	}

})();

