<?php

namespace Brandy\BlockSettings\HoverSettings;

use Brandy\Traits\SingletonTrait;

class Caller {
	use SingletonTrait;

	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' ) );
		add_filter( 'render_block_woocommerce/product-button', array( $this, 'apply_hover_settings_to_product_button_block' ), 10, 2 );
		add_filter( 'render_block', array( $this, 'apply_hover_settings_to_blocks' ), 10, 3 );
	}

	private function is_block_support_text_color( $settings ) {
		return ! empty( $settings['supports']['color']['text'] ) || ! empty( $settings['supports']['color']['__experimentalDefaultControls']['text'] );
	}

	private function is_block_support_background_color( $settings ) {
		return ! empty( $settings['supports']['color']['background'] ) || ! empty( $settings['supports']['color']['__experimentalDefaultControls']['background'] );
	}

	private function is_block_support_border( $settings ) {
		return ! empty( $settings['supports']['__experimentalBorder'] );
	}

	private function is_block_need_overflow_hidden( $settings ) {
		return ! empty( $settings['supports']['__experimentalBorder'] ) && isset( $settings['name'] ) && in_array( $settings['name'], array( 'core/group', 'core/columns' ) );
	}

	public function enqueue_settings_scripts() {
		wp_enqueue_script(
			'brandy/hover-settings-controls',
			BRANDY_TEMPLATE_URL . '/inc/BlockSettings/HoverSettings/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
		);

		// Pass outline hover style to JS for per-block hover generation
		$global_settings    = wp_get_global_settings();
		$outline_hover_style = $global_settings['custom']['color']['button']['outline']['hover-style'] ?? 'solid';
		wp_localize_script( 'brandy/hover-settings-controls', 'brandyHoverSettings', array(
			'outlineHoverStyle' => $outline_hover_style,
		) );
	}

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

	public 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_register_style( 'brandy/hover-settings-style', false );
		wp_enqueue_style( 'brandy/hover-settings-style' );
		wp_add_inline_style( 'brandy/hover-settings-style', $this->get_css() );
	}

	public function get_css() {
		ob_start();
		?>
		.block-editor-block-list__block.wp-block-button:where(
[style*="--hover-color"]
):hover .wp-element-button,.block-editor-block-list__block.wp-block-woocommerce-product-button:where(
[style*="--hover-color"]
):hover .wp-element-button,.wp-block-button:where([style*="--hover-color"]) .wp-element-button:hover,:where([style*="--hover-color"]):not(
.wp-block-button,.block-editor-block-list__block.wp-block-woocommerce-product-button
):hover{color:var(--hover-color)!important}.block-editor-block-list__block.wp-block-button:where(
[style*="--hover-background-color"]
):hover .wp-element-button,.block-editor-block-list__block.wp-block-woocommerce-product-button:where(
[style*="--hover-background-color"]
):hover .wp-element-button,.wp-block-button:where([style*="--hover-background-color"]) .wp-element-button:hover,:where([style*="--hover-background-color"]):not(
.wp-block-button,.block-editor-block-list__block.wp-block-woocommerce-product-button
):hover{background:var(--hover-background-color)!important}.block-editor-block-list__block.wp-block-woocommerce-product-button:where(
[style*="--hover-border-w"]
):hover .wp-element-button,.wp-block-button:where([style*="--hover-border-w"]) .wp-element-button:hover,:where([style*="--hover-border-w"]):not(.wp-block-button):hover{border-width:var(--hover-border-w)!important}.block-editor-block-list__block.wp-block-woocommerce-product-button:where(
[style*="--hover-border-c"]
):hover .wp-element-button,.wp-block-button:where([style*="--hover-border-c"]) .wp-element-button:hover,:where([style*="--hover-border-c"]):not(.wp-block-button):hover{border-color:var(--hover-border-c)!important}.block-editor-block-list__block.wp-block-woocommerce-product-button:where(
[style*="--hover-border-s"]
):hover .wp-element-button,.wp-block-button:where([style*="--hover-border-s"]) .wp-element-button:hover,:where([style*="--hover-border-s"]):not(.wp-block-button):hover{border-style:var(--hover-border-s)!important}.block-editor-block-list__block.wp-block-woocommerce-product-button:where(
[style*="--hover-border-left-w"]
):hover .wp-element-button,.wp-block-button:where([style*="--hover-border-left-w"]) .wp-element-button:hover,:where([style*="--hover-border-left-w"]):not(.wp-block-button):hover{border-left-width:var(--hover-border-left-w)!important}.block-editor-block-list__block.wp-block-woocommerce-product-button:where(
[style*="--hover-border-left-c"]
):hover .wp-element-button,.wp-block-button:where([style*="--hover-border-left-c"]) .wp-element-button:hover,:where([style*="--hover-border-left-c"]):not(.wp-block-button):hover{border-left-color:var(--hover-border-left-c)!important}.block-editor-block-list__block.wp-block-woocommerce-product-button:where(
[style*="--hover-border-left-s"]
):hover .wp-element-button,.wp-block-button:where([style*="--hover-border-left-s"]) .wp-element-button:hover,:where([style*="--hover-border-left-s"]):not(.wp-block-button):hover{border-left-style:var(--hover-border-left-s)!important}.block-editor-block-list__block.wp-block-woocommerce-product-button:where(
[style*="--hover-border-right-w"]
):hover .wp-element-button,.wp-block-button:where([style*="--hover-border-right-w"]) .wp-element-button:hover,:where([style*="--hover-border-right-w"]):not(.wp-block-button):hover{border-right-width:var(--hover-border-right-w)!important}.block-editor-block-list__block.wp-block-woocommerce-product-button:where(
[style*="--hover-border-right-c"]
):hover .wp-element-button,.wp-block-button:where([style*="--hover-border-right-c"]) .wp-element-button:hover,:where([style*="--hover-border-right-c"]):not(.wp-block-button):hover{border-right-color:var(--hover-border-right-c)!important}.block-editor-block-list__block.wp-block-woocommerce-product-button:where(
[style*="--hover-border-right-s"]
):hover .wp-element-button,.wp-block-button:where([style*="--hover-border-right-s"]) .wp-element-button:hover,:where([style*="--hover-border-right-s"]):not(.wp-block-button):hover{border-right-style:var(--hover-border-right-s)!important}.block-editor-block-list__block.wp-block-woocommerce-product-button:where(
[style*="--hover-border-bottom-w"]
):hover .wp-element-button,.wp-block-button:where([style*="--hover-border-bottom-w"]) .wp-element-button:hover,:where([style*="--hover-border-bottom-w"]):not(.wp-block-button):hover{border-bottom-width:var(--hover-border-bottom-w)!important}.block-editor-block-list__block.wp-block-woocommerce-product-button:where(
[style*="--hover-border-bottom-c"]
):hover .wp-element-button,.wp-block-button:where([style*="--hover-border-bottom-c"]) .wp-element-button:hover,:where([style*="--hover-border-bottom-c"]):not(.wp-block-button):hover{border-bottom-color:var(--hover-border-bottom-c)!important}.block-editor-block-list__block.wp-block-woocommerce-product-button:where(
[style*="--hover-border-bottom-s"]
):hover .wp-element-button,.wp-block-button:where([style*="--hover-border-bottom-s"]) .wp-element-button:hover,:where([style*="--hover-border-bottom-s"]):not(.wp-block-button):hover{border-bottom-style:var(--hover-border-bottom-s)!important}.block-editor-block-list__block.wp-block-woocommerce-product-button:where(
[style*="--hover-border-top-w"]
):hover .wp-element-button,.wp-block-button:where([style*="--hover-border-top-w"]) .wp-element-button:hover,:where([style*="--hover-border-top-w"]):not(.wp-block-button):hover{border-top-width:var(--hover-border-top-w)!important}.block-editor-block-list__block.wp-block-woocommerce-product-button:where(
[style*="--hover-border-top-c"]
):hover .wp-element-button,.wp-block-button:where([style*="--hover-border-top-c"]) .wp-element-button:hover,:where([style*="--hover-border-top-c"]):not(.wp-block-button):hover{border-top-color:var(--hover-border-top-c)!important}.block-editor-block-list__block.wp-block-woocommerce-product-button:where(
[style*="--hover-border-top-s"]
):hover .wp-element-button,.wp-block-button:where([style*="--hover-border-top-s"]) .wp-element-button:hover,:where([style*="--hover-border-top-s"]):not(.wp-block-button):hover{border-top-style:var(--hover-border-top-s)!important}
	<?php
		return ob_get_clean();
	}

	/**
	 * Build CSS custom property declarations from hover border, background, and text values.
	 */
	private function build_hover_css_vars( $hover_border, $hover_background_color, $hover_text_color ) {
		$styles = array();

		if ( isset( $hover_border ) ) {
			foreach ( array( 'top', 'bottom', 'left', 'right' ) as $aspect ) {
				if ( isset( $hover_border[ $aspect ]['color'] ) ) {
					$styles[] = '--hover-border-' . $aspect . '-c:' . esc_attr( $hover_border[ $aspect ]['color'] );
				}
				if ( isset( $hover_border[ $aspect ]['width'] ) ) {
					$styles[] = '--hover-border-' . $aspect . '-w:' . esc_attr( $hover_border[ $aspect ]['width'] );
				}
				if ( isset( $hover_border[ $aspect ]['style'] ) ) {
					$styles[] = '--hover-border-' . $aspect . '-s:' . esc_attr( $hover_border[ $aspect ]['style'] );
				}
			}
			if ( isset( $hover_border['color'] ) ) {
				$styles[] = '--hover-border-c:' . esc_attr( $hover_border['color'] );
			}
			if ( isset( $hover_border['width'] ) ) {
				$styles[] = '--hover-border-w:' . esc_attr( $hover_border['width'] );
			}
			if ( isset( $hover_border['style'] ) ) {
				$styles[] = '--hover-border-s:' . esc_attr( $hover_border['style'] );
			}
		}

		if ( isset( $hover_background_color ) ) {
			$styles[] = '--hover-background-color:' . esc_attr( $hover_background_color );
		}

		if ( isset( $hover_text_color ) ) {
			$styles[] = '--hover-color:' . esc_attr( $hover_text_color );
		}

		return $styles;
	}

	/**
	 * Apply hover CSS vars to the first tag in HTML and enqueue styles if needed.
	 */
	private function apply_hover_styles_to_html( $html, $extra_styles, $hover_border, $hover_background_color, $hover_text_color ) {
		$tag = new \WP_HTML_Tag_Processor( $html );

		if ( ! $tag->next_tag() ) {
			return $html;
		}

		$escape_styles = array_merge( $extra_styles, $this->build_hover_css_vars( $hover_border, $hover_background_color, $hover_text_color ) );

		if ( empty( $escape_styles ) ) {
			return $html;
		}

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

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

		$tag->set_attribute( 'style', $existing_style . implode( ';', $escape_styles ) . ';' );
		$this->maybe_enqueue_frontend_styles();

		return $tag->get_updated_html();
	}

	public function apply_hover_settings_to_product_button_block( $html, $block ) {
		$hover_background_color = null;
		$hover_text_color       = null;
		$hover_border           = null;

		$tag = new \WP_HTML_Tag_Processor( $html );
		if ( $tag->next_tag() ) {
			if ( $tag->get_attribute( 'data-hover-background-color' ) ) {
				$hover_background_color = $tag->get_attribute( 'data-hover-background-color' );
			}
			if ( $tag->get_attribute( 'data-hover-text-color' ) ) {
				$hover_text_color = $tag->get_attribute( 'data-hover-text-color' );
			}
			if ( $tag->get_attribute( 'data-hover-border' ) ) {
				$hover_border = json_decode( $tag->get_attribute( 'data-hover-border' ), true );
			}
		}

		if ( ! empty( $block['attrs']['style']['hoverBackgroundColor'] ) ) {
			$hover_background_color = $block['attrs']['style']['hoverBackgroundColor'];
		}
		if ( ! empty( $block['attrs']['style']['hoverTextColor'] ) ) {
			$hover_text_color = $block['attrs']['style']['hoverTextColor'];
		}

		return $this->apply_hover_styles_to_html( $html, array(), $hover_border, $hover_background_color, $hover_text_color );
	}

	public function apply_hover_settings_to_blocks( $html, $_, $block ) {
		$hover_background_color = null;
		$hover_text_color       = null;
		$hover_border           = null;
		$extra_styles           = array();

		if ( $this->is_block_support_background_color( (array) $block->block_type ) && ! empty( $block->attributes['style']['hoverBackgroundColor'] ) ) {
			$hover_background_color = $block->attributes['style']['hoverBackgroundColor'];
		}
		if ( $this->is_block_support_text_color( (array) $block->block_type ) && ! empty( $block->attributes['style']['hoverTextColor'] ) ) {
			$hover_text_color = $block->attributes['style']['hoverTextColor'];
		}
		if ( $this->is_block_support_border( (array) $block->block_type ) && ! empty( $block->attributes['style']['hoverBorder'] ) ) {
			$hover_border = $block->attributes['style']['hoverBorder'];
		}
		if ( $this->is_block_need_overflow_hidden( (array) $block->block_type ) && ! empty( $block->attributes['style']['border']['radius'] ) ) {
			$extra_styles[] = 'overflow: hidden';
		}

		return $this->apply_hover_styles_to_html( $html, $extra_styles, $hover_border, $hover_background_color, $hover_text_color );
	}
}

Caller::get_instance();
