<?php
/**
 * BricksExtras Main Class
 *
 * Handles plugin initialization, element registration, and settings management.
 *
 * @package BricksExtras
 */

namespace BricksExtras;

use Bricks\Database;

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

if ( class_exists( 'BricksExtrasMain' ) ) {
	return;
}

// Define required classes.
$required_classes = array(
	'BricksExtrasInteractive'  => 'BricksExtrasInteractive.php',
	'BricksExtrasInteractions' => 'BricksExtrasInteractions.php',
	'BricksExtrasHeaderExtras' => 'BricksExtrasHeaderExtras.php',
	'BricksExtrasHelpers'      => 'BricksExtrasHelpers.php',
	'BricksExtrasFavorite'     => 'BricksExtrasFavorite.php',
	'BricksExtrasVideo'        => 'BricksExtrasVideo.php',
	'BricksExtrasBunnyStream'  => 'BricksExtrasBunnyStream.php',
);

// Load required classes.
foreach ( $required_classes as $class_name => $file_path ) {
	if ( ! class_exists( $class_name ) ) {
		require_once __DIR__ . '/' . $file_path;
	}
}

global $bricks_extras_element_css_added;
$bricks_extras_element_css_added = array();

/**
 * Main plugin class.
 *
 * Manages element registration, settings, conditions, and file loading.
 */
class BricksExtrasMain {
	/**
	 * Available elements.
	 *
	 * @var array
	 */
	public $elements = array();

	/**
	 * Option prefix.
	 *
	 * @var string
	 */
	public $prefix = '';

	/**
	 * Plugin version.
	 *
	 * @var string
	 */
	public $version = '';

	/**
	 * General conditions.
	 *
	 * @var array
	 */
	public $conditions = array();

	/**
	 * Member conditions.
	 *
	 * @var array
	 */
	public $member_conditions = array();

	/**
	 * WooCommerce conditions.
	 *
	 * @var array
	 */
	public $wc_conditions = array();

	/**
	 * Miscellaneous options.
	 *
	 * @var array
	 */
	public $misc_options = array();

	/**
	 * Constructor.
	 *
	 * @param string $prefix  Option prefix.
	 * @param string $version Plugin version.
	 */
	public function __construct( $prefix, $version ) {

		$this->prefix  = $prefix;
		$this->version = $version;

		$this->set_files();
		$this->set_member_conditions();
		$this->set_wc_conditions();
		$this->set_misc_options();
		$this->set_conditions();

		add_action( 'admin_init', array( $this, 'register_options' ) );

		add_action( $this->prefix . 'form_options', array( $this, 'options_form' ) );
		add_action( $this->prefix . 'conditions_form_options', array( $this, 'conditions_form_options' ) );
		add_action( $this->prefix . 'member_conditions_form_options', array( $this, 'member_conditions_form_options' ) );
		add_action( $this->prefix . 'wc_conditions_form_options', array( $this, 'wc_conditions_form_options' ) );
		add_action( $this->prefix . 'misc_form_options', array( $this, 'misc_form_options' ) );

		// Add Gutenberg support.
		if ( apply_filters( 'bricksextras/load_gutenberg_css', true ) ) {
			add_action( 'enqueue_block_assets', array( $this, 'load_gutenberg_css' ) );
		}

		if ( ! class_exists( '\Bricks\Elements' ) ) {
			return;
		}

		$this->load_files();

		$media_player_active       = get_option( $this->prefix . 'media_player' );
		$media_player_audio_active = get_option( $this->prefix . 'media_player_audio' );

		if ( $media_player_active || $media_player_audio_active ) {

			require_once __DIR__ . '/BricksExtrasMedia.php';
			$media_handler = new \BricksExtras\BricksExtrasMedia();

			if ( $media_player_active ) {

				// Initialize Bunny Stream integration for captions.
				if ( class_exists( '\BricksExtras\BricksExtrasBunnyStream' ) ) {
					$bunny_stream = new \BricksExtras\BricksExtrasBunnyStream();
					if ( method_exists( $bunny_stream, 'init' ) ) {
						$bunny_stream->init();
					}
				}
			}

			// Initialize waveform handler if enabled.
			if ( $media_player_audio_active ) {
				$media_handler->init_waveform_handler();
			}
		}

		if ( bricks_is_frontend() ) {
			add_action( 'wp_enqueue_scripts', array( $this, 'conditional_default_css' ) );

			add_action( 'wp_enqueue_scripts', array( $this, 'global_scripts' ), 1 );

			// Interactions.
			if ( get_option( $this->prefix . 'interactions' ) ) {
				add_action( 'wp_enqueue_scripts', array( $this, 'interactions_script' ), 1 );
			}

			// frontend Scripts.
			add_action( 'bricks_after_footer', array( $this, 'frontend_scripts' ), 200 );
		}

		if ( bricks_is_builder_main() ) {
			add_action( 'wp_enqueue_scripts', array( $this, 'builder_scripts' ) );
		}

		if ( bricks_is_builder_iframe() ) {
			add_action( 'wp_enqueue_scripts', array( $this, 'iframe_scripts' ) );
			add_filter( 'bricks/body/attributes', array( $this, 'proslider_builder_init' ) );
		}

		if ( get_option( $this->prefix . 'header_row' ) ) {
			( new HeaderExtras() )->init();
		}

		if ( ! class_exists( 'WPGridBuilderStyler' ) && get_option( $this->prefix . 'wpgb_facets' ) ) {
			require_once __DIR__ . '/WPGridBuilderStyler.php';
			( new WPGridBuilderStyler() )->init();
		}

		if ( get_option( $this->prefix . 'favorite' ) ) {
			( new Favorite() )->init();
		}

		// Load Toast Queue helper.
		if ( get_option( $this->prefix . 'toast' ) ) {
			if ( ! class_exists( '\BricksExtras\BricksExtrasToast' ) ) {
				require_once __DIR__ . '/BricksExtrasToast.php';
				( new BricksExtrasToast() )->init();
			}
		}
	}

