// source --> https://evolutionpowertools.bg/wp-content/plugins/fusion-pay-tbi/includes/../assets/js/tbi_product.min.js?ver=1764850986 
const FPTBI_ORIGIN = 'https://beta.tbibank.support';
const fptbi_maxChecks = 10;
const fptbi_intervalTime = 1000;

let fptbi_buttonEvent = false;
let fptbi_windowEvent = false;
let fptbi_formEvent = false;

let fptbi_checkCount = 0;

// TBI API configuration
const TBI_API_CONFIG = {
	UAT_URL: 'https://tbi-uat.online/admin-0071/merchant_settings/render-button',
	PROD_URL: 'https://beta.tbibank.support/admin-30cffb5df303275a2c4ce4fa7d19c8ed/merchant_settings/render-button',
	TIMEOUT: 10000
};


const fptbi_interval = setInterval( () => {
    fptbi_checkCount++;

    if (fptbi_buttonEvent && fptbi_windowEvent && fptbi_formEvent) {
        clearInterval(fptbi_interval);
    } else if (fptbi_checkCount >= fptbi_maxChecks) {
        clearInterval(fptbi_interval);
    } else {
    	tbiHandler();
    }
}, fptbi_intervalTime);

document.addEventListener("DOMContentLoaded", function() {
	
	tbiHandler();
	
	// Setup event delegation for click events (works with Elementor dynamic content)
	setupEventDelegation();
	
	// Setup MutationObserver as fallback for late-rendered content
	setupMutationObserver();
  
});

