<?php
/**
 * Main loader class for Product Display.
 *
 * @package Product_Display.
 */

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

/**
 * Class PRODDISP_Loader.
 *
 * This class is responsible for loading the necessary components of the plugin.
 */
class PRODDISP_Loader {
	/**
	 * The single instance of the class.
	 */
	protected static $_instance = null;

	/**
	 * Main Instance.
	 */
	public static function get_instance() {
		if ( is_null(self::$_instance) ) {
			self::$_instance = new self();
		}
		return self::$_instance;
	}

	/**
	 * Constructor.
	 */
	public function __construct() {
		$this->includes();
		$this->init_hooks();
		$this->register_query_vars();
	}

	/**
	 * Include necessary files.
	 *
	 * This method includes all the required classes and files for the plugin to function.
	 */
	private function includes() {
		// Always include assets class
		require_once PRODDISP_PLUGIN_DIR . 'inc/class-proddisp-assets.php';

		// Include base layout class
		require_once PRODDISP_PLUGIN_DIR . 'inc/base/class-proddisp-layout-base.php';

		// Include layout classes
		require_once PRODDISP_PLUGIN_DIR . 'inc/layouts/grid/class-proddisp-grid.php';
		require_once PRODDISP_PLUGIN_DIR . 'inc/layouts/card/class-proddisp-grid-card.php';
		require_once PRODDISP_PLUGIN_DIR . 'inc/layouts/list/class-proddisp-list.php';
		require_once PRODDISP_PLUGIN_DIR . 'inc/layouts/masonry/class-proddisp-grid-masonry.php';
		require_once PRODDISP_PLUGIN_DIR . 'inc/layouts/slider/class-proddisp-slider.php';
		require_once PRODDISP_PLUGIN_DIR . 'inc/layouts/table/class-proddisp-table.php';
		require_once PRODDISP_PLUGIN_DIR . 'inc/layouts/flip/class-proddisp-flip.php';
		require_once PRODDISP_PLUGIN_DIR . 'inc/layouts/gallery/class-proddisp-gallery.php';

		// Always include the free showcase class (it handles PRO detection internally)
		require_once PRODDISP_PLUGIN_DIR . 'inc/layouts/showcase/class-proddisp-showcase-free.php';

		require_once PRODDISP_PLUGIN_DIR . 'inc/layouts/category-tabs/class-proddisp-category-tabs.php';
		require_once PRODDISP_PLUGIN_DIR . 'inc/layouts/cta/class-proddisp-cta.php';
		require_once PRODDISP_PLUGIN_DIR . 'inc/layouts/caption/class-proddisp-caption.php';

		// Include shortcode class
		require_once PRODDISP_PLUGIN_DIR . 'inc/class-proddisp-shortcode.php';

		// Include feature classes
		require_once PRODDISP_PLUGIN_DIR . 'inc/features/class-proddisp-compare.php';
		require_once PRODDISP_PLUGIN_DIR . 'inc/features/class-proddisp-quickview.php';
		require_once PRODDISP_PLUGIN_DIR . 'inc/features/class-proddisp-wishlist.php';
		require_once PRODDISP_PLUGIN_DIR . 'inc/features/class-proddisp-wishlist-analytics.php';
		require_once PRODDISP_PLUGIN_DIR . 'inc/features/class-proddisp-shop-integration.php';

		// Include wishlist settings (needed for both frontend and admin)
		require_once PRODDISP_PLUGIN_DIR . 'inc/admin/class-proddisp-wishlist-settings.php';

		if ( is_admin() ) {
			require_once PRODDISP_PLUGIN_DIR . 'inc/admin/class-proddisp-admin.php';
			require_once PRODDISP_PLUGIN_DIR . 'inc/admin/class-proddisp-recommendations.php';
		}

		// Include Elementor integration if Elementor is active
		if ( $this->is_elementor_active() ) {
			require_once PRODDISP_PLUGIN_DIR . 'inc/class-proddisp-elementor.php';
		}

		// Include Gutenberg integration if Gutenberg is active
		if ( $this->is_gutenberg_active() ) {
			require_once PRODDISP_PLUGIN_DIR . 'inc/class-proddisp-gutenberg.php';
		}
	}

	/**
	 * Initialize hooks.
	 */
	private function init_hooks() {

		// Initialize shortcode
		PRODDISP_Shortcode::get_instance();

		// Initialize features
		PRODDISP_Compare::get_instance();
		PRODDISP_Quickview::get_instance();
		
		// Initialize wishlist after WordPress is fully loaded
		add_action('wp_loaded', array( $this, 'init_wishlist' ));
		
		PRODDISP_Shop_Integration::get_instance();

		// Initialize admin if in admin area.
		if ( is_admin() ) {
			PRODDISP_Admin::get_instance();
		}

		// Initialize Elementor integration if Elementor is active
		if ( $this->is_elementor_active() ) {
			PRODDISP_Elementor::get_instance();
		}

		// Initialize Gutenberg integration if Gutenberg is active
		if ( $this->is_gutenberg_active() ) {
			PRODDISP_Gutenberg::get_instance();
		}

		// Add plugin action links.
		add_filter('plugin_action_links_' . PRODDISP_PLUGIN_BASENAME, array( $this, 'add_plugin_action_links' ));
	}

