<?php
/**
 * Front-end SEO UI enqueue guards.
 *
 * WooCommerce Cart/Checkout blocks treat the presence of the core/editor data
 * store (registered by wp-editor) as "running inside the block editor" and then
 * render preview products instead of the real cart. This helper keeps SEOvault
 * (and future FE SEO UI) from loading editor-dependent bundles on those pages.
 *
 * @package SEOvaultSEO\Utils
 */

namespace SEOvaultSEO\Utils;

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

/**
 * Gates and dequeues front-end SEO / editor-adjacent assets.
 */
final class FrontendSeoEnqueue {

	/**
	 * Register late dequeue safety net.
	 *
	 * @return void
	 */
	public static function init() {
		add_action( 'wp_enqueue_scripts', array( __CLASS__, 'dequeue_editor_dependent_assets' ), 999 );
	}

	/**
	 * Whether front-end SEO UI assets may load on the current request.
	 *
	 * Use this before enqueuing any future FE SEO metabox / badge / admin-bar UI.
	 *
	 * @return bool
	 */
	public static function should_enqueue_frontend_seo_ui() {
		$allow = true;

		if ( self::is_excluded_request_context() || self::is_woocommerce_transactional_page() ) {
			$allow = false;
		}

		/**
		 * Filter whether front-end SEO UI assets may enqueue.
		 *
		 * @param bool $allow Default allow decision.
		 */
		return (bool) apply_filters( 'seovaultseo_enqueue_frontend_seo_ui', $allow );
	}

	/**
	 * Whether the current request is a WooCommerce cart or checkout page
	 * (classic shortcodes or Cart/Checkout blocks).
	 *
	 * @return bool
	 */
	public static function is_woocommerce_transactional_page() {
		$is_transactional = false;

		if ( function_exists( 'is_cart' ) && is_cart() ) {
			$is_transactional = true;
		} elseif ( function_exists( 'is_checkout' ) && is_checkout() ) {
			$is_transactional = true;
		} elseif ( function_exists( 'wc_get_page_id' ) && is_singular( 'page' ) ) {
			$page_id = (int) get_queried_object_id();
			if ( $page_id > 0 ) {
				foreach ( array( 'cart', 'checkout' ) as $page ) {
					if ( $page_id === (int) wc_get_page_id( $page ) ) {
						$is_transactional = true;
						break;
					}
				}
			}
		}

		/**
		 * Filter WooCommerce cart/checkout detection for enqueue exclusion.
		 *
		 * @param bool $is_transactional Whether this is a cart/checkout context.
		 */
		return (bool) apply_filters( 'seovaultseo_is_woocommerce_transactional_page', $is_transactional );
	}

	/**
	 * Shared-URL contexts that fire wp_enqueue_scripts but must not get SEO UI.
	 *
	 * @return bool
	 */
	public static function is_excluded_request_context() {
		if ( wp_doing_ajax() ) {
			return true;
		}

		if ( defined( 'REST_REQUEST' ) && REST_REQUEST ) {
			return true;
		}

		if ( is_feed() || is_embed() || is_customize_preview() || is_preview() ) {
			return true;
		}

		// Third-party visual-builder previews on a public URL.
		// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only GET probe for builder preview.
		if ( isset( $_GET['elementor-preview'] ) ) {
			return true;
		}

		if ( function_exists( 'bricks_is_builder' ) && bricks_is_builder() ) {
			return true;
		}

		if ( function_exists( 'et_fb_is_enabled' ) && et_fb_is_enabled() ) {
			return true;
		}

		return false;
	}

	/**
	 * Script/style handles that must not load on WooCommerce cart/checkout.
	 *
	 * Includes wp-editor (registers core/editor store — breaks Cart/Checkout
	 * blocks) and SEOvault admin SEO UI bundles that must stay off the front end.
	 *
	 * @return array<int, string>
	 */
	public static function get_editor_dependent_handles() {
		$handles = array(
			'wp-editor',
			'wp-edit-post',
			'wp-block-editor',
			'seovaultseo-metabox',
		);

		/**
		 * Filter handles treated as editor-dependent for cart/checkout exclusion.
		 *
		 * @param array<int, string> $handles Script/style handles.
		 */
		return apply_filters( 'seovaultseo_editor_dependent_handles', $handles );
	}

	/**
	 * Whether a handle is editor-dependent.
	 *
	 * @param string $handle Script or style handle.
	 * @return bool
	 */
	public static function is_editor_dependent_handle( $handle ) {
		$handle = (string) $handle;
		return in_array( $handle, self::get_editor_dependent_handles(), true );
	}

	/**
	 * Whether a specific handle may be enqueued on the current front-end request.
	 *
	 * @param string $handle Script or style handle.
	 * @return bool
	 */
	public static function should_enqueue_handle( $handle ) {
		$handle = (string) $handle;

		if ( self::is_editor_dependent_handle( $handle ) && self::is_woocommerce_transactional_page() ) {
			return false;
		}

		if ( self::is_editor_dependent_handle( $handle ) && ! is_admin() && ! self::should_enqueue_frontend_seo_ui() ) {
			return false;
		}

		return true;
	}

	/**
	 * Late safety net: dequeue editor-dependent assets on cart/checkout.
	 *
	 * @return void
	 */
	public static function dequeue_editor_dependent_assets() {
		if ( is_admin() && ! wp_doing_ajax() ) {
			return;
		}

		if ( ! self::is_woocommerce_transactional_page() ) {
			return;
		}

		foreach ( self::get_editor_dependent_handles() as $handle ) {
			if ( wp_script_is( $handle, 'enqueued' ) || wp_script_is( $handle, 'registered' ) ) {
				wp_dequeue_script( $handle );
				wp_deregister_script( $handle );
			}
			if ( wp_style_is( $handle, 'enqueued' ) || wp_style_is( $handle, 'registered' ) ) {
				wp_dequeue_style( $handle );
				wp_deregister_style( $handle );
			}
		}
	}
}