function tbiHandler() {

	let iframe = getByID('tbi_popup_iframe');

	if(getByID('tbi_button') != null && getByID('tbi_button')!=undefined){

		let tbi_container = getByID('tbi_button_container');
		let tbi_button = getByID('tbi_button');
		let tbi_popup = getByID('tbi_popup_container');
		let tbi_loading = getByID('tbi_loading');

		let form = document.querySelector('form.cart');
		if(document.querySelector('.woobt-wrap') !== null){
			form = document.querySelector('.entry-summary');
		}

		let tbi_current_cart = getFormData('form.cart');
		let tbi_current_price = getByID('tbi_button_body').getAttribute('data-price');
		let tbi_current_quantity = tbi_current_cart.quantity;
		let tbi_current_variation = tbi_current_cart.variation_id || 0;
		let tbi_delivery_limit = getByID('tbi_button_body').getAttribute('data-delivery-limit');
		let tbi_delivery_fee = getByID('tbi_button_body').getAttribute('data-delivery-fee');

		if(form && !fptbi_formEvent) {

			form.addEventListener("click", delay((e)=>{

				let new_cart = getFormData('form.cart');

				let tbi_actual_delivery = 0;
				if(tbi_current_price*new_cart.quantity < tbi_delivery_limit) {
					tbi_actual_delivery = tbi_delivery_fee;
				}

				let calculate_price = parseFloat(tbi_current_price * new_cart.quantity) + parseFloat(tbi_actual_delivery);

				if(calculate_price>30000 || calculate_price < getByID('tbi_button_body').getAttribute('data-visible')){
					tbi_container.style.maxHeight = "0";
					tbi_container.style.display = "none";
				}
				else {
					tbi_container.style.maxHeight = "250px";
					tbi_container.style.display = "flex";
				}

				if( new_cart.variation_id == undefined || new_cart.variation_id == 0 ) {
					iframe.src = "";
					tbi_loading.style.display = 'block';

					if( new_cart.quantity != tbi_current_quantity) {
						// Use API call instead of local calculation
						updateButtonWithAPI(tbi_current_price, new_cart.quantity, tbi_actual_delivery);
						tbi_current_quantity = new_cart.quantity;
					} 
				} else {
						// Only update if variation actually changed
						if(new_cart.variation_id != tbi_current_variation) {
							iframe.src = "";
							tbi_loading.style.display = 'block';

							tbi_current_price = getByID('tbi_button_body').getAttribute('data-'+new_cart.variation_id);
							// Use API call instead of local calculation
							updateButtonWithAPI(tbi_current_price, new_cart.quantity, tbi_actual_delivery);
							tbi_current_quantity = new_cart.quantity;
							tbi_current_variation = new_cart.variation_id;
						}
				}

			},500));

			form.addEventListener("change", delay((e) => {

				let new_cart = getFormData('form.cart');

				let tbi_actual_delivery = 0;
				if(tbi_current_price * new_cart.quantity < tbi_delivery_limit) {
					tbi_actual_delivery = tbi_delivery_fee;
				}

				let calculate_price = parseFloat(tbi_current_price*new_cart.quantity)+parseFloat(tbi_actual_delivery);

				if(calculate_price>30000 || calculate_price < getByID('tbi_button_body').getAttribute('data-visible')){
					tbi_container.style.maxHeight = "0";
				}
				else {
					tbi_container.style.maxHeight = "250px";
				}

				if( new_cart.variation_id == undefined || new_cart.variation_id == 0 ) {
					
					iframe.src = "";
					tbi_loading.style.display = 'block';

					if( new_cart.quantity != tbi_current_quantity) {
						// Use API call instead of local calculation
						updateButtonWithAPI(tbi_current_price, new_cart.quantity, tbi_actual_delivery);
						tbi_current_quantity = new_cart.quantity;
					} 
				} else {
						// Only update if variation or quantity changed
						if(new_cart.variation_id != tbi_current_variation || new_cart.quantity != tbi_current_quantity) {
							iframe.src = "";
							tbi_loading.style.display = 'block';

							tbi_current_price = getByID('tbi_button_body').getAttribute('data-'+new_cart.variation_id);
							// Use API call instead of local calculation
							updateButtonWithAPI(tbi_current_price, new_cart.quantity, tbi_actual_delivery);
							tbi_current_quantity = new_cart.quantity;
							tbi_current_variation = new_cart.variation_id;
						}
				}

			},500));
			fptbi_formEvent = true;
		}

		if(fptbi_buttonEvent === false) {
			tbi_button.addEventListener("click", (e)=>{
				e.preventDefault();
				e.stopPropagation();

				if (document.querySelector('form.cart .out-of-stock') !== null) {
					alert(getByID('tbi_button_body').getAttribute('data-alert1'));
					return;
				}

				if (iframe.getAttribute('src') === "") {
					let data = getFormData('form.cart');
					//check for wcpa plugin. If its used, use the price from frontend due to limitations in the backend for taking the correct price
					if(document.querySelector('.wcpa_total .price_value') != null){
						data.wcpa_price = document.querySelector('.wcpa_total .price_value').textContent.trim().replace(',', '.');
					}
					data = Object.fromEntries(
					  Object.entries(data).filter(([key]) => 
						!key.startsWith('fishinggear') && !key.startsWith('xts') && !key.startsWith('wd')
					  )
					);
					data.action = 'process_tbi_product'; // This should match the action in your add_action() call in PHP
					if (getByID('tbi_button_body').getAttribute('data-variable') == 1 && (!data.variation_id || data.variation_id == 0)) {
						alert(getByID('tbi_button_body').getAttribute('data-alert'));
					} else {
						tbi_popup.style.display = "flex";
						document.body.style.overflow = "hidden";
						// Adjusted fetch request for WP AJAX
						const fetchTimeout = (url, options, timeout = 30000) => {
							return Promise.race([
								fetch(url, options),
								new Promise((_, reject) =>
									setTimeout(() => reject(new Error('Request timed out')), timeout)
								)
							]);
						};
						
						// Build URLSearchParams manually to handle arrays properly
						const formParams = new URLSearchParams();
						for (const [key, value] of Object.entries(data)) {
							if (Array.isArray(value)) {
								// For arrays, add each value separately with the same key
								value.forEach(arrayValue => {
									formParams.append(key, arrayValue);
								});
							} else {
								formParams.append(key, value);
							}
						}
						
						fetchTimeout(myAjax.ajaxurl, { // 'myAjax.ajaxurl' should be localized in your WordPress enqueuing script
							method: 'POST',
							headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8' }, // WP AJAX expects URL encoded form data
							body: formParams.toString() // Use our manually built parameters
						})
						.then(response => response.json())
						.then(response => {
							if (response.success) {
								console.log(response.data.url);
								let iframeUrl = response.data.url;
								
								// Check if modal configuration is stored and add query parameters
								const modalSection = iframe.getAttribute('data-modal-section');
								const mode = iframe.getAttribute('data-mode');
								const schemeId = iframe.getAttribute('data-scheme-id');
								const defaultInstallments = iframe.getAttribute('data-default-installments');
								const defaultInstallmentAmount = iframe.getAttribute('data-default-installment-amount');
								
								// Build query parameters
								const params = [];
								
								// If scheme_id is present, use "selected" as modal_section
								if (schemeId) {
									params.push('modal_section=selected');
									params.push('scheme_id=' + encodeURIComponent(schemeId));
								} else if (modalSection) {
									// Use the modal_section from API (promo/buyer)
									params.push('modal_section=' + encodeURIComponent(modalSection));
								}
								
								if (mode) {
									params.push('mode=' + encodeURIComponent(mode));
								}
								
								if (defaultInstallments) {
									params.push('default_installments=' + encodeURIComponent(defaultInstallments));
								}
								
								if (defaultInstallmentAmount) {
									params.push('default_installment_amount=' + encodeURIComponent(defaultInstallmentAmount));
								}
								
								// Append parameters to URL if any exist
								if (params.length > 0) {
									const separator = iframeUrl.includes('?') ? '&' : '?';
									iframeUrl += separator + params.join('&');
								}
								
								iframe.src = iframeUrl; // Set the iframe URL with all parameters
							} else {
								throw new Error(response.data.message); // Handling error message from WP AJAX
							}
							tbi_loading.style.display = 'none';
						})
						.catch(error => {
							console.error('Error:', error);
							iframe.src = FPTBI_ORIGIN + '/application/error/error_notified/?merchant=' + window.location.href;
							tbi_loading.style.display = 'none';
						});
					}
				} else {
					tbi_popup.style.display = "flex";
					document.body.style.overflow = "hidden";
				}
			});
			fptbi_buttonEvent = true;
		}
		
		if(!fptbi_windowEvent) {
			iframe.addEventListener("click", (e) => {
				e.stopPropagation();
			});
			window.addEventListener("click", (e) => {
				tbi_popup.style.display="none";
				document.body.style.overflow = "auto";
			});
		
			window.addEventListener('message', (e) => {
			if (e.origin === FPTBI_ORIGIN) {
				try {

					const jsonObject = JSON.parse(e.data);
					let redirect_base = getByID('tbi_popup_container').getAttribute('data-redirect');

					if ( redirect_base.indexOf('?') > -1 ){
						redirect_base = redirect_base + '&order-received='+jsonObject.order_id + '&key=' + jsonObject.wc_key;
					}
					else {
						redirect_base = redirect_base + '/order-received/' + jsonObject.order_id + '/?key=' + jsonObject.wc_key;	
					}

					if(jsonObject.command === "allow_close") {
						window.addEventListener('click', (e)=>{
							window.location = redirect_base;
						});
					}
					if (jsonObject.command === "close" && jsonObject.order_id!=undefined) {
							window.location = redirect_base;
					}				
					if(jsonObject.command === "close" && jsonObject.order_id==undefined ){
						tbi_popup.style.display = 'none';
						document.body.style.overflow = "auto";
					}
					if(jsonObject.command === "close_calculator" && jsonObject.order_id==undefined ){
						tbi_popup.style.display = 'none';
						document.body.style.overflow = "auto";
					}					

					if (jsonObject.scheme_id !== undefined || jsonObject.downpayment !== undefined) {
						// First, set session data via AJAX
						fetch(myAjax.ajaxurl, {
							method: 'POST',
							headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
							body: new URLSearchParams({
								action: 'set_tbi_session_data',
								scheme_id: jsonObject.scheme_id,
								downpayment: jsonObject.downpayment
							})
						})
						.then(res => res.json())
						.then(response => {
							if (response.success) {
								// Now submit the native WooCommerce form
								tbi_popup.style.display = 'none';
								document.body.style.overflow = "auto";
					
								const addToCartButton = document.querySelectorAll('button[type="submit"].single_add_to_cart_button');

								if (addToCartButton.length){
									addToCartButton.item(0).click();
								}		
							} else {
								alert('Failed to store financing info.');
							}
						})
						.catch(error => {
							console.error('Error setting session data:', error);
							alert('An error occurred while storing financing info.');
						});
					}
					
					
					  
				} catch (error) {
				  console.error('Invalid JSON string:', error);
				}
			  }
			});
			fptbi_windowEvent = true;
		}
	}	

}

