<?php

namespace Brandy\BlockSettings\CustomBoxShadow;

use Brandy\Traits\SingletonTrait;
use Brandy\Utils\Helpers;

class Caller {
	use SingletonTrait;

	/**
	 * Track if frontend styles already enqueued.
	 *
	 * @var bool
	 */
	private $frontend_styles_enqueued = false;

	protected function __construct() {
		add_action( 'enqueue_block_editor_assets', array( $this, 'enqueue_settings_scripts' ) );
		add_action( 'enqueue_block_assets', array( $this, 'enqueue_editor_styles' ) ); // Enqueuing frontend styles in editor.
		add_filter( 'render_block_woocommerce/product-button', array( $this, 'apply_shadow_settings' ), 10, 2 );
		add_filter( 'render_block', array( $this, 'apply_shadow_settings_to_blocks' ), 10, 3 );
	}

	private function is_block_support_shadow( $settings ) {
		return ! empty( $settings['supports']['shadow'] )
		|| ( isset( $settings['name'] ) && in_array( $settings['name'], array( 'core/avatar', 'core/paragraph', 'core/heading', 'woocommerce/product-button' ) ) );
	}

	public function enqueue_settings_scripts() {
		wp_enqueue_script(
			'brandy/custom-box-shadow-controls',
			BRANDY_TEMPLATE_URL . '/inc/BlockSettings/CustomBoxShadow/script.js',
			array( 'wp-edit-post', 'wp-element', 'wp-compose', 'wp-blocks', 'wp-hooks', 'wp-i18n', 'wp-components', 'wp-block-editor' ),
			BRANDY_SCRIPT_VERSION,
			true
		);
		wp_enqueue_style(
			'brandy/custom-box-shadow-editor',
			BRANDY_TEMPLATE_URL . '/inc/BlockSettings/CustomBoxShadow/editor.css',
			array(),
			BRANDY_SCRIPT_VERSION
		);
	}

	public function enqueue_editor_styles() {
		$this->maybe_enqueue_frontend_styles( true );
	}

	/**
	 * Enqueue frontend styles only when needed.
	 */
	private function maybe_enqueue_frontend_styles( $admin_enqueue = false ) {
		if ( ! $admin_enqueue && is_admin() ) {
			return;
		}

		if ( $admin_enqueue && ! is_admin() ) {
			return;
		}

		if ( $this->frontend_styles_enqueued ) {
			return;
		}
		$this->frontend_styles_enqueued = true;
		wp_enqueue_style(
			'brandy/custom-box-shadow-style',
			BRANDY_TEMPLATE_URL . '/inc/BlockSettings/CustomBoxShadow/style.css',
			array(),
			BRANDY_SCRIPT_VERSION
		);
	}

	public function apply_shadow_settings( $html, $block ) {

		$tag = new \WP_HTML_Tag_Processor( $html );

		if ( $tag->next_tag() ) {
			// Get hover-related attributes
			if ( $tag->get_attribute( 'data-hover-shadow' ) ) {
				$hover_shadow = json_decode( $tag->get_attribute( 'data-hover-shadow' ), true );
			}

			$escape_styles = array();

			if ( ! empty( $hover_shadow ) && is_string( $hover_shadow ) ) {
				if ( 'unset' !== $hover_shadow ) {
					$escape_styles[] = '--hover-box-shadow: ' . Helpers::get_ref_shadow( $hover_shadow );
				}
			}

			// Update the style attribute
			$existing_style = $tag->get_attribute( 'style' );
			$updated_style  = '';

			if ( empty( $existing_style ) ) {
				$existing_style = '';
			} elseif ( ! str_ends_with( $existing_style, ';' ) ) {
				$existing_style .= ';';
			}

			$updated_style  = $existing_style;
			$updated_style .= implode( ';', $escape_styles );

			if ( ! empty( $escape_styles ) ) {
				$this->maybe_enqueue_frontend_styles();
			}

			$tag->set_attribute( 'style', $updated_style );

			$html = $tag->get_updated_html();
		}

		return $html;
	}

	public function apply_shadow_settings_to_blocks( $html, $_, $block ) {
		$tag = new \WP_HTML_Tag_Processor( $html );

		if ( $tag->next_tag() ) {
			if ( $this->is_block_support_shadow( (array) $block->block_type ) && ! empty( $block->attributes['style']['hoverShadow'] ) ) {
				$hover_shadow = $block->attributes['style']['hoverShadow'];
			}

			$escape_styles = array();

			// Manage hover shadow style
			if ( ! empty( $hover_shadow ) && is_string( $hover_shadow ) ) {
				if ( 'unset' !== $hover_shadow ) {
					$escape_styles[] = '--hover-box-shadow: ' . Helpers::get_ref_shadow( $hover_shadow );
				}
			}

			$existing_style = $tag->get_attribute( 'style' );
			$updated_style  = '';

			if ( empty( $existing_style ) ) {
				$existing_style = '';
			} elseif ( ! str_ends_with( $existing_style, ';' ) ) {
				$existing_style .= ';';
			}

			$updated_style  = $existing_style;
			$updated_style .= implode( ';', $escape_styles );

			if ( ! empty( $escape_styles ) ) {
				$this->maybe_enqueue_frontend_styles();
			}

			$tag->set_attribute( 'style', $updated_style );

			$html = $tag->get_updated_html();
		}

		return $html;
	}
}

Caller::get_instance();