	/**
	 * Sanitize enable checkbox input.
	 *
	 * @param mixed $input The input value.
	 * @return int 1 if enabled, 0 otherwise.
	 */
	public function sanitize_enable( $input ) {
		return ( 1 === $input || '1' === $input ? 1 : 0 );
	}


	/**
	 * Set available elements/features.
	 *
	 * @return void
	 */
	public function set_files() {
		$this->elements = array(
			'add_to_calendar'             => array(
				'title'     => esc_html__( 'Add to calendar', 'bricksextras' ),
				'file_name' => 'x-add-to-calendar',
				'docs_slug' => 'add-to-calendar',
			),
			'back_to_top'          => array(
				'title'     => esc_html__( 'Back to Top', 'bricksextras' ),
				'file_name' => 'x-back-to-top',
				'docs_slug' => 'back-to-top',
			),
			'before_after_image'   => array(
				'title'     => esc_html__( 'Before / After Image', 'bricksextras' ),
				'file_name' => 'x-before-after-image',
				'docs_slug' => 'before-after-image',
			),
			'burger_trigger'       => array(
				'title'     => esc_html__( 'Burger Trigger', 'bricksextras' ),
				'file_name' => 'x-burger-trigger',
				'docs_slug' => 'burger-trigger',
			),
			'calendar'             => array(
				'title'     => esc_html__( 'Calendar', 'bricksextras' ),
				'file_name' => 'x-calendar',
				'docs_slug' => 'calendar',
			),
			'color_scheme_toggle'  => array(
				'title'     => esc_html__( 'Color Scheme Toggle', 'bricksextras' ),
				'file_name' => 'x-color-scheme-toggle',
				'docs_slug' => 'color-scheme-toggle',
			),
			'content_switcher'     => array(
				'title'     => esc_html__( 'Content Switcher', 'bricksextras' ),
				'file_name' => 'x-content-switcher',
				'docs_slug' => 'content-switcher',
			),
			'content_timeline'     => array(
				'title'     => esc_html__( 'Content Timeline', 'bricksextras' ),
				'file_name' => 'x-content-timeline',
				'docs_slug' => 'content-timeline',
			),
			'copy_to_clipboard'    => array(
				'title'     => esc_html__( 'Copy to Clipboard', 'bricksextras' ),
				'file_name' => 'x-copy-to-clipboard',
				'docs_slug' => 'copy-to-clipboard',
			),
			'dynamic_chart'        => array(
				'title'     => esc_html__( 'Dynamic Chart', 'bricksextras' ),
				'file_name' => 'x-dynamic-chart',
				'docs_slug' => 'dynamic-chart',
			),
			'dynamic_lightbox'     => array(
				'title'     => esc_html__( 'Dynamic Lightbox', 'bricksextras' ),
				'file_name' => 'x-dynamic-lightbox',
				'docs_slug' => 'dynamic-lightbox',
			),

			'dynamic_table'        => array(
				'title'     => esc_html__( 'Dynamic Table', 'bricksextras' ),
				'file_name' => 'x-dynamic-table',
				'docs_slug' => 'dynamic-table',
			),
			'favorite'             => array(
				'title'     => esc_html__( 'Favorites', 'bricksextras' ) . ' / ' . esc_html__( 'Wishlist', 'bricksextras' ),
				'file_name' => 'x-favorite',
				'docs_slug' => 'favorites-wishlist',
			),

			'fluent_form'          => array(
				'title'     => 'Fluent Form',
				'file_name' => 'x-fluent-form',
				'docs_slug' => 'fluent-form',
			),
			'header_row'           => array(
				'title'     => esc_html__( 'Header Extras', 'bricksextras' ) . ' / ' . esc_html__( 'Rows', 'bricksextras' ),
				'file_name' => 'x-header-row',
				'docs_slug' => 'header-extras',
			),
			'notification_bar'     => array(
				'title'     => esc_html__( 'Header Notification Bar', 'bricksextras' ),
				'file_name' => 'x-notification-bar',
				'docs_slug' => 'header-notification-bar',
			),

			'header_search'        => array(
				'title'     => esc_html__( 'Header Search', 'bricksextras' ),
				'file_name' => 'x-header-search',
				'docs_slug' => 'header-search',
			),
			'image_hotspots'       => array(
				'title'     => esc_html__( 'Image Hotspots', 'bricksextras' ),
				'file_name' => 'x-image-hotspots',
				'docs_slug' => 'image-hotspots',
			),
			'image_hotspot_marker' => array(
				'title'      => esc_html__( 'Image Hotspot Marker', 'bricksextras' ),
				'file_name'  => 'x-image-hotspot-marker',
				'docs_slug'  => 'image-hotspot-marker',
				'stylesheet' => false,
			),
			'interactive_cursor'   => array(
				'title'     => esc_html__( 'Interactive Cursor', 'bricksextras' ),
				'file_name' => 'x-interactive-cursor',
				'docs_slug' => 'interactive-cursor',
			),
			'lottie'               => array(
				'title'     => esc_html__( 'Lottie', 'bricksextras' ),
				'file_name' => 'x-lottie',
				'docs_slug' => 'lottie',
			),
			'media_player'         => array(
				'title'     => esc_html__( 'Media Player', 'bricksextras' ),
				'file_name' => 'x-media-player',
				'docs_slug' => 'media-player',
			),
			'media_player_audio'   => array(
				'title'      => esc_html__( 'Media Player', 'bricksextras' ) . ' (' . esc_html__( 'Audio', 'bricksextras' ) . ')',
				'file_name'  => 'x-media-player-audio',
				'docs_slug'  => 'media-player-audio',
				'stylesheet' => 'mediaplayer',
			),
			'media_control'        => array(
				'title'      => esc_html__( 'Media Control', 'bricksextras' ),
				'file_name'  => 'x-media-control',
				'docs_slug'  => 'media-control',
				'stylesheet' => false,
			),
			'media_playlist'       => array(
				'title'     => esc_html__( 'Media Playlist', 'bricksextras' ),
				'file_name' => 'x-media-playlist',
				'docs_slug' => 'media-playlist',
			),
			'pro_modal'            => array(
				'title'     => esc_html__( 'Modal', 'bricksextras' ) . ' (' . esc_html__( 'Template', 'bricksextras' ) . ' - ' . esc_html__( 'Legacy', 'bricksextras' ) . ')',
				'file_name' => 'x-pro-modal',
				'docs_slug' => 'modal',
			),
			'pro_modal_nestable'   => array(
				'title'      => esc_html__( 'Modal', 'bricksextras' ),
				'file_name'  => 'x-pro-modal-nestable',
				'docs_slug'  => 'modal',
				'stylesheet' => 'promodal',
			),
			'nestable_table'       => array(
				'title'     => esc_html__( 'Nestable Table', 'bricksextras' ),
				'file_name' => 'x-nestable-table',
				'docs_slug' => 'nestable-table',
			),
			'offcanvas'            => array(
				'title'     => esc_html__( 'Offcanvas', 'bricksextras' ) . ' (' . esc_html__( 'Template', 'bricksextras' ) . ' - ' . esc_html__( 'Legacy', 'bricksextras' ) . ')',
				'file_name' => 'x-offcanvas',
				'docs_slug' => 'offcanvas',
			),
			'offcanvas_nestable'   => array(
				'title'      => esc_html__( 'Offcanvas', 'bricksextras' ),
				'file_name'  => 'x-offcanvas-nestable',
				'docs_slug'  => 'offcanvas',
				'stylesheet' => 'offcanvas',
			),
			'page_tour'            => array(
				'title'     => esc_html__( 'Page Tour', 'bricksextras' ),
				'file_name' => 'x-page-tour',
				'docs_slug' => 'page-tour',
			),
			'page_tour_step'       => array(
				'title'      => esc_html__( 'Page Tour Step', 'bricksextras' ),
				'file_name'  => 'x-page-tour-step',
				'docs_slug'  => 'page-tour', /* same as pagetour */
				'stylesheet' => 'pagetour', /* same as pagetour */
			),
			'panorama_viewer'      => array(
				'title'     => esc_html__( 'Panorama Viewer', 'bricksextras' ),
				'file_name' => 'x-panorama-viewer',
				'docs_slug' => 'panorama-viewer',
			),
			'panorama_scene'       => array(
				'title'      => esc_html__( 'Panorama Scene', 'bricksextras' ),
				'file_name'  => 'x-panorama-scene',
				'docs_slug'  => 'panorama-viewer',
				'stylesheet' => false,
			),
			'popover'              => array(
				'title'     => esc_html__( 'Popover / Tooltips', 'bricksextras' ),
				'file_name' => 'x-popover',
				'docs_slug' => 'popovers-tooltips',
			),
			'pro_accordion'        => array(
				'title'     => esc_html__( 'Pro Accordion', 'bricksextras' ),
				'file_name' => 'x-pro-accordion',
				'docs_slug' => 'pro-accordion',
			),
			'pro_alert'            => array(
				'title'     => esc_html__( 'Pro Alert', 'bricksextras' ),
				'file_name' => 'x-pro-alert',
				'docs_slug' => 'pro-alert',
			),
			'countdown'            => array(
				'title'     => esc_html__( 'Pro Countdown', 'bricksextras' ),
				'file_name' => 'x-countdown',
				'docs_slug' => 'countdown',
			),
			'pro_slider'           => array(
				'title'     => esc_html__( 'Pro Slider', 'bricksextras' ),
				'file_name' => 'x-pro-slider',
				'docs_slug' => 'pro-slider',
			),
			'pro_slider_control'   => array(
				'title'     => esc_html__( 'Pro Slider Control', 'bricksextras' ),
				'file_name' => 'x-pro-slider-control',
				'docs_slug' => 'pro-slider',
			),
			'pro_slider_gallery'   => array(
				'title'      => esc_html__( 'Pro Slider Gallery', 'bricksextras' ),
				'file_name'  => 'x-pro-slider-gallery',
				'docs_slug'  => 'pro-slider',
				'stylesheet' => false,
			),
			'pro_tabs'             => array(
				'title'     => esc_html__( 'Pro Tabs', 'bricksextras' ),
				'file_name' => 'x-tabs',
				'docs_slug' => 'pro-tabs',
			),
			'qr_code'              => array(
				'title'     => esc_html__( 'QR Code', 'bricksextras' ),
				'file_name' => 'x-qr-code',
				'docs_slug' => 'qr-code',
			),
			'reading_progress_bar' => array(
				'title'     => esc_html__( 'Reading Progress Bar', 'bricksextras' ),
				'file_name' => 'x-reading-progress-bar',
				'docs_slug' => 'reading-progress-bar',
			),
			'read_more_less'       => array(
				'title'     => esc_html__( 'Read More / Less', 'bricksextras' ),
				'file_name' => 'x-read-more-less',
				'docs_slug' => 'read-more-less',
			),
			'shortcode_wrapper'    => array(
				'title'      => esc_html__( 'Shortcode Wrapper', 'bricksextras' ),
				'file_name'  => 'x-shortcode-wrapper',
				'docs_slug'  => 'shortcode-wrapper',
				'stylesheet' => false,
			),
			'breadcrumbs'          => array(
				'title'     => esc_html__( 'Site Breadcrumbs', 'bricksextras' ),
				'file_name' => 'x-breadcrumbs',
				'docs_slug' => 'site-breadcrumbs',
			),
			'slide_menu'           => array(
				'title'     => esc_html__( 'Slide menu', 'bricksextras' ),
				'file_name' => 'x-slide-menu',
				'docs_slug' => 'slide-menu',
			),
			'social_share'         => array(
				'title'     => esc_html__( 'Social Share', 'bricksextras' ),
				'file_name' => 'x-social-share',
				'docs_slug' => 'social-share',
			),
			'star_rating'          => array(
				'title'     => esc_html__( 'Star Rating', 'bricksextras' ),
				'file_name' => 'x-star-rating',
				'docs_slug' => 'star-rating',
			),
			'table_of_contents'    => array(
				'title'     => esc_html__( 'Table of Contents', 'bricksextras' ),
				'file_name' => 'x-table-of-contents',
				'docs_slug' => 'table-of-contents',
			),
			'toast'                => array(
				'title'     => esc_html__( 'Toast', 'bricksextras' ),
				'file_name' => 'x-toast',
				'docs_slug' => 'toast',
			),
			'toast_notification'   => array(
				'title'      => esc_html__( 'Toast Notification', 'bricksextras' ),
				'file_name'  => 'x-toast-notification',
				'docs_slug'  => 'toast',
				'stylesheet' => false,
			),
			'toggle_switch'        => array(
				'title'     => esc_html__( 'Toggle Switch', 'bricksextras' ),
				'file_name' => 'x-toggle-switch',
				'docs_slug' => 'toggle-switch',
			),
			'wpgb_facets'          => array(
				'title'     => 'WPGB ' . esc_html__( 'Facet Styler', 'bricksextras' ),
				'file_name' => 'x-wpgb-facet-styler',
				'docs_slug' => 'wpgb-facet-styler',
				'element'   => false,
			),
			'ws_forms'             => array(
				'title'     => 'WS Form',
				'file_name' => 'x-ws-forms',
				'docs_slug' => 'ws-forms',
			),

		);
	}

