<?php
/**
 * Cache module — Theme Compat: Avada / Fusion Builder
 *
 * Avada compiles its CSS bundle dynamically and detects active output buffers
 * from cache plugins; when it finds one, it silently downgrades to a minimal
 * CSS bundle, leaving the cached HTML visually broken. The constant
 * FUSION_DISABLE_COMPILERS short-circuits that detection and forces Avada to
 * enqueue the full CSS — making the cache safe to serve.
 *
 * Same approach as WP Rocket's inc/ThirdParty/Themes/Avada.php (line 136-140).
 *
 * @package BlaminhorEssentials
 */

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

class Blaminhor_Essentials_Cache_Theme_Compat_Avada extends Blaminhor_Essentials_Cache_Theme_Compat_Base {

	public function id() {
		return 'avada';
	}

	public function label() {
		return 'Avada / Fusion Builder';
	}

	public function is_active() {
		if ( ! function_exists( 'wp_get_theme' ) ) {
			return false;
		}
		$theme      = wp_get_theme();
		$template   = strtolower( (string) $theme->get_template() );
		$stylesheet = strtolower( (string) $theme->get_stylesheet() );
		return 'avada' === $template
			|| 'avada' === $stylesheet
			|| false !== strpos( $stylesheet, 'avada' );
	}

	public function register_hooks() {
		// Note: FUSION_DISABLE_COMPILERS, when needed, is set by the bootstrap
		// in blaminhor-essentials.php on 'plugins_loaded' priority 0, BEFORE
		// the Cache module instantiates (which happens on 'init', too late).
		// It is only set when an aggressive optimisation (RUCSS, full minify,
		// critical CSS) actually needs the CSS bundle uncompiled. With Avada's
		// default rendering and our cache off-the-shelf, the constant is NOT
		// set — the JS compiler keeps defining `window.fusion` and animations
		// keep working. Cache stays correct because Avada's dynamic CSS file
		// is generated on the fly and referenced by URL in the cached HTML.

		// Bidirectional purge sync: when Avada invalidates its dynamic CSS or
		// the Fusion Cache builder cache, our HTML cache is stale too.
		add_action( 'avada_clear_dynamic_css_cache', array( $this, 'purge_all' ) );
		add_action( 'fusion_cache_reset_after', array( $this, 'purge_all' ) );
	}

	public function purge_all() {
		if ( $this->parent->purge ) {
			$this->parent->purge->purge_all();
		}
	}

	public function defer_js_exclusions() {
		// Avada relies on jQuery being parse-blocking; deferring it breaks the
		// menu, sliders and any inline jQuery() bootstrap. Maps must also load
		// synchronously for the location pages.
		return array(
			'#/jquery-?[0-9.]*(.min|.slim|.slim.min)?\.js#',
			'maps.googleapis.com',
		);
	}

	public function delay_js_exclusions() {
		// Flexslider drives the WooCommerce product gallery; delaying it leaves
		// the gallery image static and clickable areas dead.
		return array(
			'/jquery.flexslider.js',
			'/avada-woo-product-images.js',
			'fusionNavIsCollapsed',
		);
	}

	public function rucss_safelist() {
		return array(
			'.fusion-',
			'.awb-',
			'#main',
			'#wrapper',
			'.avada-',
		);
	}

	public function async_css_excluded_handles() {
		// Avada's CSS bundle relies on a strict sourcing order:
		//   parent fusion-stylesheet  →  child-style overrides  →  fusion-dynamic-css
		//   compiled rules with the highest specificity. Letting the Critical CSS
		//   async loader rewrite any of these as <link rel="preload">
		//   serializes their application to network-arrival order, which inverts
		//   the cascade and strips container max-widths off `.fusion-row` etc.
		return array(
			'child-style',
			'fusion-',
			'awb-',
			'avada-',
		);
	}
}
