<?php
namespace Prodigy\Includes;

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

/**
 * WP Rocket Compatibility Class
 *
 * Handles compatibility between Prodigy Commerce plugin and WP Rocket caching plugin
 *
 * @package Prodigy
 */
class Prodigy_WP_Rocket_Compatibility {

	private const PRODIGY_JS_FILES  = array(
		'prodigy-commerce',
		'public',
		'cart-widget',
		'price-filter',
		'my-account',
		'active-filter',
		'brands',
		'categories',
		'feature-products',
		'global',
		'swiper-bundle.min',
		'photoswipe.min',
		'photoswipe-ui-default.min',
		'jquery.magnific-popup.min',
		'jquery.inputmask.bundle.min',
		'popper.min',
		'bootstrap.min',
		'slick.min',
		'jquery.formstyler.min',
		'dd.min',
		'ion.rangeSlider.min',
		'prodigy-categories',
		'prodigy-category.js',
		'cart-page.js',
		'active-filter.js',
		'brands.js',
		'categories.js',
		'feature-products.js',
		'my-account.js',
		'price-filter.js',
	);
	private const PRODIGY_CSS_FILES = array(
		'styles',
		'photoswipe',
		'photoswipe-skin',
		'slick',
		'slick.theme',
		'dd',
		'inputmask',
		'customizer-range-value-style',
		'select2.min.css',
		'astra_theme',
		'twenty_nineteen_theme',
		'twenty_twenty_theme',
		'twenty_seventeen_theme',
		'hello_elementor_theme',
		'oceanwp_theme',
		'divi_theme',
		'flatsome_theme',
		'twenty_twenty_one_theme',
	);

	private const PRODIGY_COOKIES = array(
		'wordpress_prodigy_user_auth_token',
		'wordpress_prodigy_user_access_token',
		'wordpress_prodigy_user_refresh_token',
		'wordpress_prodigy_user_name',
		'wordpress_prodigy_user_email',
		'wordpress_prodigy_user_last_name',
		'wordpress_prodigy_user_phone',
		'wordpress_prodigy_cart',
	);

	private const PRODIGY_URIS = array(
		'/cart/',
		'/checkout/',
		'/my-account/',
		'/thank-you/',
		'/product/.*',
		'/product-category/.*',
		'/product-tag/.*',
		'/product-brand/.*',
		'/wp-admin/admin-ajax.php',
		'/prodigy-api/.*',
	);

	private const PRODIGY_AJAX_URIS = array(
		'/wp-admin/admin-ajax.php',
		'/prodigy-ajax/.*',
		'/api/prodigy/.*',
	);

	private const PRODIGY_MOBILE_FILES = array(
		'prodigy-mobile',
		'cart-mobile',
		'product-mobile',
	);


	private const PRODIGY_EXCLUDE_CDN = array(
		'prodigy-commerce',
		'cart',
		'product',
		'checkout',
	);

	private const PRODIGY_EXTERNAL_JS = array(
		'google-recaptcha',
		'googletagmanager.com',
		'google-analytics',
	);

	private const PRODIGY_INLINE_JS = array(
		'prodigy-commerce',
		'cart_data',
		'product_data',
		'filter_data',
		'ajax_url',
		'settings',
		'params',
		'options',
		'data',
	);

	private const PRODIGY_ATTRIBUTES = array(
		'data-prodigy-image',
		'data-product-image',
		'data-gallery-image',
		'class.*prodigy.*image',
		'class.*product.*image',
	);

	/**
	 * Initialize the compatibility class
	 */
	public function __construct() {
		if ( ! $this->is_wp_rocket_active() ) {
			return;
		}

		$this->init_hooks();
	}

	/**
	 * Check if WP Rocket is active
	 *
	 * @return bool
	 */
	private function is_wp_rocket_active(): bool {
		return function_exists( 'rocket_clean_domain' ) ||
				defined( 'WP_ROCKET_VERSION' ) ||
				is_plugin_active( 'wp-rocket/wp-rocket.php' );
	}