	/**
	 * Set general conditions.
	 *
	 * @return void
	 */
	public function set_conditions() {
		$this->conditions = Helpers::get_extras_conditions( 'general' );
	}

	/**
	 * Set member conditions.
	 *
	 * @return void
	 */
	public function set_member_conditions() {
		$this->member_conditions = Helpers::get_extras_conditions( 'member' );
	}

	/**
	 * Set WooCommerce conditions.
	 *
	 * @return void
	 */
	public function set_wc_conditions() {
		$this->wc_conditions = Helpers::get_extras_conditions( 'wc' );
	}

	/**
	 * Set miscellaneous options.
	 *
	 * @return void
	 */
	public function set_misc_options() {
		$this->misc_options = Helpers::get_extras_misc_options();
	}

	/**
	 * Register plugin options and settings.
	 *
	 * @return void
	 */
	public function register_options() {

		/* elements/features  */
		foreach ( $this->elements as $key => $element ) {

				add_option( $this->prefix . $key, 0 );
				register_setting( $this->prefix . 'settings', $this->prefix . $key, array( $this, 'sanitize_enable' ) );

		}

		/* conditons */
		foreach ( $this->conditions as $key => $condition ) {

			add_option( $this->prefix . $key, 0 );
			register_setting( $this->prefix . 'conditions_settings', $this->prefix . $key, array( $this, 'sanitize_enable' ) );

		}

		/* member conditons */
		foreach ( $this->member_conditions as $key => $member_condition ) {

			add_option( $this->prefix . $key, 0 );
			register_setting( $this->prefix . 'conditions_settings', $this->prefix . $key, array( $this, 'sanitize_enable' ) );

		}

		/* WooCommerce conditons */
		foreach ( $this->wc_conditions as $key => $wc_condition ) {

			add_option( $this->prefix . $key, 0 );
			register_setting( $this->prefix . 'conditions_settings', $this->prefix . $key, array( $this, 'sanitize_enable' ) );

		}

		/* Misc features */
		foreach ( $this->misc_options as $key => $misc_option ) {

			add_option( $this->prefix . $key, 0 );
			register_setting( $this->prefix . 'misc_options', $this->prefix . $key, array( $this, 'sanitize_enable' ) );

		}
	}