/**
 * Calculate installments using TBI API
 * @param {number} amount - The amount to calculate installments for
 * @returns {Promise<Object|null>} Promise resolving to calculation data or null on failure
 */
async function tbiCalculateInstallments(amount) {
	try {
		// Check if myAjax is available
		if (typeof myAjax === 'undefined' || !myAjax.ajaxurl) {
			console.error('WordPress AJAX URL not available');
			return null;
		}

		// Prepare request data as URLSearchParams for WordPress AJAX
		const formData = new URLSearchParams();
		formData.append('action', 'tbi_calculate_installments_ajax');
		formData.append('amount', amount.toFixed(2));

		// Make API request through WordPress AJAX
		const response = await fetch(myAjax.ajaxurl, {
			method: 'POST',
			headers: {
				'Content-Type': 'application/x-www-form-urlencoded'
			},
			body: formData.toString()
		});

		if (!response.ok) {
			throw new Error(`HTTP error! status: ${response.status}`);
		}

		const data = await response.json();
		
		if (data.success && data.data) {
			return {
				success: true,
				button_text: data.data.button_text,
				installment: data.data.installment_amount,
				period: data.data.installments,
				modal_section: data.data.modal_section,
				mode: data.data.mode,
				amount: data.data.amount,
				scheme_id: data.data.scheme_id,
				default_installments: data.data.default_installments,
				default_installment_amount: data.data.default_installment_amount
			};
		} else {
			console.log('TBI API returned error:', data.data?.message || 'Unknown error');
			return null;
		}
	} catch (error) {
		console.error('TBI API Error:', error);
		return null;
	}
}