	/**
	 * Initialize all compatibility hooks
	 */
	private function init_hooks() {
		// Prevent caching of dynamic content
		add_action( 'init', array( $this, 'prevent_caching_on_dynamic_pages' ) );

		// Exclude Prodigy scripts from optimization
		add_filter( 'rocket_exclude_js', array( $this, 'exclude_js_from_optimization' ) );
		add_filter( 'rocket_exclude_css', array( $this, 'exclude_css_from_optimization' ) );

		// Exclude Prodigy cookies from cache
		add_filter( 'rocket_cache_dynamic_cookies', array( $this, 'add_dynamic_cookies' ) );
		add_filter( 'rocket_cache_reject_cookies', array( $this, 'add_reject_cookies' ) );

		// Exclude Prodigy URLs from cache
		add_filter( 'rocket_cache_reject_uri', array( $this, 'exclude_uris_from_cache' ) );

		// Handle cache purging for Prodigy content
		add_action( 'prodigy_content_updated', array( $this, 'purge_cache_on_content_update' ) );

		// Prevent lazy loading on Prodigy images
		add_filter( 'rocket_lazyload_excluded_attributes', array( $this, 'exclude_prodigy_images_from_lazyload' ) );

		// Handle AJAX requests properly
		add_filter( 'rocket_cache_reject_uri', array( $this, 'exclude_ajax_requests' ) );

		// Exclude Prodigy post types from cache
		add_filter( 'rocket_cache_reject_post_types', array( $this, 'exclude_post_types' ) );

		// Handle cart and user session caching
		add_action( 'wp_head', array( $this, 'add_cache_headers' ) );

		// Exclude Prodigy shortcodes from optimization
		add_filter( 'rocket_exclude_inline_js', array( $this, 'exclude_inline_js' ) );

		// Handle mobile cache separately
		add_filter( 'rocket_cache_mobile_files_tablet', array( $this, 'exclude_mobile_cache' ) );

		// Prevent minification of Prodigy scripts
		add_filter( 'rocket_minify_excluded_external_js', array( $this, 'exclude_external_js' ) );

		// Handle CDN exclusions
		add_filter( 'rocket_cdn_reject_files', array( $this, 'exclude_from_cdn' ) );
	}

	/**
	 * Prevent caching on dynamic Prodigy pages
	 */
	public function prevent_caching_on_dynamic_pages() {
		// Don't cache cart page
		if ( is_page() && $this->is_cart_page() ) {
			add_filter( 'rocket_override_donotcachepage', '__return_true' );
		}

		// Don't cache user account pages
		if ( $this->is_user_logged_in() ) {
			add_filter( 'rocket_override_donotcachepage', '__return_true' );
		}
	}

	/**
	 * Exclude Prodigy JavaScript files from optimization
	 *
	 * @param   array $excluded_files
	 *
	 * @return array
	 */
	public function exclude_js_from_optimization( array $excluded_files ): array {
		foreach ( self::PRODIGY_JS_FILES as $file ) {
			$excluded_files[] = $file;
		}

		return $excluded_files;
	}

	/**
	 * Exclude Prodigy CSS files from optimization
	 *
	 * @param   array $excluded_files
	 *
	 * @return array
	 */
	public function exclude_css_from_optimization( array $excluded_files ): array {
		foreach ( self::PRODIGY_CSS_FILES as $file ) {
			$excluded_files[] = $file;
		}

		return $excluded_files;
	}

	/**
	 * Add Prodigy cookies to dynamic cookies list
	 *
	 * @param   array $cookies
	 *
	 * @return array
	 */
	public function add_dynamic_cookies( array $cookies ): array {
		if ( ! isset( $cookies ) ) {
			$cookies = array();
		}

		return array_merge( $cookies, self::PRODIGY_COOKIES );
	}

	/**
	 * Add Prodigy cookies to reject cookies list
	 *
	 * @param   array $cookies
	 *
	 * @return array
	 */
	public function add_reject_cookies( array $cookies ): array {
		if ( ! isset( $cookies ) ) {
			$cookies = array();
		}

		return array_merge( $cookies, self::PRODIGY_COOKIES );
	}