	/**
	 * Display options form for elements/features.
	 *
	 * @return void
	 */
	public function options_form() {

		foreach ( $this->elements as $key => $element ) {  ?>

			<tr valign="top"<?php echo get_option( $this->prefix . $key ) === '1' ? ' class="active"' : ' class="inactive"'; ?>>
				<th class="check-column">
					<input id="<?php echo esc_attr( $this->prefix . $key ); ?>" name="<?php echo esc_attr( $this->prefix . $key ); ?>" type="checkbox" value="1" <?php checked( get_option( $this->prefix . $key ), 1 ); ?> />
				</th>
				<td class="plugin-title column-primary">
					<?php echo '<strong>' . esc_html( $element['title'] ) . '</strong>'; ?>
				</td>
				<th class="doc-link-th" style="text-align: end; padding-right: 10px;">
					<?php echo '<p class="doc-link"><a target="_blank" href="https://bricksextras.com/docs/' . esc_attr( $element['docs_slug'] ) . '">Doc</a></p>'; ?>
				</th>
			</tr>
			<?php
		}
	}

	/**
	 * Display form options for general conditions.
	 *
	 * @return void
	 */
	public function conditions_form_options(): void {

		foreach ( $this->conditions as $key => $condition ) {
			?>

			<tr valign="top"<?php echo get_option( $this->prefix . $key ) === '1' ? ' class="active"' : ' class="inactive"'; ?>>
				<th class="check-column">
					<input id="<?php echo esc_attr( $this->prefix . $key ); ?>" name="<?php echo esc_attr( $this->prefix . $key ); ?>" type="checkbox" value="1" <?php checked( get_option( $this->prefix . $key ), 1 ); ?> />
				</th>
				<td class="plugin-title column-primary">
					<?php echo '<strong>' . esc_html( $condition['title'] ) . '</strong>'; ?>
				</td>
				<th class="doc-link-th" style="text-align: end; padding-right: 10px;">
					<?php echo '<p class="doc-link"><a target="_blank" href="https://bricksextras.com/docs/' . esc_attr( $condition['docs_slug'] ) . '">Doc</a></p>'; ?>
				</th>
			</tr>
			<?php
		}
	}