/**
 * Update button label with API data or fallback to local calculation
 * @param {number} price - Base price
 * @param {number} quantity - Quantity
 * @param {number} delivery - Delivery fee
 */
async function updateButtonWithAPI(price, quantity, delivery) {
	const totalAmount = parseFloat(price * quantity) + parseFloat(delivery);
	
	// Show loading state
	showTBIButtonLoading();
	
	try {
		// Try to get data from API first
		const apiData = await tbiCalculateInstallments(totalAmount);
		
		if (apiData && apiData.success) {
			// Use API data
			updateButtonWithAPIData(apiData);
		} else {
			// Fallback to local calculation
			const bnplLimit = getByID('tbi_button_body').getAttribute('data-hide-bnpl');
			if (totalAmount <= bnplLimit) {
				bnplLabel(price, quantity, delivery);
			} else {
				posLabel(price, quantity, delivery);
			}
		}
	} finally {
		// Hide loading state regardless of success or failure
		hideTBIButtonLoading();
	}
}

/**
 * Update button label with API response data
 * @param {Object} apiData - Data from TBI API
 */
function updateButtonWithAPIData(apiData) {
	const buttonLine = document.querySelector('#tbi_button .tbi_button_line:nth-of-type(2)');
	
	if (!buttonLine) return;
	
	let label = '';
	
	// Use button_text directly from API if available
	if (apiData.button_text) {
		label = apiData.button_text;
	} else {
		// Fallback to constructing label from installment data
		const eur = getByID('tbi_button_body').getAttribute('data-eur') || 1;
		const installment = parseFloat(apiData.installment).toFixed(2);
		const eurInstallment = parseFloat(installment / eur).toFixed(2);
		
		label = 'installments starting from {installment} ({eur_installment} €)/month';
		label = label.replace('{installment}', installment);
		label = label.replace('{eur_installment}', eurInstallment);
		label = label.replace('{installments}', apiData.period);
	}
	
	// Update the button text
	buttonLine.innerHTML = '';
	buttonLine.innerText = label;
	// Remove the original text attribute since we have new content
	buttonLine.removeAttribute('data-original-text');
	
	// Store modal configuration on iframe for later use
	const iframe = getByID('tbi_popup_iframe');
	if (iframe && apiData) {
		// Store modal_section
		if (apiData.modal_section) {
			const modalSection = apiData.modal_section.toLowerCase();
			if (modalSection === 'buyer' || modalSection === 'promo') {
				iframe.setAttribute('data-modal-section', modalSection);
			} else {
				iframe.removeAttribute('data-modal-section');
			}
		}
		
		// Store mode
		if (apiData.mode) {
			iframe.setAttribute('data-mode', apiData.mode);
		}
		
		// Store scheme_id
		if (apiData.scheme_id) {
			iframe.setAttribute('data-scheme-id', apiData.scheme_id);
		}
		
		// Store default_installments
		if (apiData.default_installments) {
			iframe.setAttribute('data-default-installments', apiData.default_installments);
		}
		
		// Store default_installment_amount
		if (apiData.default_installment_amount) {
			iframe.setAttribute('data-default-installment-amount', apiData.default_installment_amount);
		}
	}
}