	/**
	 * Initialize wishlist feature.
	 */
	public function init_wishlist() {
		PRODDISP_Wishlist::get_instance();

		// Only initialize analytics if Pro is active
		if ( self::is_pro_active() ) {
			PRODDISP_Wishlist_Analytics::get_instance();

			// Create table only when needed (check via option to avoid dbDelta on every load)
			$db_version = get_option( 'proddisp_analytics_db_version', '0' );
			if ( version_compare( $db_version, '1.0', '<' ) ) {
				PRODDISP_Wishlist_Analytics::create_table();
				update_option( 'proddisp_analytics_db_version', '1.0' );
			}
		}
	}

	/**
	 * Add plugin action links.
	 */
	public function add_plugin_action_links( $links ) {
		$plugin_links = array(
			'<a href="' . admin_url('admin.php?page=product-display') . '">' . __('Settings', 'product-display') . '</a>',
		);
		return array_merge($plugin_links, $links);
	}

	/**
	 * Check if Pro version is active and compatible.
	 */
	public static function is_pro_active() {
		// First check if the pro plugin file exists
		$pro_file_exists = file_exists( WP_PLUGIN_DIR . '/product-display-pro/product-display-pro.php' );

		if ( ! $pro_file_exists ) {
			return false;
		}

		// Then check if it's active in WordPress
		include_once ABSPATH . 'wp-admin/includes/plugin.php';
		$is_plugin_active = \is_plugin_active(
			defined('PRODDISP_PRO_PLUGIN_BASENAME')
				? PRODDISP_PRO_PLUGIN_BASENAME
				: 'product-display-pro/product-display-pro.php'
		);

		// If plugin is not active, return false
		if ( ! $is_plugin_active ) {
			return false;
		}

		// Check version compatibility - Free 2.2.1 requires Pro 1.2.2+
		if ( defined( 'PRODDISP_VERSION' ) && defined( 'PRODDISP_MIN_PRO_VERSION' ) && defined( 'PRODDISP_PRO_VERSION' ) ) {
			if ( version_compare( PRODDISP_VERSION, '2.2.1', '>=' ) ) {
				// Free version is 2.2.1+, check if Pro is 1.2.2+
				if ( version_compare( PRODDISP_PRO_VERSION, PRODDISP_MIN_PRO_VERSION, '<' ) ) {
					// Pro version is too old
					return false;
				}
			}
		}

		// Check Freemius premium status
		if ( function_exists( 'pd_fs' ) ) {
			return pd_fs()->can_use_premium_code__premium_only();
		}

		return false;

	}


	/**
	 * Render locked layout for pro features.
	 *
	 * @param string $image_filename The locked layout image filename.
	 * @return string HTML output for locked layout.
	 */
	public static function render_locked_layout( $image_filename ) {
		// Use external URL for locked layout images like the old version
		$image_url = 'https://wpazleen.com/wp-content/uploads/2025/product-display/' . $image_filename;
		$output = '<div class="proddisp-locked-layout">';
		$output .= '<img src="' . esc_url($image_url) . '" alt="Pro Layout Locked" style="max-width:100%;height:auto;" />';
		$output .= '<div class="proddisp-locked-message">This layout is available in the Pro version. <span class="wcps-upgrade-pro-btn toast-tag-pro" tabindex="0">Upgrade to Pro</span> to unlock!</div>';
		$output .= '</div>';
		return $output;
	}

	/**
	 * Load pro layout class and render.
	 *
	 * @param string $layout_class Pro layout class name.
	 * @param array  $settings Layout settings.
	 * @param array  $products Products array.
	 * @return string HTML output from pro layout.
	 */
	public static function load_pro_layout( $layout_class, $settings, $products ) {
		if ( ! self::is_pro_active() ) {
			return '';
		}

		// Try to use Composer autoloading first
		if ( class_exists($layout_class) ) {
			$pro_layout = new $layout_class($settings);
			return $pro_layout->render($products);
		}

		// Fallback to manual require if class doesn't exist
		$pro_file_path = PRODDISP_PRO_PLUGIN_DIR . 'inc/layouts/' . strtolower(str_replace('PRODDISP_PRO_', '', $layout_class)) . '/class-proddisp-pro-' . strtolower(str_replace('PRODDISP_PRO_', '', $layout_class)) . '.php';

		if ( file_exists($pro_file_path) ) {
			require_once $pro_file_path;
			if ( class_exists($layout_class) ) {
				$pro_layout = new $layout_class($settings);
				return $pro_layout->render($products);
			}
		}

		return '';
	}

	/**
	 * Register custom query vars for pagination.
	 */
	private function register_query_vars() {
		add_filter('query_vars', array( $this, 'add_query_vars' ));
	}

	/**
	 * Add custom query vars.
	 *
	 * @param array $vars Existing query vars.
	 * @return array Modified query vars.
	 */
	public function add_query_vars( $vars ) {
		$vars[] = 'wcps_page';
		return $vars;
	}

	/**
	 * Check if Elementor is active and loaded.
	 */
	private function is_elementor_active() {
		// Check if Elementor plugin is active
		include_once ABSPATH . 'wp-admin/includes/plugin.php';

		if ( ! \is_plugin_active( 'elementor/elementor.php' ) ) {
			return false;
		}

		// Check if Elementor is loaded
		return did_action( 'elementor/loaded' ) || class_exists( '\Elementor\Plugin' );
	}

	/**
	 * Check if Gutenberg is active and available.
	 */
	private function is_gutenberg_active() {
		// Check if block editor is available (WordPress 5.0+)
		if ( ! function_exists( 'register_block_type' ) ) {
			return false;
		}

		// Check if Gutenberg plugin is active or WordPress has built-in block editor
		return function_exists( 'gutenberg_init' ) || version_compare( get_bloginfo( 'version' ), '5.0', '>=' );
	}
}