	/**
	 * Display form options for member conditions.
	 *
	 * @return void
	 */
	public function member_conditions_form_options(): void {

		foreach ( $this->member_conditions as $key => $member_condition ) {
			?>

			<tr valign="top"<?php echo get_option( $this->prefix . $key ) === '1' ? ' class="active"' : ' class="inactive"'; ?>>
				<th class="check-column">
					<input id="<?php echo esc_attr( $this->prefix . $key ); ?>" name="<?php echo esc_attr( $this->prefix . $key ); ?>" type="checkbox" value="1" <?php checked( get_option( $this->prefix . $key ), 1 ); ?> />
				</th>
				<td class="plugin-title column-primary">
					<?php echo '<strong>' . esc_html( $member_condition['title'] ) . '</strong>'; ?>
				</td>
				<th class="doc-link-th" style="text-align: end; padding-right: 10px;">
					<?php echo '<p class="doc-link"><a target="_blank" href="https://bricksextras.com/docs/' . esc_attr( $member_condition['docs_slug'] ) . '/">Doc</a></p>'; ?>
				</th>
			</tr>
			<?php
		}
	}

	/**
	 * Display form options for WooCommerce conditions.
	 *
	 * @return void
	 */
	public function wc_conditions_form_options(): void {

		foreach ( $this->wc_conditions as $key => $wc_condition ) {
			?>

			<tr valign="top"<?php echo get_option( $this->prefix . $key ) === '1' ? ' class="active"' : ' class="inactive"'; ?>>
				<th class="check-column">
					<input id="<?php echo esc_attr( $this->prefix . $key ); ?>" name="<?php echo esc_attr( $this->prefix . $key ); ?>" type="checkbox" value="1" <?php checked( get_option( $this->prefix . $key ), 1 ); ?> />
				</th>
				<td class="plugin-title column-primary">
					<?php echo '<strong>' . esc_html( $wc_condition['title'] ) . '</strong>'; ?>
				</td>
				<th class="doc-link-th" style="text-align: end; padding-right: 10px;">
					<?php echo '<p class="doc-link"><a target="_blank" href="https://bricksextras.com/docs/' . esc_attr( $wc_condition['docs_slug'] ) . '">Doc</a></p>'; ?>
				</th>
			</tr>
			<?php
		}
	}

	/**
	 * Display form options for miscellaneous settings.
	 *
	 * @return void
	 */
	public function misc_form_options() {

		foreach ( $this->misc_options as $key => $misc_option ) {
			?>

			<tr valign="top"<?php echo get_option( $this->prefix . $key ) === '1' ? ' class="active"' : ' class="inactive"'; ?>>
				<th class="check-column">
					<input id="<?php echo esc_attr( $this->prefix . $key ); ?>" name="<?php echo esc_attr( $this->prefix . $key ); ?>" type="checkbox" value="1" <?php checked( get_option( $this->prefix . $key ), 1 ); ?> />
				</th>
				<td class="plugin-title column-primary">
					<?php echo '<strong>' . esc_html( $misc_option['title'] ) . '</strong>'; ?>
					<?php echo isset( $misc_option['description'] ) ? esc_html( $misc_option['description'] ) : ''; ?>
				</td>
				<th class="doc-link-th" style="text-align: end; padding-right: 10px;">
					<?php echo '<p class="doc-link"><a target="_blank" href="https://bricksextras.com/docs/' . esc_attr( $misc_option['docs_slug'] ) . '">Doc</a></p>'; ?>
				</th>
			</tr>
			<?php
		}
	}