/**
 * Show loading effect on TBI button
 */
function showTBIButtonLoading() {
	const buttonLine = document.querySelector('#tbi_button .tbi_button_line:nth-of-type(2)');
	const tbiButton = getByID('tbi_button');
	
	if (buttonLine) {
		// Store original text
		buttonLine.setAttribute('data-original-text', buttonLine.innerText);
		// Show loading text with animation
		buttonLine.innerHTML = '<span class="tbi-loading">Calculating... <span class="tbi-dots">⠋</span></span>';
		
		// Add loading class to button
		if (tbiButton) {
			tbiButton.classList.add('loading');
		}
		
		// Start loading animation
		startLoadingAnimation();
	}
}

/**
 * Hide loading effect on TBI button
 */
function hideTBIButtonLoading() {
	const buttonLine = document.querySelector('#tbi_button .tbi_button_line:nth-of-type(2)');
	const tbiButton = getByID('tbi_button');
	
	if (buttonLine) {
		// Stop loading animation
		stopLoadingAnimation();
		
		// Remove loading class from button
		if (tbiButton) {
			tbiButton.classList.remove('loading');
		}
		
		// Restore original text if no new content was set
		const originalText = buttonLine.getAttribute('data-original-text');
		if (originalText && buttonLine.innerHTML.includes('tbi-loading')) {
			buttonLine.innerText = originalText;
		}
		
		// Remove the stored original text
		buttonLine.removeAttribute('data-original-text');
	}
}

/**
 * Start loading dots animation
 */
function startLoadingAnimation() {
	const dots = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
	let index = 0;
	
	// Clear any existing animation
	stopLoadingAnimation();
	
	window.tbiLoadingInterval = setInterval(() => {
		const dotsElement = document.querySelector('.tbi-dots');
		if (dotsElement) {
			dotsElement.textContent = dots[index];
			index = (index + 1) % dots.length;
		} else {
			// Stop animation if element no longer exists
			stopLoadingAnimation();
		}
	}, 100);
}

