<?php
/**
 * Frontend Class.
 *
 * @package SmartWait_Animated_Preloader
 */

// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

/**
 * Class SWAP_Frontend.
 */
class SWAP_Frontend {

	/**
	 * Constructor.
	 */
	public function __construct() {
		add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_frontend_assets' ) );
		add_action( 'wp_body_open', array( $this, 'render_preloader' ) );
		// Fallback if theme doesn't support wp_body_open.
		add_action( 'wp_footer', array( $this, 'render_preloader_fallback' ) );
	}

	/**
	 * Check if preloader should display.
	 *
	 * @return boolean
	 */
	public function should_display() {
		$settings = SWAP_Helpers::get_settings();

		if ( 'none' === $settings['active_preloader_type'] ) {
			return false;
		}

		if ( 'homepage' === $settings['display_rule'] && ! is_front_page() ) {
			return false;
		}

		return true;
	}

	/**
	 * Enqueue frontend assets.
	 */
	public function enqueue_frontend_assets() {
		if ( ! $this->should_display() ) {
			return;
		}

		wp_enqueue_style( 'swap-frontend-css', SWAP_URL . 'resources/css/frontend.css', array(), SWAP_VERSION );
		wp_enqueue_style( 'swap-spinners-css', SWAP_URL . 'resources/css/spinners.css', array(), SWAP_VERSION );
		wp_enqueue_script( 'swap-frontend-js', SWAP_URL . 'resources/js/frontend.js', array(), SWAP_VERSION, true );

		// Pass settings to JS.
		$settings = SWAP_Helpers::get_settings();
		wp_localize_script(
			'swap-frontend-js',
			'swapVars',
			array(
				'activeType'      => isset( $settings['active_preloader_type'] ) ? esc_js( $settings['active_preloader_type'] ) : 'none',
				'loadingText'     => esc_js( $settings['loading_text'] ),
				'showPercentage'  => esc_js( $settings['show_percentage'] ),
				'showProgressBar' => esc_js( $settings['show_progress_bar'] ),
				'fadeSpeed'       => absint( $settings['fade_out_speed'] ),
				'minTime'         => absint( $settings['min_display_time'] ),
				'delay'           => absint( $settings['show_delay'] ),
				'transition'      => esc_js( $settings['transition_effect'] ),
				'logoWait'        => isset( $settings['logo_wait_anim'] ) ? esc_js( $settings['logo_wait_anim'] ) : 'no',
				'logoSpeed'       => isset( $settings['logo_anim_speed'] ) ? absint( $settings['logo_anim_speed'] ) : 1000,
				'textWait'        => isset( $settings['text_wait_anim'] ) ? esc_js( $settings['text_wait_anim'] ) : 'no',
				'textSpeed'       => isset( $settings['text_anim_speed'] ) ? absint( $settings['text_anim_speed'] ) : 2000,
				'logoAnim'        => esc_js( $settings['logo_animation'] ),
				'textAnim'        => isset( $settings['text_animation'] ) ? esc_js( $settings['text_animation'] ) : 'none',
				'styleWait'       => isset( $settings['style_wait_anim'] ) ? esc_js( $settings['style_wait_anim'] ) : 'no',
			)
		);

		// Add dynamic CSS with mandatory stripping of all tags.
		$custom_css = $this->generate_custom_css( $settings );
		wp_add_inline_style( 'swap-frontend-css', wp_strip_all_tags( $custom_css ) );
	}