	/**
	 * Load element and component files.
	 *
	 * @return void
	 */
	public function load_files() {

		$element_dir = BRICKSEXTRAS_PATH . 'components/classes/';

		foreach ( $this->elements as $key => $element ) {

			if ( 0 === intval( get_option( $this->prefix . $key, 0 ) ) ) {
				continue;
			}

			if ( isset( $element['element'] ) ) {
				continue;
			}

			$file       = $element_dir . $element['file_name'] . '.php';
			$name       = str_replace( '-', '', $element['file_name'] );
			$class_name = str_replace( '-', '_', $element['file_name'] );
			$class_name = ucwords( $class_name, '_' );

			/*
			Example output for each element for Bricks' register_element() function ..

				$file = BRICKSEXTRAS_PATH . 'components/classes/x-burger-trigger.php';
				$name = xburgertrigger ( this is the $name from the element class, no dashes )
				$class_name = X_Burger_Trigger ( the Class of the element, always capitalized, underscore not dashes )

			*/

			// Register all elements in builder & frontend.
			\Bricks\Elements::register_element( $file, $name, $class_name );

			/* include styles in builder */
			if ( bricks_is_builder_iframe() ) {

				if ( ! isset( $element['stylesheet'] ) ) {
					$element['stylesheet'] = true;
				}

				if ( true === $element['stylesheet'] ) {
					$stylesheet = ltrim( str_replace( '-', '', $element['file_name'] ), 'x' );
				} elseif ( false !== $element['stylesheet'] ) {
					$stylesheet = $element['stylesheet'];
				}

				if ( (bool) $element['stylesheet'] ) {

					if ( 'xmodalnestable' === $name ) {
						$handle = 'x-modal';
					} elseif ( 'xoffcanvasnestable' === $name ) {
						$handle = 'x-offcanvas';
					} elseif ( 'xmediaplayeraudio' === $name ) {
						$handle = 'x-media-player';
					} else {
						$handle = $element['file_name'];
					}

					if ( 'xwsforms' === $name && method_exists( '\WS_Form_Common', 'styler_enabled' ) && \WS_Form_Common::styler_enabled() ) {
						$stylesheet = 'wsforms-styler-enabled';
					}

					wp_enqueue_style( $handle, BRICKSEXTRAS_URL . 'components/assets/css/' . $stylesheet . '.css', array(), $this->version );

				}
			}
		}

		BricksExtrasInteractive::init();

		if ( get_option( $this->prefix . 'interactions' ) ) {
			BricksExtrasInteractions::init( $this->prefix );
		}

		if ( get_option( $this->prefix . 'query_loop_extras' ) ) {
			if ( ! class_exists( 'BricksExtrasQueryLoop' ) ) {
				require_once __DIR__ . '/BricksExtrasQueryLoop.php';
			}

			( new BricksExtrasQueryLoop() )->init( $this->prefix );
		}

		if ( ! class_exists( 'BricksExtrasDynamicTags' ) ) {
			require_once __DIR__ . '/BricksExtrasDynamicTags.php';
		}
		BricksExtrasDynamicTags::init();

		if ( ! class_exists( 'BricksExtrasHelpers' ) ) {
			require_once BRICKSEXTRAS_PATH . '/includes/BricksExtrasHelpers.php';
		}
	}

	/**
	 * Get all elements on the current page.
	 *
	 * @return array Array of elements.
	 */
	private static function get_elements_on_page() {

		static $cached_elements = null;

		if ( null !== $cached_elements ) {
			return $cached_elements;
		}

		$template_types = array(
			'header',
			'content',
			'footer',
		);

		if ( ! method_exists( '\Bricks\Database', 'get_template_data' ) ||
			! method_exists( '\Bricks\Database', 'get_setting' ) ||
			! method_exists( '\Bricks\Assets', 'minify_css' ) ||
			! method_exists( '\Bricks\Query', 'get_query_object_type' ) ||
			! method_exists( '\Bricks\Helpers', 'get_template_setting' ) ) {
			return array();
		}

		$elements_on_page_array = array();

		foreach ( $template_types as $template_type ) {

			$template_data = Database::get_template_data( $template_type );

			if ( (bool) $template_data ) {

				foreach ( $template_data as $template_elements ) {
					$elements_on_page_array[] = $template_elements;
				}
			}
		}

		$template_ids = array();

		/* find elements inside templates, post content, shortcodes */

		foreach ( $elements_on_page_array as $element_on_page ) {

			if ( isset( $element_on_page['settings']['template'] ) ) {
				$template_ids[] = ! empty( $element_on_page['settings']['template'] ) ? intval( $element_on_page['settings']['template'] ) : 0;
			}

			if ( isset( $element_on_page['settings']['offcanvas_template'] ) ) {
				$template_ids[] = ! empty( $element_on_page['settings']['offcanvas_template'] ) ? intval( $element_on_page['settings']['offcanvas_template'] ) : 0;
			}

			if ( isset( $element_on_page['settings']['modal_template'] ) ) {
				$template_ids[] = ! empty( $element_on_page['settings']['modal_template'] ) ? intval( $element_on_page['settings']['modal_template'] ) : 0;
			}

			if ( isset( $element_on_page['settings']['templateId'] ) ) {
				$template_ids[] = ! empty( $element_on_page['settings']['templateId'] ) ? intval( $element_on_page['settings']['templateId'] ) : 0;
			}

			if ( isset( $element_on_page['settings']['shortcode'] ) ) {
				$template_ids[] = strstr( $element_on_page['settings']['shortcode'], '[bricks_template' ) ? (int) filter_var( $element_on_page['settings']['shortcode'], FILTER_SANITIZE_NUMBER_INT ) : 0;
			}

			if ( isset( $element_on_page['settings']['dataSource'] ) ) {

				if ( 'bricks' === $element_on_page['settings']['dataSource'] ) {

					$post_id = get_the_ID();

					if ( ! empty( $post_id ) ) {
						$template_ids[] = $post_id;
					}
				}
			}
		}

		foreach ( $template_ids as $template_id ) {

			$template_elements = get_post_meta( $template_id, \BRICKS_DB_PAGE_CONTENT, true );

			if ( ! empty( $template_elements ) ) {
				foreach ( $template_elements as $template_element ) {
					$elements_on_page_array[] = $template_element;
				}
			}
		}

		// Get all components data.
		$all_components = get_option( defined( '\BRICKS_DB_COMPONENTS' ) ? \BRICKS_DB_COMPONENTS : 'bricks_components', array() );

		// Keep track of processed component IDs to avoid infinite loops.
		$processed_component_ids = array();

		// Recursive function to process component elements.
		$process_component_elements = function ( $elements_array ) use ( &$process_component_elements, &$processed_component_ids, $all_components, &$elements_on_page_array ) {
			// Convert elements array to JSON to search for cid references.
			$elements_json = wp_json_encode( $elements_array );

			// Find all cid references in the data.
			preg_match_all( '/"cid":"(.*?)"/', $elements_json, $matches );

			if ( ! empty( $matches[1] ) ) {
				$found_component_ids = array_unique( $matches[1] );

				// For each found component ID, get its elements and add them to our array.
				foreach ( $found_component_ids as $component_id ) {
					// Skip if we've already processed this component.
					if ( in_array( $component_id, $processed_component_ids, true ) ) {
						continue;
					}

					// Mark this component as processed.
					$processed_component_ids[] = $component_id;

					// Find the component in the components data.
					foreach ( $all_components as $component ) {
						if ( $component['id'] === $component_id && ! empty( $component['elements'] ) ) {
							// Add all elements from this component to our array.
							foreach ( $component['elements'] as $component_element ) {
								$elements_on_page_array[] = $component_element;
							}

							// Recursively process the component elements.
							$process_component_elements( $component['elements'] );
							break;
						}
					}
				}
			}
		};

		// Start the recursive processing with the current elements.
		$process_component_elements( $elements_on_page_array );

		// Store the results in the cache before returning.
		$cached_elements = $elements_on_page_array;

		return $cached_elements;
	}