	/**
	 * Exclude Prodigy URIs from cache
	 *
	 * @param   array $uris
	 *
	 * @return array
	 */
	public function exclude_uris_from_cache( array $uris ): array {
		if ( ! isset( $uris ) ) {
			$uris = array();
		}

		return array_merge( $uris, self::PRODIGY_URIS );
	}

	/**
	 * Exclude AJAX requests from cache
	 *
	 * @param   array $uris
	 *
	 * @return array
	 */
	public function exclude_ajax_requests( array $uris ): array {
		if ( ! isset( $uris ) ) {
			$uris = array();
		}

		return array_merge( $uris, self::PRODIGY_AJAX_URIS );
	}

	/**
	 * Exclude Prodigy post types from cache
	 *
	 * @param   array $post_types
	 *
	 * @return array
	 */
	public function exclude_post_types( array $post_types ): array {
		$prodigy_post_types = array(
			Prodigy::get_prodigy_product_type(),
			Prodigy::PRODIGY_VARIATION_POST_TYPE,
		);
		if ( ! isset( $post_types ) ) {
			$post_types = array();
		}

		return array_merge( $post_types, $prodigy_post_types );
	}

	/**
	 * Exclude Prodigy images from lazy loading
	 *
	 * @param   array $attributes
	 *
	 * @return array
	 */
	public function exclude_prodigy_images_from_lazyload( array $attributes ): array {
		if ( ! isset( $attributes ) ) {
			$attributes = array();
		}

		return array_merge( $attributes, self::PRODIGY_ATTRIBUTES );
	}

	/**
	 * Exclude inline JavaScript from optimization
	 *
	 * @param   array $inline_js
	 *
	 * @return array
	 */
	public function exclude_inline_js( array $inline_js ): array {
		if ( ! isset( $inline_js ) ) {
			$inline_js = array();
		}

		return array_merge( $inline_js, self::PRODIGY_INLINE_JS );
	}

	/**
	 * Exclude external JavaScript from minification
	 *
	 * @param   array $external_js
	 *
	 * @return array
	 */
	public function exclude_external_js( array $external_js ): array {
		if ( ! isset( $external_js ) ) {
			$external_js = array();
		}

		return array_merge( $external_js, self::PRODIGY_EXTERNAL_JS );
	}

	/**
	 * Exclude files from CDN
	 *
	 * @param   array $files
	 *
	 * @return array
	 */
	public function exclude_from_cdn( array $files ): array {
		if ( ! isset( $files ) ) {
			$files = array();
		}

		return array_merge( $files, self::PRODIGY_EXCLUDE_CDN );
	}

	/**
	 * Exclude mobile cache for Prodigy content
	 *
	 * @param   array|string $files
	 *
	 * @return array
	 */
	public function exclude_mobile_cache( $files ): array {
		if ( ! is_array( $files ) ) {
			$files = array_filter( array( $files ) );
		}

		return array_merge( $files, self::PRODIGY_MOBILE_FILES );
	}

	/**
	 * Add cache headers for Prodigy pages
	 */
	public function add_cache_headers() {
		if ( $this->is_user_logged_in() || $this->is_cart_page() ) {
			header( 'Cache-Control: no-cache, no-store, must-revalidate' );
			header( 'Pragma: no-cache' );
			header( 'Expires: 0' );
		}
	}

	/**
	 * Purge cache when Prodigy content is updated
	 */
	public function purge_cache_on_content_update() {
		if ( function_exists( 'rocket_clean_domain' ) ) {
			rocket_clean_domain();
		}
	}

	/**
	 * Check if current page is cart page
	 *
	 * @return bool
	 */
	private function is_cart_page(): bool {
		global $post;

		if ( ! $post ) {
			return false;
		}

		$cart_page_id = get_option( 'prodigy_cart_page_id' );

		return $cart_page_id && $post->ID == $cart_page_id;
	}

	/**
	 * Check if user is logged in
	 *
	 * @return bool
	 */
	private function is_user_logged_in(): bool {
		return isset( $_COOKIE['wordpress_prodigy_user_auth_token'] ) || isset( $_COOKIE['wordpress_prodigy_user_access_token'] );
	}
}

new Prodigy_WP_Rocket_Compatibility();