	/**
	 * Generate custom CSS.
	 * 
	 * @param array $settings Plugin settings.
	 * @return string CSS.
	 */
	public function generate_custom_css( $settings ) {
		$css = '';
		// Background Logic.
		$bg_styles = '';
		$bg_type = $settings['bg_type'];

		// Force solid background for free users as a safety net.
		if ( ! SWAP_Helpers::is_pro() ) {
			$bg_type = 'solid';
		}

		$opacity = intval( $settings['bg_opacity'] ) / 100;
		
		if ( 'solid' === $bg_type ) {
			// Convert Hex to RGB for opacity.
			$hex = sanitize_hex_color( $settings['bg_custom_color'] );
			list($r, $g, $b) = sscanf($hex, "#%02x%02x%02x");
			$bg_styles = "background-color: rgba(" . absint( $r ) . ", " . absint( $g ) . ", " . absint( $b ) . ", $opacity);";
		} elseif ( 'gradient' === $bg_type ) {
			$bg_styles = "background: " . esc_attr( $settings['bg_gradient'] ) . "; opacity: $opacity;";
		} elseif ( 'image' === $bg_type ) {
			$bg_styles = "background-image: url('" . esc_url( $settings['bg_image_url'] ) . "'); background-size: " . esc_attr( $settings['bg_image_size'] ) . "; background-position: " . esc_attr( $settings['bg_image_position'] ) . "; opacity: $opacity;";
		}
		
		// Blur.
		if ( ! empty( $settings['bg_blur'] ) ) {
			$bg_styles .= " backdrop-filter: blur(" . absint( $settings['bg_blur'] ) . "px); -webkit-backdrop-filter: blur(" . absint( $settings['bg_blur'] ) . "px);";
		}

		// Text & Spinner Colors.
		// If Custom BG, use user defined text color. If Simple, auto-contrast.
		if ( 'custom' === $settings['bg_choice'] ) {
			$text_color = $settings['text_color'];
		} else {
			$text_color = ( 'white' === $settings['bg_color_type'] ) ? '#000000' : '#ffffff';
		}

		// Typography.
		$font_family = sanitize_text_field( $settings['font_family'] );
		$font_size   = absint( $settings['font_size'] ) . 'px';
		$font_weight = sanitize_text_field( $settings['font_weight'] );

		// Logo Dimensions.
		$logo_width = absint( $settings['logo_width'] ) . 'px';
		$logo_margin = absint( $settings['logo_spacing'] ) . 'px';

		$loader_color = sanitize_hex_color( $settings['loader_color'] );

		// Handle Custom Font URL
		if ( ! empty( $settings['custom_font_url'] ) ) {
			$font_name = basename( $settings['custom_font_url'] );
			$font_name = preg_replace( '/\.[^.]+$/', '', $font_name ); // Remove extension
			$font_name = sanitize_title( $font_name );
			$css .= "
				@font-face {
					font-family: '{$font_name}';
					src: url('" . esc_url( $settings['custom_font_url'] ) . "');
					font-display: swap;
				}
			";
			// If used, ensure font-family is set to this name
			if ( $settings['font_family'] === sanitize_text_field( $settings['font_family'] ) ) {
				$font_family = "'{$font_name}'";
			}
		}

		$css .= "
			#swap-preloader {
				{$bg_styles}
				font-family: " . esc_attr( $font_family ) . ", sans-serif;
				--swap-loader-color: " . esc_attr( $loader_color ) . ";
			}
			#swap-preloader .swap-logo {
				width: " . esc_attr( $logo_width ) . ";
				height: auto;
				margin-bottom: " . esc_attr( $logo_margin ) . ";
			}
			#swap-preloader .swap-text {
				color: " . esc_attr( $text_color ) . ";
				--loader-color: " . esc_attr( $text_color ) . ";
				font-size: " . esc_attr( $font_size ) . ";
				font-weight: " . esc_attr( $font_weight ) . ";
				font-family: inherit;
			}
			#swap-preloader .swap-percentage {
				color: " . esc_attr( $text_color ) . ";
				font-weight: bold;
			}
			/* Spinner Colors */
			#swap-preloader .swap-spinner {
				border-top-color: " . esc_attr( $text_color ) . ";
				background-color: " . esc_attr( $text_color ) . ";
			}
			#swap-preloader .swap-spinner.circle {
				border-color: rgba(150,150,150,0.2);
				border-top-color: " . esc_attr( $text_color ) . ";
				background-color: transparent;
			}
			#swap-preloader .swap-spinner.bar div,
			#swap-preloader .swap-spinner.wave div,
			#swap-preloader .swap-spinner.dots div {
				background-color: " . esc_attr( $text_color ) . ";
			}
		";

		// Readymade Preloader Size.
		$style_size = isset( $settings['style_size'] ) ? absint( $settings['style_size'] ) : 60;
		$scale_factor = round( $style_size / 60, 3 );
		$css .= "
			#swap-preloader .swap-tpl-wrap {
				transform: scale({$scale_factor});
				transform-origin: center center;
			}
		";
		
		// Progress Bar.
		if ( 'yes' === $settings['show_progress_bar'] ) {
			$bar_color = sanitize_hex_color( $settings['progress_bar_color'] );
			
			if ( 'linear' === $settings['progress_bar_type'] ) {
				$css .= "
					#swap-preloader .swap-progress-bar-wrap {
						position: fixed;
						top: 0;
						left: 0;
						width: 100%;
						height: 4px;
						z-index: 99999;
						background: transparent;
					}
					#swap-preloader .swap-progress-bar {
						width: 0%;
						height: 100%;
						background: " . esc_attr( $bar_color ) . ";
						transition: width 0.2s linear;
					}
				";
			} else {
				// Center (Default)
				$css .= "
					#swap-preloader .swap-progress-bar-wrap {
						width: 200px;
						height: 4px;
						background: rgba(255,255,255,0.2);
						border-radius: 2px;
						margin-top: 15px;
						overflow: hidden;
						position: relative;
					}
					#swap-preloader .swap-progress-bar {
						width: 0%;
						height: 100%;
						background: " . esc_attr( $bar_color ) . ";
						transition: width 0.2s linear;
					}
				";
			}
		}
		
		// Custom CSS.
		if ( ! empty( $settings['custom_css'] ) ) {
			$css .= $settings['custom_css'];
		}

		return $css;
	}

	/**
	 * Render preloader HTML.
	 */
	public function render_preloader() {
		if ( ! $this->should_display() ) {
			return;
		}
		// Prevent double rendering if fallback is triggered.
		if ( defined( 'SWAP_RENDERED' ) ) {
			return;
		}
		define( 'SWAP_RENDERED', true );

		$settings = SWAP_Helpers::get_settings();
		$devices  = isset( $settings['device_targeting'] ) && is_array( $settings['device_targeting'] ) ? $settings['device_targeting'] : array();
		
		$visibility_classes = array();
		if ( ! empty( $devices ) && ! in_array( 'all', $devices, true ) ) {
			if ( ! in_array( 'desktop', $devices, true ) ) {
				$visibility_classes[] = 'swap-hide-desktop';
			}
			if ( ! in_array( 'tablet', $devices, true ) ) {
				$visibility_classes[] = 'swap-hide-tablet';
			}
			if ( ! in_array( 'mobile', $devices, true ) ) {
				$visibility_classes[] = 'swap-hide-mobile';
			}
		}
		
		$preloader_class = 'swap-transition-' . esc_attr( $settings['transition_effect'] );
		if ( ! empty( $visibility_classes ) ) {
			$preloader_class .= ' ' . implode( ' ', $visibility_classes );
		}
		?>
		<div id="swap-preloader" class="<?php echo esc_attr( $preloader_class ); ?>" style="display:none;"> <!-- Hidden initially for show_delay logic -->
			
			<?php if ( 'custom' === $settings['bg_choice'] && 'video' === $settings['bg_type'] && ! empty( $settings['bg_video_url'] ) ) : ?>
				<video autoplay muted loop playsinline class="swap-bg-video">
					<source src="<?php echo esc_url( $settings['bg_video_url'] ); ?>" type="video/mp4">
				</video>
				<div class="swap-video-overlay" style="<?php echo is_numeric( $settings['bg_opacity'] ) ? esc_attr( 'background: rgba(0,0,0,' . ( 1 - ( intval( $settings['bg_opacity'] ) / 100 ) ) . ');' ) : ''; ?>"></div>
			<?php endif; ?>

			<div class="swap-loader-inner">
				
				<?php
				$active_type = isset( $settings['active_preloader_type'] ) ? $settings['active_preloader_type'] : 'none';
				?>

				<?php // Logo: only for logo type. ?>
				<?php if ( 'logo' === $active_type && ! empty( $settings['logo_url'] ) ) : ?>
					<div class="swap-logo <?php echo esc_attr( $settings['logo_animation'] !== 'none' ? 'swap-anim-' . $settings['logo_animation'] : '' ); ?>" style="--swap-anim-speed: <?php echo absint( $settings['logo_anim_speed'] ); ?>ms;">
						<img src="<?php echo esc_url( $settings['logo_url'] ); ?>" alt="<?php echo esc_attr__( 'Logo', 'smartwait-animated-preloader' ); ?>">
					</div>
				<?php endif; ?>

				<?php // Spinner: only for style type. ?>
				<?php if ( 'style' === $active_type ) : ?>
				<?php
				$allowed_html = array( 'div' => array( 'class' => array() ) );
				echo wp_kses( SWAP_Helpers::get_spinner_html( $settings['spinner_type'] ), $allowed_html );
				?>
				<?php endif; ?>

				<?php // Loading text: only for text type. ?>
			<?php if ( 'text' === $active_type && ! empty( $settings['loading_text'] ) ) : ?>
				<?php
				$use_normal    = ( isset( $settings['use_normal_text'] ) && 'yes' === $settings['use_normal_text'] );
				$use_readymade = ( isset( $settings['use_readymade_text'] ) && 'yes' === $settings['use_readymade_text'] );
				
				$text_class = 'swap-text';
				$show_text  = false;

				if ( $use_readymade ) {
					$text_class .= ' swap-text-loader-' . $settings['readymade_text_style'];
					$show_text = true;
				} elseif ( $use_normal ) {
					if ( $settings['text_animation'] !== 'none' ) {
						$text_class .= ' swap-anim-' . $settings['text_animation'];
					}
					$show_text = true;
				} else {
					$show_text = true; // Fallback to display plain text without animations.
				}
				?>
				<?php if ( $show_text ) : ?>
					<div class="<?php echo esc_attr( $text_class ); ?>" data-text="<?php echo esc_attr( $settings['loading_text'] ); ?>" style="--loader-color: <?php echo esc_attr( sanitize_hex_color( $settings['text_color'] ) ); ?>;">
						<?php echo esc_html( $settings['loading_text'] ); ?>
					</div>
				<?php endif; ?>
			<?php endif; ?>

				<?php // Percentage: only for progress_timing type. ?>
				<?php if ( 'progress_timing' === $active_type && 'yes' === $settings['show_percentage'] ) : ?>
					<div class="swap-percentage" style="color: <?php echo esc_attr( sanitize_hex_color( $settings['percentage_color'] ) ); ?>; font-size: <?php echo absint( $settings['percentage_font_size'] ); ?>px;">0%</div>
				<?php endif; ?>

				<?php // Progress bar: only for progress_timing type. ?>
				<?php if ( 'progress_timing' === $active_type && 'yes' === $settings['show_progress_bar'] ) : ?>
					<div class="swap-progress-bar-wrap" style="height: <?php echo absint( $settings['progress_bar_height'] ); ?>px;">
						<div class="swap-progress-bar" style="background: <?php echo esc_attr( sanitize_hex_color( $settings['progress_bar_color'] ) ); ?>;"></div>
					</div>
				<?php endif; ?>
			</div>
		</div>
		<?php
	}

	/**
	 * Render fallback.
	 */
	public function render_preloader_fallback() {
		if ( ! defined( 'SWAP_RENDERED' ) ) {
			$this->render_preloader();
		}
	}
}

new SWAP_Frontend();