	/**
	 * Conditionally load default CSS for elements.
	 *
	 * @return void
	 */
	public function conditional_default_css() {

		global $bricks_extras_element_css_added;
		$bricks_extras_element_css_added['version'] = $this->version;

		$elements_on_page_array = self::get_elements_on_page();

		$elements_on_page_names = array_column( $elements_on_page_array, 'name' );

		// find all the active elements.
		foreach ( $this->elements as $key => $element ) {

			if ( 0 === intval( get_option( $this->prefix . $key, 0 ) ) ) {
				continue;
			}

			$name = str_replace( '-', '', $element['file_name'] );

			$bricks_extras_element_css_added[ $name ] = false;

			// check if our elements are being used on the page.
			if ( in_array( $name, $elements_on_page_names, true ) ) {

				// enqueue neccessary styles in head for that page.

				if ( ! isset( $element['stylesheet'] ) ) {
					$element['stylesheet'] = true;
				}

				if ( true === $element['stylesheet'] ) {
					$stylesheet = ltrim( str_replace( '-', '', $element['file_name'] ), 'x' );
				} elseif ( false !== $element['stylesheet'] ) {
					$stylesheet = $element['stylesheet'];
				}

				if ( (bool) $element['stylesheet'] ) {

					$bricks_extras_element_css_added[ $name ] = true;

					// Make sure the new versions of modal/offcanvas use the same CSS as the older ones.
					if ( 'xpromodalnestable' === $name ) {
						$handle = 'x-modal';
					} elseif ( 'xoffcanvasnestable' === $name ) {
						$handle = 'x-offcanvas';
					} elseif ( 'xmediaplayeraudio' === $name ) {
						$handle = 'x-media-player';
					} else {
						$handle = $element['file_name'];
					}

					if ( 'xproslider' === $name ) {
						// Include Splide CSS.
						wp_enqueue_style( 'bricks-splide' );
					}

					if ( 'xwsforms' === $name && method_exists( '\WS_Form_Common', 'styler_enabled' ) && \WS_Form_Common::styler_enabled() ) {
						$stylesheet = 'wsforms-styler-enabled';
					}

					if ( \Bricks\Database::get_setting( 'cssLoading' ) === 'file' || 'xwsforms' === $name ) {
						wp_enqueue_style( $handle, BRICKSEXTRAS_URL . 'components/assets/css/' . $stylesheet . '.css', array(), $this->version );
					} else {
						$minified_css = false;

						/* check for bricks v1.8.1 - Bricks changed helper function from get_file_contents to file_get_contents */
						if ( method_exists( '\Bricks\Helpers', 'get_file_contents' ) ) {
							$minified_css = \Bricks\Assets::minify_css( \Bricks\Helpers::get_file_contents( BRICKSEXTRAS_URL . 'components/assets/css/' . $stylesheet . '.css' ) );
						} elseif ( method_exists( '\Bricks\Helpers', 'file_get_contents' ) ) {
							$minified_css = \Bricks\Assets::minify_css( \Bricks\Helpers::file_get_contents( BRICKSEXTRAS_PATH . 'components/assets/css/' . $stylesheet . '.css' ) );
						}
						if ( $minified_css ) {
							wp_add_inline_style( 'bricks-frontend', $minified_css );
						} else {
							wp_enqueue_style( $handle, BRICKSEXTRAS_URL . 'components/assets/css/' . $stylesheet . '.css', array(), $this->version );
						}
					}
				}
			}
		}
	}

	/**
	 * Enqueue interactions script.
	 *
	 * @return void
	 */
	public function interactions_script() {
		wp_enqueue_script( 'x-interactions', BRICKSEXTRAS_URL . 'includes/js/interactions.min.js', array( 'bricks-scripts' ), $this->version, true );
	}