/**
 * Stop loading dots animation
 */
function stopLoadingAnimation() {
	if (window.tbiLoadingInterval) {
		clearInterval(window.tbiLoadingInterval);
		window.tbiLoadingInterval = null;
	}
}

	
function getByID(el){
	return document.getElementById(el);
}

function exists(el){
	if(getByID(el)!=undefined)return true;
	return false;
}

function getFormData(className) {
  let form = document.querySelector(className);
  const formData = {};

  for (let i = 0; i < form.elements.length; i++) {
    const element = form.elements[i];
    
    if (element.name && element.value) {
      // Handle checkboxes and multiple select fields with array names (ending with [])
      if (element.name.endsWith('[]')) {
        // Check if element is checked (for checkboxes/radio) or selected (for select options)
        if ((element.type === 'checkbox' || element.type === 'radio') && !element.checked) {
          continue; // Skip unchecked checkboxes/radio buttons
        }
        
        // Initialize array if it doesn't exist
        if (!formData[element.name]) {
          formData[element.name] = [];
        }
        
        // Add value to array
        formData[element.name].push(element.value);
      } else {
        // Handle regular form fields
        formData[element.name] = element.value;
      }
    }
  }

	const [labels, price] = getExtraDetails();

  if(labels !== "" || price > 0) {
      formData['extra_name'] = labels;
      formData['extra_price'] = price;
  }

  return formData;
}

function fptbi_updateButton() {

}

function posLabel( price, quantity, delivery ) {
	let eur = getByID('tbi_button_body').getAttribute('data-eur') ?? 1;
	let new_total = parseFloat(price*quantity) + parseFloat(delivery);
	let new_label = getByID('tbi_button_body').getAttribute('data-label');
	let multiplier = 0;
	let period = 0;
	let tier1 = getByID('tbi_button_body').getAttribute('data-t1-limit');
	let tier2 = getByID('tbi_button_body').getAttribute('data-t2-limit');
	let tier3 = getByID('tbi_button_body').getAttribute('data-t3-limit');

	if( new_total < tier1 ) {
		period = getByID('tbi_button_body').getAttribute('data-t1');
		multiplier = getByID('tbi_button_body').getAttribute('data-f1');
	}
	if( new_total >= tier1 && new_total < tier2 ) {
		period = getByID('tbi_button_body').getAttribute('data-t2');
		multiplier = getByID('tbi_button_body').getAttribute('data-f2');
	}
	if( new_total >= tier2 && new_total <= tier3 ) {
		period = getByID('tbi_button_body').getAttribute('data-t3');
		multiplier = getByID('tbi_button_body').getAttribute('data-f3');							
	}

	let new_installment = parseFloat(multiplier*new_total).toFixed(2);
	new_label = new_label.replace('{installment}', new_installment);
	new_label = new_label.replace('{eur_installment}', parseFloat(new_installment/eur).toFixed(2));
	new_label = new_label.replace('{installments}', period);
	
	const buttonLine = document.querySelector('#tbi_button .tbi_button_line:nth-of-type(2)');
	if (buttonLine) {
		// Clear any loading content and set new text
		buttonLine.innerHTML = '';
		buttonLine.innerText = new_label;
		// Remove the original text attribute since we have new content
		buttonLine.removeAttribute('data-original-text');
	}
}

