/**
 * Promo SDK JavaScript
 *
 * @package PromoSDK
 */

(function() {
	'use strict';

	// Namespace to avoid conflicts.
	window.PromoSDK = window.PromoSDK || {};

	/**
	 * Modal Controller - Manages multiple product instances
	 */
	PromoSDK.Modal = {
		/**
		 * Modal instances by product slug
		 */
		instances: {},

		/**
		 * Initialize all modal instances
		 */
		init: function() {
			var self = this;
			
			// Find all PromoSDKData_* variables in window
			for ( var key in window ) {
				if ( key.indexOf( 'PromoSDKData_' ) === 0 ) {
					var productSlug = key.replace( 'PromoSDKData_', '' );
					var sdkData = window[key];
					
					if ( sdkData && sdkData.productSlug ) {
						self.initInstance( sdkData.productSlug, sdkData );
					}
				}
			}
		},

		/**
		 * Initialize a single product instance
		 */
		initInstance: function( productSlug, sdkData ) {
			var modalId = 'promo-sdk-modal-' + productSlug;
			var element = document.getElementById( modalId );

			if ( ! element ) {
				return;
			}

			var instance = {
				element: element,
				productSlug: productSlug,
				promoId: element.getAttribute( 'data-promo-id' ),
				sdkData: sdkData
			};

			this.instances[productSlug] = instance;
			this.bindEvents( instance );
			this.bindProBadges( instance );
		},

		/**
		 * Bind event listeners for an instance
		 */
		bindEvents: function( instance ) {
			var self = this;

			// Close button click.
			var closeBtn = instance.element.querySelector( '.ps-modal-close' );
			if ( closeBtn ) {
				closeBtn.addEventListener( 'click', function( e ) {
					e.preventDefault();
					self.dismiss( instance );
				});
			}

			// Overlay click.
			var overlay = instance.element.querySelector( '.ps-modal-overlay' );
			if ( overlay ) {
				overlay.addEventListener( 'click', function( e ) {
					e.preventDefault();
					self.dismiss( instance );
				});
			}

			// ESC key press - close all visible modals.
			document.addEventListener( 'keyup', function( e ) {
				if ( 27 === e.keyCode ) {
					for ( var slug in self.instances ) {
						if ( self.isVisible( self.instances[slug] ) ) {
							self.dismiss( self.instances[slug] );
						}
					}
				}
			});
		},

		/**
		 * Bind Pro badge click events for an instance
		 */
		bindProBadges: function( instance ) {
			var self = this;
			var productSlug = instance.productSlug;
			
			if ( ! productSlug ) {
				return;
			}
			
			// Listen for clicks on Pro badges with data-promo-product attribute
			document.addEventListener( 'click', function( e ) {
				var target = e.target;
				var element = target;
				
				// Check up to 3 levels of parents
				for ( var i = 0; i < 3; i++ ) {
					if ( ! element ) break;
					
					// Only trigger if element has matching data-promo-product attribute
					var promoProduct = element.getAttribute( 'data-promo-product' );
					
					if ( promoProduct && promoProduct === productSlug ) {
						e.preventDefault();
						e.stopPropagation();
						
						self.show( instance );
						return;
					}
					
					element = element.parentElement;
				}
			});
		},

		/**
		 * Populate modal with promo data
		 */
		populate: function( instance, promoData ) {
			if ( ! instance || ! instance.element ) {
				return;
			}

			// If no promo data or API failed, use fallback defaults
			if ( ! promoData ) {
				this.setFallbackContent( instance );
				return;
			}

			// Handle both old flat structure and new nested structure
			var popupData = promoData.popup || promoData;

			// Set promo ID
			instance.promoId = promoData.id;
			instance.element.setAttribute( 'data-promo-id', promoData.id );

			// Set title
			var titleEl = instance.element.querySelector( '.ps-modal-title-text' );
			if ( titleEl ) {
				titleEl.innerHTML = popupData.title || promoData.popup_title || 'Unlock All Features!';
			}

			// Set CTA text
			var ctaTextEl = instance.element.querySelector( '.ps-modal-cta-text-content' );
			var ctaTextContainer = instance.element.querySelector( '.ps-modal-cta-text' );
			if ( ctaTextEl ) {
				var ctaText = popupData.cta_text || promoData.popup_cta_text;
				if ( ctaText ) {
					ctaTextEl.innerHTML = ctaText;
					if ( ctaTextContainer ) {
						ctaTextContainer.style.display = 'block';
					}
				} else if ( ctaTextContainer ) {
					ctaTextContainer.style.display = 'none';
				}
			}

			// Set percentage badge
			var percentageBadge = instance.element.querySelector( '.ps-percentage-badge' );
			var percentageText = instance.element.querySelector( '.ps-percentage-text' );
			if ( percentageText && (popupData.percentage_off || promoData.popup_percentage_off) ) {
				percentageText.textContent = popupData.percentage_off || promoData.popup_percentage_off;
				if ( percentageBadge ) {
					percentageBadge.style.display = 'inline-flex';
				}
			}

			// Set button
			var buttonEl = instance.element.querySelector( '.ps-cta-button' );
			if ( buttonEl ) {
				// Handle both old flat structure and new nested structure
				var popupData = promoData.popup || promoData;
				
				buttonEl.textContent = popupData.button_text || promoData.popup_button_text || 'Get Pro';
				buttonEl.href = popupData.button_url || promoData.popup_button_url || '#';
				
				// Get colors from data or use SDK defaults from data attributes
				var textColor = popupData.button_text_color || promoData.popup_button_text_color;
				var bgColor = popupData.button_bg_color || promoData.popup_button_bg_color;
				
				// If no color provided (null/empty), use SDK defaults from template
				if ( ! textColor ) {
					textColor = buttonEl.getAttribute( 'data-default-text' ) || '#FFFFFF';
				}
				if ( ! bgColor ) {
					bgColor = buttonEl.getAttribute( 'data-default-bg' ) || '#085DF2';
				}
				
				// Apply colors with !important to override any CSS
				buttonEl.style.setProperty('color', textColor, 'important');
				buttonEl.style.setProperty('background-color', bgColor, 'important');
				buttonEl.style.setProperty('background', bgColor, 'important');
				
				// Also set as regular properties for fallback
				buttonEl.style.color = textColor;
				buttonEl.style.backgroundColor = bgColor;
				buttonEl.style.background = bgColor;
			}

			// Set demo link
			var demoLink = instance.element.querySelector( '.ps-demo-link' );
			if ( demoLink && (popupData.button_url || promoData.popup_button_url) ) {
				demoLink.href = popupData.button_url || promoData.popup_button_url;
			}

			// Set countdown - hide if no countdown data
			var countdownEl = instance.element.querySelector( '.ps-countdown' );
			if ( countdownEl ) {
				if ( promoData.countdown_end_time ) {
					countdownEl.setAttribute( 'data-end-time', promoData.countdown_end_time );
					countdownEl.style.display = 'flex';
					// Start countdown
					PromoSDK.Countdown.start( countdownEl, promoData.countdown_end_time );
				} else {
					// Hide countdown if no end time
					countdownEl.style.display = 'none';
				}
			}
		},

		/**
		 * Set fallback content when API fails
		 */
		setFallbackContent: function( instance ) {
			if ( ! instance || ! instance.element ) {
				return;
			}

			// Set default title
			var titleEl = instance.element.querySelector( '.ps-modal-title-text' );
			if ( titleEl ) {
				titleEl.innerHTML = 'Unlock All Features!';
			}

			// Show CTA text with default message
			var ctaTextEl = instance.element.querySelector( '.ps-modal-cta-text-content' );
			var ctaTextContainer = instance.element.querySelector( '.ps-modal-cta-text' );
			if ( ctaTextEl && ctaTextContainer ) {
				ctaTextEl.innerHTML = 'Upgrade to Pro and get access to all premium features';
				ctaTextContainer.style.display = 'block';
			}

			// Set default button
			var buttonEl = instance.element.querySelector( '.ps-cta-button' );
			if ( buttonEl ) {
				buttonEl.textContent = 'Get Pro';
				buttonEl.href = '#';
				
				var textColor = buttonEl.getAttribute( 'data-default-text' ) || '#FFFFFF';
				var bgColor = buttonEl.getAttribute( 'data-default-bg' ) || '#085DF2';
				
				buttonEl.style.setProperty('color', textColor, 'important');
				buttonEl.style.setProperty('background-color', bgColor, 'important');
				buttonEl.style.setProperty('background', bgColor, 'important');
			}

			// Hide countdown
			var countdownEl = instance.element.querySelector( '.ps-countdown' );
			if ( countdownEl ) {
				countdownEl.style.display = 'none';
			}
		},

		/**
		 * Show modal for a specific instance
		 */
		show: function( instance ) {
			var self = this;
			
			if ( ! instance ) {
				return;
			}
			
			// Re-check for modal element in case it was added after init
			if ( ! instance.element ) {
				var modalId = 'promo-sdk-modal-' + instance.productSlug;
				instance.element = document.getElementById( modalId );
				if ( instance.element ) {
					instance.promoId = instance.element.getAttribute( 'data-promo-id' );
					this.bindEvents( instance );
				}
			}
			
			if ( ! instance.element ) {
				var attempts = 0;
				var maxAttempts = 50; // 5 seconds
				
				// Wait for modal to be added to DOM (it's rendered in admin_footer)
				var checkInterval = setInterval( function() {
					attempts++;
					var modalId = 'promo-sdk-modal-' + instance.productSlug;
					instance.element = document.getElementById( modalId );
					
					if ( instance.element ) {
						clearInterval( checkInterval );
						instance.promoId = instance.element.getAttribute( 'data-promo-id' );
						self.bindEvents( instance );
						self.showModal( instance );
					} else if ( attempts >= maxAttempts ) {
						clearInterval( checkInterval );
					}
				}, 100 );
				
				return;
			}

			this.showModal( instance );
		},

		/**
		 * Actually show the modal (internal method)
		 */
		showModal: function( instance ) {
			// Always populate modal - either with real data or fallback
			if ( instance.sdkData && instance.sdkData.promoData ) {
				this.populate( instance, instance.sdkData.promoData );
			} else {
				// No promo data available, use fallback
				this.setFallbackContent( instance );
			}

			instance.element.style.display = 'flex';
			instance.element.setAttribute( 'aria-hidden', 'false' );
			document.body.style.overflow = 'hidden';
		},

		/**
		 * Hide modal
		 */
		hide: function( instance ) {
			if ( ! instance || ! instance.element ) {
				return;
			}

			instance.element.style.display = 'none';
			instance.element.setAttribute( 'aria-hidden', 'true' );
			document.body.style.overflow = '';
		},

		/**
		 * Dismiss modal and save state
		 */
		dismiss: function( instance ) {
			this.hide( instance );
			this.saveDismissState( instance );
		},

		/**
		 * Check if modal is visible
		 */
		isVisible: function( instance ) {
			return instance && instance.element && 'none' !== instance.element.style.display;
		},

		/**
		 * Check if user dismissed modal
		 */
		isDismissed: function( instance ) {
			if ( ! instance || ! instance.promoId ) {
				return false;
			}

			var dismissKey = 'promo_sdk_dismissed_' + instance.promoId;
			var dismissedTime = localStorage.getItem( dismissKey );

			if ( ! dismissedTime ) {
				return false;
			}

			// Check if dismiss duration has expired.
			var dismissDuration = instance.sdkData ? instance.sdkData.dismissDuration : 604800;
			var currentTime = Math.floor( Date.now() / 1000 );
			var dismissedTimestamp = parseInt( dismissedTime, 10 );

			if ( ( currentTime - dismissedTimestamp ) > dismissDuration ) {
				// Dismiss duration expired, remove and show again.
				localStorage.removeItem( dismissKey );
				return false;
			}

			return true;
		},

		/**
		 * Save dismiss state to localStorage
		 */
		saveDismissState: function( instance ) {
			if ( ! instance || ! instance.promoId ) {
				return;
			}

			var dismissKey = 'promo_sdk_dismissed_' + instance.promoId;
			var currentTime = Math.floor( Date.now() / 1000 );
			localStorage.setItem( dismissKey, currentTime.toString() );
		}
	};

	/**
	 * Notice Controller
	 */
	PromoSDK.Notice = {
		/**
		 * Initialize notice
		 */
		init: function() {
			this.checkPageVisibility();
			this.bindEvents();
		},

		/**
		 * Check if notice should be visible on current page
		 */
		checkPageVisibility: function() {
			// Get ALL notices (multiple plugins may have notices)
			var notices = document.querySelectorAll( '.ps-notice' );
			
			if ( ! notices || notices.length === 0 ) {
				return;
			}

			// Get current page from URL
			var urlParams = new URLSearchParams( window.location.search );
			var currentPage = urlParams.get( 'page' ) || '';

			// If no current page, don't show any notices
			if ( ! currentPage ) {
				return;
			}

			// Check each notice independently
			notices.forEach( function( notice ) {
				// Ensure notice is hidden by default
				notice.style.display = 'none';

				// Get configuration from data attributes
				var specificPages = notice.getAttribute( 'data-specific-pages' ) || '';
				var pluginPageSlug = notice.getAttribute( 'data-plugin-page-slug' ) || '';

				// Debug logging
				if ( window.console && window.console.log ) {
					console.log( '[Promo SDK] Checking notice for plugin:', pluginPageSlug );
					console.log( '[Promo SDK] Specific Pages:', specificPages );
				}

				// If no specific pages configured, show on all pages containing plugin slug
				if ( ! specificPages || specificPages.trim() === '' ) {
					if ( currentPage.indexOf( pluginPageSlug ) !== -1 ) {
						if ( window.console && window.console.log ) {
							console.log( '[Promo SDK] Showing notice for ' + pluginPageSlug + ' (no specific pages, matches plugin slug)' );
						}
						notice.style.display = 'block';
					}
					return;
				}

				// Check if current page matches any specific page
				var specificPagesArray = specificPages.split( ',' ).map( function( page ) {
					return page.trim();
				});

				var shouldShow = false;
				var matchedPage = '';
				
				for ( var i = 0; i < specificPagesArray.length; i++ ) {
					var pageSlug = specificPagesArray[i];
					
					// Exact match only (no partial matching to avoid false positives)
					if ( currentPage === pageSlug ) {
						shouldShow = true;
						matchedPage = pageSlug;
						break;
					}
				}

				// Debug logging
				if ( window.console && window.console.log ) {
					if ( shouldShow ) {
						console.log( '[Promo SDK] Showing notice for ' + pluginPageSlug + ' (matched: ' + matchedPage + ')' );
					} else {
						console.log( '[Promo SDK] Hiding notice for ' + pluginPageSlug + ' (no match found)' );
					}
				}

				if ( shouldShow ) {
					notice.style.display = 'block';
				}
			});
		},

		/**
		 * Bind event listeners
		 */
		bindEvents: function() {
			var self = this;

			// WordPress notice dismiss button.
			jQuery( document ).on( 'click', '.ps-notice .notice-dismiss', function( e ) {
				var notice = jQuery( this ).closest( '.ps-notice' );
				var promoId = notice.data( 'promo-id' );

				if ( promoId ) {
					self.dismiss( promoId );
				}
			});
		},

		/**
		 * Dismiss notice via AJAX
		 */
		dismiss: function( promoId ) {
			// Find the SDK data for this notice
			var sdkData = null;
			
			// Try to find PromoSDKData_* variable for this promo
			for ( var key in window ) {
				if ( key.indexOf( 'PromoSDKData_' ) === 0 ) {
					var data = window[key];
					if ( data && data.promoData && data.promoData.id == promoId ) {
						sdkData = data;
						break;
					}
				}
			}
			
			// Fallback to first available SDK data if not found
			if ( ! sdkData ) {
				for ( var key in window ) {
					if ( key.indexOf( 'PromoSDKData_' ) === 0 ) {
						sdkData = window[key];
						break;
					}
				}
			}
			
			// If still no SDK data, try legacy PromoSDKData
			if ( ! sdkData && window.PromoSDKData ) {
				sdkData = window.PromoSDKData;
			}
			
			if ( ! sdkData || ! sdkData.ajaxUrl || ! sdkData.nonce ) {
				console.error( 'PromoSDK: No SDK data found for dismiss' );
				return;
			}

			var ajaxData = {
				action: 'dismiss_promo_notice',
				promo_id: promoId,
				_wpnonce: sdkData.nonce
			};

			jQuery.post( sdkData.ajaxUrl, ajaxData, function( response ) {
				if ( response.success ) {
					jQuery( '.ps-notice[data-promo-id="' + promoId + '"]' ).fadeOut();
				}
			});
		}
	};

	/**
	 * Countdown Controller
	 */
	PromoSDK.Countdown = {
		/**
		 * Active timers
		 */
		timers: {},

		/**
		 * Initialize all countdowns
		 */
		init: function() {
			this.startAll();
		},

		/**
		 * Start all countdown elements
		 */
		startAll: function() {
			var self = this;
			var countdowns = document.querySelectorAll( '.ps-countdown, .ps-countdown-inline' );

			countdowns.forEach( function( element ) {
				var endTime = element.getAttribute( 'data-end-time' );
				if ( endTime ) {
					self.start( element, endTime );
				}
			});
		},

		/**
		 * Start countdown for element
		 */
		start: function( element, endTime ) {
			var self = this;

			try {
				var endDate = new Date( endTime );
				
				if ( isNaN( endDate.getTime() ) ) {
					console.error( 'PromoSDK: Invalid end time format:', endTime );
					return;
				}

				// Update immediately.
				self.update( element, endDate );

				// Update every second.
				var timerId = setInterval( function() {
					var shouldContinue = self.update( element, endDate );
					if ( ! shouldContinue ) {
						clearInterval( timerId );
						self.stop( element );
					}
				}, 1000 );

				// Store timer ID.
				this.timers[ element.id || Math.random() ] = timerId;
			} catch ( error ) {
				console.error( 'PromoSDK Countdown Error:', error );
			}
		},

		/**
		 * Update countdown display
		 */
		update: function( element, endDate ) {
			var now = new Date();
			var remaining = Math.floor( ( endDate - now ) / 1000 );

			if ( 0 >= remaining ) {
				return false;
			}

			// Calculate time units.
			var days = Math.floor( remaining / ( 3600 * 24 ) );
			var hours = Math.floor( ( remaining % ( 3600 * 24 ) ) / 3600 );
			var minutes = Math.floor( ( remaining % 3600 ) / 60 );
			var seconds = remaining % 60;

			// Update DOM elements.
			var daysEl = element.querySelector( '[data-unit="days"]' );
			var hoursEl = element.querySelector( '[data-unit="hours"]' );
			var minutesEl = element.querySelector( '[data-unit="minutes"]' );
			var secondsEl = element.querySelector( '[data-unit="seconds"]' );

			if ( daysEl ) daysEl.textContent = String( days ).padStart( 2, '0' );
			if ( hoursEl ) hoursEl.textContent = String( hours ).padStart( 2, '0' );
			if ( minutesEl ) minutesEl.textContent = String( minutes ).padStart( 2, '0' );
			if ( secondsEl ) secondsEl.textContent = String( seconds ).padStart( 2, '0' );

			return true;
		},

		/**
		 * Stop countdown and hide component
		 */
		stop: function( element ) {
			// Hide the countdown element.
			element.style.display = 'none';

			// Hide parent modal or notice if countdown expired.
			var modal = element.closest( '.ps-modal' );
			if ( modal ) {
				modal.style.display = 'none';
			}

			var notice = element.closest( '.ps-notice' );
			if ( notice ) {
				notice.style.display = 'none';
			}
		}
	};

	/**
	 * Initialize on DOM ready
	 */
	if ( 'loading' === document.readyState ) {
		document.addEventListener( 'DOMContentLoaded', function() {
			PromoSDK.Modal.init();
			PromoSDK.Notice.init();
			PromoSDK.Countdown.init();
		});
	} else {
		PromoSDK.Modal.init();
		PromoSDK.Notice.init();
		PromoSDK.Countdown.init();
	}

	/**
	 * Global helper function for easy access
	 */
	window.showPromoModal = function() {
		if ( window.PromoSDK && window.PromoSDK.Modal ) {
			window.PromoSDK.Modal.show();
		} else {
			console.error( 'PromoSDK not loaded' );
		}
	};

})();