	/**
	 * Enqueue frontend scripts.
	 *
	 * @return void
	 */
	public function frontend_scripts() {

		/* WPGridbuilder facet support */
		if ( defined( 'WPGB_VERSION' ) ) {

			$elements_on_page_array = self::get_elements_on_page();
			$elements_on_page_names = array_column( $elements_on_page_array, 'name' );

			if ( in_array( 'wpgb-facet', $elements_on_page_names, true ) ) {

				if ( get_option( $this->prefix . 'wpgb_facets' ) ) {
					wp_enqueue_style( 'wpgb-facets-extras', BRICKSEXTRAS_URL . 'components/assets/css/wpgb-facets.css', array( 'wpgb-facets' ), $this->version );
				}

				wp_enqueue_script( 'wpgb-extras', BRICKSEXTRAS_URL . 'includes/js/wpgb-extras.js', array( 'wpgb-facets' ), $this->version, true );
			}
		}

		/* Jet Smart Filters support */
		if ( class_exists( 'Jet_Smart_Filters' ) ) {
			wp_enqueue_script( 'jsf-extras', BRICKSEXTRAS_URL . 'includes/js/jsf-extras.js', array( 'jet-smart-filters' ), $this->version, true );
		}

		/* Piotnet Grid Filters support */
		if ( class_exists( 'piotnetgrid' ) ) {
			wp_enqueue_script( 'piotnet-extras', BRICKSEXTRAS_URL . 'includes/js/piotnet-extras.js', array( 'piotnetgrid-script' ), $this->version, true );
		}
	}

	/**
	 * Enqueue global scripts.
	 *
	 * @return void
	 */
	public function global_scripts() {
		wp_enqueue_script( 'x-frontend', BRICKSEXTRAS_URL . 'components/assets/js/' . \BricksExtras\Helpers::maybe_minify_scripts( 'frontend' ) . '.js', array( 'bricks-scripts' ), $this->version, true );
	}

	/**
	 * Enqueue builder scripts.
	 *
	 * @return void
	 */
	public function builder_scripts() {

		if ( get_option( $this->prefix . 'x_ray' ) ) {
			wp_enqueue_script( 'bricks-editor', BRICKSEXTRAS_URL . 'includes/js/editor.js', array(), '1.0.0', true );
		}
	}

	/**
	 * Enqueue iframe scripts.
	 *
	 * @return void
	 */
	public function iframe_scripts() {

		if ( get_option( $this->prefix . 'wpgb_facets' ) ) {
			wp_enqueue_style( 'wpgb-facets-extras', BRICKSEXTRAS_URL . 'components/assets/css/wpgb-facets.css', array(), $this->version );
		}
	}


	/**
	 * Load all element CSS files in the Gutenberg editor and preview iframe
	 */
	public function load_gutenberg_css() {

		// Only load in admin context (Gutenberg editor or preview).
		if ( ! is_admin() ) {
			return;
		}

		// Include Splide CSS directly from our plugin.
		wp_enqueue_style(
			'bricksextras-splide',
			BRICKSEXTRAS_URL . 'components/assets/css/splide-layer.min.css',
			array(),
			$this->version
		);

		wp_enqueue_script(
			'x-frontend',
			BRICKSEXTRAS_URL . 'components/assets/js/frontend.min.js',
			array(),
			$this->version,
			false
		);

		// Load CSS for all active elements.
		foreach ( $this->elements as $element_key => $element_data ) {

			if ( isset( $element_data['element'] ) ) {
				continue;
			}

			$option_name = $this->prefix . $element_key;

			if ( get_option( $option_name ) ) {
				$file_name = $element_data['file_name'];
				$file_name = str_replace( 'x-', '', $file_name );

				// Get stylesheet name - remove hyphens to match actual filenames.
				if ( isset( $element_data['stylesheet'] ) && true !== $element_data['stylesheet'] ) {
					$stylesheet = $element_data['stylesheet'];
				} else {
					$stylesheet = ltrim( $file_name, 'x' );
				}

				// Remove hyphens from stylesheet name to match actual filenames.
				$stylesheet = str_replace( '-', '', $stylesheet );

				// Special cases for certain elements.
				if ( 'xpromodalnestable' === $file_name ) {
					$handle     = 'x-modal';
					$stylesheet = 'promodal'; // Use correct filename.
				} elseif ( 'xoffcanvasnestable' === $file_name ) {
					$handle     = 'x-offcanvas';
					$stylesheet = 'offcanvas'; // Use correct filename.
				} else {
					$handle = $element_data['file_name'];
				}

				// Skip elements with no stylesheet.
				if ( empty( $stylesheet ) ) {
					continue;
				}

				// Enqueue the CSS file.
				$css_file = BRICKSEXTRAS_URL . 'components/assets/css/' . $stylesheet . '.css';

				wp_enqueue_style(
					'bricksextras-gutenberg-' . $handle,
					$css_file,
					array(),
					$this->version
				);
			}
		}
	}

	/**
	 * Initialize Pro Slider in builder.
	 *
	 * @param array $attributes Body attributes.
	 * @return array Modified attributes.
	 */
	public function proslider_builder_init( $attributes ) {

		$init_pro_slider = false;

		/* allow for init if prefered */
		$init_pro_slider = apply_filters( 'bricksextras/proslider/builderinit', $init_pro_slider );

		if ( $init_pro_slider ) {
			$attributes['data-x-proslider-init'] = 'true';
		}

		return $attributes;
	}
}