function bnplLabel( price, quantity, delivery ) {
	let eur = getByID('tbi_button_body').getAttribute('data-eur') ?? 1;

	let new_price = parseFloat(price * quantity) + parseFloat(delivery);

	let new_label = getByID('tbi_button_body').getAttribute('data-label-bnpl');
	let new_installment = parseFloat( Math.ceil( new_price / 4 - 0.5 ) ).toFixed(2);
	new_label = new_label.replace('{installment}', new_installment);
	new_label = new_label.replace('{installments}', 4);
	new_label = new_label.replace('{eur_installment}', parseFloat( new_installment/eur ).toFixed(2));

	const buttonLine = document.querySelector('#tbi_button .tbi_button_line:nth-of-type(2)');
	if (buttonLine) {
		// Clear any loading content and set new text
		buttonLine.innerHTML = '';
		buttonLine.innerText = new_label;
		// Remove the original text attribute since we have new content
		buttonLine.removeAttribute('data-original-text');
	}
}

function delay(callback, ms) {
  var timer = 0;
  return function() {
    var context = this, args = arguments;
    clearTimeout(timer);
    timer = setTimeout(function() {
      callback.apply(context, args);
      callbackExecuted = true;
    }, ms || 0);
  };
}

function getExtraDetails() {
    const checkedInputs = document.querySelectorAll('.tmcp-field-wrap input:checked');
    let accumulatedLabels = "";
    let totalExtraPrice = 0;
    checkedInputs.forEach(input => {
        const parentWrap = input.closest('.tmcp-field-wrap');
        if (parentWrap) {
            const priceElement = parentWrap.querySelector('.price');
            const labelElement = parentWrap.querySelector('.tm-label');
            if (priceElement && labelElement) {
                const price = priceElement.textContent.trim();
                const label = labelElement.textContent.trim();
                accumulatedLabels += label + ', ';
                totalExtraPrice += parseFloat(price) || 0; 
            }
        }
    });

    accumulatedLabels = accumulatedLabels.replace(/, $/, '');

    return [accumulatedLabels, totalExtraPrice];
}

/**
 * Setup event delegation for TBI button clicks
 * Works with dynamically loaded content (Elementor, AJAX, etc.)
 */
function setupEventDelegation() {
	// Use event delegation on document.body to catch clicks on dynamically added elements
	document.body.addEventListener('click', function(e) {
		// Check if clicked element is #tbi_button or #tbi_button_body or inside them
		const tbiButton = e.target.closest('#tbi_button, #tbi_button_body');
		
		if (tbiButton) {
			e.preventDefault();
			e.stopPropagation();
			
			// Get required elements
			const iframe = getByID('tbi_popup_iframe');
			const tbi_popup = getByID('tbi_popup_container');
			const tbi_loading = getByID('tbi_loading');
			
			// If required elements don't exist yet, try to initialize
			if (!iframe || !tbi_popup) {
				console.log('TBI popup elements not found, attempting initialization...');
				tbiHandler();
				return;
			}
			
			// Check for out of stock
			if (document.querySelector('form.cart .out-of-stock') !== null) {
				const alertMsg = getByID('tbi_button_body')?.getAttribute('data-alert1') || 'Product is out of stock';
				alert(alertMsg);
				return;
			}
			
			// If iframe needs to be loaded
			if (iframe.getAttribute('src') === "" || !iframe.getAttribute('src')) {
				let data = getFormData('form.cart');
				
				// Check for wcpa plugin
				if(document.querySelector('.wcpa_total .price_value') != null){
					data.wcpa_price = document.querySelector('.wcpa_total .price_value').textContent.trim().replace(',', '.');
				}
				
				// Filter out unnecessary data
				data = Object.fromEntries(
					Object.entries(data).filter(([key]) => 
						!key.startsWith('fishinggear') && !key.startsWith('xts') && !key.startsWith('wd')
					)
				);
				data.action = 'process_tbi_product';
				
				// Check if variable product and no variation selected
				const buttonBody = getByID('tbi_button_body');
				if (buttonBody && buttonBody.getAttribute('data-variable') == 1 && (!data.variation_id || data.variation_id == 0)) {
					const alertMsg = buttonBody.getAttribute('data-alert') || 'Please select product variation';
					alert(alertMsg);
					return;
				}
				
				// Show popup and loading
				tbi_popup.style.display = "flex";
				document.body.style.overflow = "hidden";
				if (tbi_loading) tbi_loading.style.display = 'block';
				
				// Fetch timeout helper
				const fetchTimeout = (url, options, timeout = 30000) => {
					return Promise.race([
						fetch(url, options),
						new Promise((_, reject) =>
							setTimeout(() => reject(new Error('Request timed out')), timeout)
						)
					]);
				};
				
				// Build URLSearchParams manually to handle arrays properly
				const formParams = new URLSearchParams();
				for (const [key, value] of Object.entries(data)) {
					if (Array.isArray(value)) {
						value.forEach(arrayValue => {
							formParams.append(key, arrayValue);
						});
					} else {
						formParams.append(key, value);
					}
				}
				
				// Make AJAX request
				fetchTimeout(myAjax.ajaxurl, {
					method: 'POST',
					headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8' },
					body: formParams.toString()
				})
				.then(response => response.json())
				.then(response => {
					if (response.success) {
						let iframeUrl = response.data.url;
						
						// Check if modal configuration is stored and add query parameters
						const modalSection = iframe.getAttribute('data-modal-section');
						const mode = iframe.getAttribute('data-mode');
						const schemeId = iframe.getAttribute('data-scheme-id');
						const defaultInstallments = iframe.getAttribute('data-default-installments');
						const defaultInstallmentAmount = iframe.getAttribute('data-default-installment-amount');
						
						// Build query parameters
						const params = [];
						
						if (schemeId) {
							params.push('modal_section=selected');
							params.push('scheme_id=' + encodeURIComponent(schemeId));
						} else if (modalSection) {
							params.push('modal_section=' + encodeURIComponent(modalSection));
						}
						
						if (mode) params.push('mode=' + encodeURIComponent(mode));
						if (defaultInstallments) params.push('default_installments=' + encodeURIComponent(defaultInstallments));
						if (defaultInstallmentAmount) params.push('default_installment_amount=' + encodeURIComponent(defaultInstallmentAmount));
						
						// Append parameters to URL
						if (params.length > 0) {
							const separator = iframeUrl.includes('?') ? '&' : '?';
							iframeUrl += separator + params.join('&');
						}
						
						iframe.src = iframeUrl;
					} else {
						throw new Error(response.data.message);
					}
					if (tbi_loading) tbi_loading.style.display = 'none';
				})
				.catch(error => {
					console.error('Error:', error);
					iframe.src = FPTBI_ORIGIN + '/application/error/error_notified/?merchant=' + window.location.href;
					if (tbi_loading) tbi_loading.style.display = 'none';
				});
			} else {
				// Just show the popup if iframe already loaded
				tbi_popup.style.display = "flex";
				document.body.style.overflow = "hidden";
			}
		}
	});
}

/**
 * Setup MutationObserver to detect when TBI button is added to DOM
 * Useful for Elementor and other page builders that inject content after load
 */
function setupMutationObserver() {
	// Only setup if button doesn't exist yet
	if (getByID('tbi_button') || getByID('tbi_button_body')) {
		return; // Button already exists
	}
	
	const observer = new MutationObserver(function(mutations) {
		// Check if tbi_button or tbi_button_body was added
		for (let mutation of mutations) {
			if (mutation.addedNodes.length > 0) {
				// Check if any added node contains or is the TBI button
				for (let node of mutation.addedNodes) {
					if (node.nodeType === 1) { // Element node
						if (node.id === 'tbi_button' || node.id === 'tbi_button_body' ||
							node.querySelector('#tbi_button') || node.querySelector('#tbi_button_body')) {
							console.log('TBI button detected in DOM, initializing...');
							tbiHandler();
							// Don't disconnect - element might be re-added by Elementor
							break;
						}
					}
				}
			}
		}
	});
	
	// Observe the entire document for added nodes
	observer.observe(document.body, {
		childList: true,
		subtree: true
	});
};