<?php

namespace ThimPress\ThimBlocks\Gutenberg;

use ThimPress\ThimBlocks\Thim_Blocks;

class BlockStyleHandle {
	private static $frontend_css = array();

	private static $has_animation = false;

	public static $_min_assets = '.min';

	public static $_version_assets = null;

	public function __construct() {
		if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
			self::$_min_assets     = '';
			self::$_version_assets = uniqid();
		} else {
			self::$_min_assets     = '.min';
			self::$_version_assets = Thim_Blocks::$version;
		}

		add_action( 'enqueue_block_editor_assets', array( $this, 'enqueue_editor_assets' ) );
		add_action( 'enqueue_block_assets', array( $this, 'enqueue_editor_styles' ) );
		add_filter( 'render_block', array( $this, 'apply_styles' ), 10, 2 );
		add_filter( 'render_block', array( $this, 'render_button_with_icon' ), 11, 2 );
		add_action( 'wp_head', array( $this, 'print_styles' ), 999 );

		// Parse content early for classic themes - try multiple hooks
		add_action( 'template_redirect', array( $this, 'parse_current_post_content' ) );
		add_action( 'wp', array( $this, 'parse_current_post_content' ) );

		add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_frontend_assets' ) );
	}

	/**
	 * Enqueue JS for block editor only
	 */
	public function enqueue_editor_assets() {
		$this->enqueue_script(
			'thim-blocks-responsive-control',
			'/js/filters/responsive-control/responsive-control.js'
		);

		$this->enqueue_script(
			'thim-blocks-animation-control',
			'/js/filters/animation-control/animation-control.js'
		);

		$this->enqueue_script(
			'thim-blocks-custom-css-control',
			'/js/filters/css-control/custom-css-control.js'
		);

		$this->enqueue_script(
			'thim-blocks-buttons-control',
			'/js/filters/buttons-control/buttons-control.js'
		);
	}

	public function enqueue_editor_styles() {
		if ( ! is_admin() ) {
			return;
		}

		$this->enqueue_style(
			'thim-blocks-responsive-control',
			'/js/filters/responsive-control/responsive-control.css'
		);

		$this->enqueue_style(
			'thim-blocks-custom-css-control',
			'/js/filters/css-control/custom-css-control.css'
		);

		$this->enqueue_style(
			'thim-blocks-buttons-control',
			'/js/filters/buttons-control/buttons-control.css'
		);

		$this->enqueue_style(
			'thim-blocks-animation-control',
			'/js/filters/animation-control/animation-control.css'
		);
	}

	public function enqueue_frontend_assets() {
		if ( ! self::$has_animation ) {
			return;
		}

		$this->enqueue_style(
			'thim-blocks-animation-control',
			'/js/filters/animation-control/animation-control.css'
		);

		$script_rel  = '/js/filters/animation-control/animation-view-control' . self::$_min_assets . '.js';
		$script_path = Thim_Blocks::$dir_assets_dist . $script_rel;
		$script_url  = Thim_Blocks::$url_assets_dist . $script_rel;

		if ( file_exists( $script_path ) ) {
			wp_enqueue_script(
				'thim-blocks-animation-view',
				$script_url,
				array(),
				filemtime( $script_path ),
				true
			);
		}
	}

	/**
	 * Helper enqueue JS
	 */
	private function enqueue_script( $handle, $script_rel ) {
		$script_path = Thim_Blocks::$dir_assets_dist . $script_rel;
		$script_url  = Thim_Blocks::$url_assets_dist . $script_rel;

		if ( file_exists( $script_path ) ) {
			wp_enqueue_script(
				$handle,
				$script_url,
				array( 'wp-blocks', 'wp-edit-post', 'wp-element', 'wp-components', 'wp-compose', 'wp-hooks', 'wp-i18n', 'wp-block-editor' ),
				filemtime( $script_path ),
				true
			);
			wp_set_script_translations( $handle, 'thim-blocks', Thim_Blocks::$plugin_dir . 'languages' );
		}
	}

	/**
	 * Helper enqueue CSS
	 */
	private function enqueue_style( $handle, $style_rel ) {
		$style_path = Thim_Blocks::$dir_assets_dist . $style_rel;
		$style_url  = Thim_Blocks::$url_assets_dist . $style_rel;

		if ( file_exists( $style_path ) ) {
			wp_enqueue_style( $handle, $style_url, array(), filemtime( $style_path ) );
		}
	}

	public function apply_styles( $block_content, $block ) {
		if ( ! isset( $block['blockName'] ) ) {
			return $block_content;
		}

		// Create same block key as in extract_styles_from_blocks
		$attrs_for_key = $block['attrs'] ?? array();
		// Remove dynamic attributes that might change between parse and render
		unset( $attrs_for_key['className'] );

		$block_key = $block['blockName'] . '_' . md5( json_encode( $attrs_for_key ) );

		// Use mapped client_id if available, otherwise generate new one
		$client_id = isset( self::$block_id_mapping[ $block_key ] )
			? self::$block_id_mapping[ $block_key ]
			: ( ! empty( $block['attrs']['id'] ) ? $block['attrs']['id'] : uniqid() );

		// Responsive
		if ( $this->has_responsive_styles( $block['attrs'] ?? array() ) ) {
			$block_content = $this->apply_responsive_css( $block_content, $block, $client_id );
		}

		// Custom CSS
		if ( ! empty( $block['attrs']['customCss'] ) ) {
			$block_content = $this->apply_custom_css( $block_content, $block, $client_id );
		}

		// Animation
		if ( ! empty( $block['attrs']['animationType'] ) ) {
			$block_content = $this->apply_animation( $block_content, $block, $client_id );
		}

		return $block_content;
	}

	public function render_button_with_icon( $block_content, $block ) {
		if ( $block['blockName'] !== 'core/button' ) {
			return $block_content;
		}

		$attrs         = $block['attrs'] ?? array();
		$icon_class    = $attrs['iconClass'] ?? '';
		$icon_svg      = $attrs['iconSVG'] ?? '';
		$icon_position = $attrs['iconPosition'] ?? 'none';

		if ( $icon_position === 'none' || ( ! $icon_class && ! $icon_svg ) ) {
			return $block_content;
		}

		$icon_html = $icon_class
			? sprintf(
				'<i class="%s" style="margin:%s"></i>',
				esc_attr( $icon_class ),
				$icon_position === 'left' ? '0 8px 0 0' : '0 0 0 8px'
			)
			: sprintf(
				'<span style="margin:%s">%s</span>',
				$icon_position === 'left' ? '0 8px 0 0' : '0 0 0 8px',
				$icon_svg
			);

		if ( $icon_position === 'left' ) {
			$block_content = preg_replace(
				'/(<a[^>]*class="[^"]*wp-block-button__link[^"]*"[^>]*>)/',
				'$1' . $icon_html,
				$block_content,
				1
			);
		} else {
			$block_content = preg_replace(
				'/(<\/a>)/',
				$icon_html . '$1',
				$block_content,
				1
			);
		}

		return $block_content;
	}

	private function has_responsive_styles( $attrs ) {
		if ( ! empty( $attrs['hideDesktop'] ) || ! empty( $attrs['hideTablet'] ) || ! empty( $attrs['hideMobile'] ) ) {
			return true;
		}

		if ( empty( $attrs['responsiveSettings'] ) || ! is_array( $attrs['responsiveSettings'] ) ) {
			return false;
		}

		foreach ( array( 'Desktop', 'Tablet', 'Mobile' ) as $device ) {
			if ( isset( $attrs['responsiveSettings'][ $device ] ) && is_array( $attrs['responsiveSettings'][ $device ] ) ) {
				$values = $attrs['responsiveSettings'][ $device ];
				if ( ! empty( $values['fontSize'] ) ) {
					return true;
				}
				if ( ! empty( $values['padding'] ) && is_array( $values['padding'] ) ) {
					$filtered = array_filter(
						$values['padding'],
						function ( $v ) {
							return $v !== '' && $v !== null && $v !== false;
						}
					);
					if ( count( $filtered ) > 0 ) {
						return true;
					}
				}
				if ( ! empty( $values['margin'] ) && is_array( $values['margin'] ) ) {
					$filtered = array_filter(
						$values['margin'],
						function ( $v ) {
							return $v !== '' && $v !== null && $v !== false;
						}
					);
					if ( count( $filtered ) > 0 ) {
						return true;
					}
				}
			}
		}

		return false;
	}

	private function apply_responsive_css( $block_content, $block, $client_id ) {
		$unique_class = 'thim-responsive-' . $client_id;

		if ( strpos( $block_content, $unique_class ) === false ) {
			if ( preg_match( '/<([a-z0-9]+)([^>]*)class="([^"]*)"/i', $block_content ) ) {
				$block_content = preg_replace(
					'/class="([^"]*)"/i',
					'class="$1 ' . esc_attr( $unique_class ) . '"',
					$block_content,
					1
				);
			} else {
				$block_content = preg_replace(
					'/<([a-z0-9]+)([^>]*)>/i',
					'<$1$2 class="' . esc_attr( $unique_class ) . '">',
					$block_content,
					1
				);
			}
		}

		// CSS is already generated in extract_styles_from_blocks for classic themes
		// Only generate here if not already done
		if ( ! self::$content_parsed ) {
			$css_lines = array();
			foreach ( array( 'Desktop', 'Tablet', 'Mobile' ) as $device ) {
				$values   = $block['attrs']['responsiveSettings'][ $device ] ?? array();
				$padding  = $values['padding'] ?? array();
				$margin   = $values['margin'] ?? array();
				$fontSize = $values['fontSize'] ?? '';

				$padding  = array_map( array( $this, 'format_responsive_value' ), $padding );
				$margin   = array_map( array( $this, 'format_responsive_value' ), $margin );
				$fontSize = $this->format_responsive_value( $fontSize );

				$padding = array(
					$padding['top'] ?? '',
					$padding['right'] ?? '',
					$padding['bottom'] ?? '',
					$padding['left'] ?? '',
				);

				$margin = array(
					$margin['top'] ?? '',
					$margin['right'] ?? '',
					$margin['bottom'] ?? '',
					$margin['left'] ?? '',
				);

				$css_content = '';

				if ( implode( '', $padding ) !== '' ) {
					$css_content .= ' padding:' . implode( ' ', $padding ) . ';';
				}

				if ( implode( '', $margin ) !== '' ) {
					$css_content .= ' margin:' . implode( ' ', $margin ) . ';';
				}

				if ( ! empty( $fontSize ) ) {
					$css_content .= ' font-size:' . $fontSize . ';';
				}

				if ( empty( $css_content ) ) {
					continue;
				}

				$css_line = ".$unique_class {" . $css_content . '}';

				if ( $device === 'Desktop' ) {
					$css_lines[] = $css_line;
				} elseif ( $device === 'Tablet' ) {
					$css_lines[] = "@media(max-width:991px){ $css_line }";
				} elseif ( $device === 'Mobile' ) {
					$css_lines[] = "@media(max-width:767px){ $css_line }";
				}
			}

			if ( ! empty( $block['attrs']['hideDesktop'] ) ) {
				$css_lines[] = "@media (min-width: 992px) { .$unique_class { display: none !important; } }";
			}
			if ( ! empty( $block['attrs']['hideTablet'] ) ) {
				$css_lines[] = "@media (min-width: 768px) and (max-width: 991px) { .$unique_class { display: none !important; } }";
			}
			if ( ! empty( $block['attrs']['hideMobile'] ) ) {
				$css_lines[] = "@media (max-width: 767px) { .$unique_class { display: none !important; } }";
			}

			if ( $css_lines ) {
				self::$frontend_css[] = implode( "\n", $css_lines );
			}
		}

		return $block_content;
	}

	private function apply_custom_css( $block_content, $block, $client_id ) {
		// Use uniqueClass from attributes if available (for consistency with editor)
		$unique_class = ! empty( $block['attrs']['uniqueClass'] ) ? $block['attrs']['uniqueClass'] : 'thim-css-' . $client_id;

		if ( strpos( $block_content, $unique_class ) === false ) {
			if ( preg_match( '/<([a-z0-9]+)([^>]*)class="([^"]*)"/i', $block_content ) ) {
				$block_content = preg_replace(
					'/class="([^"]*)"/i',
					'class="$1 ' . esc_attr( $unique_class ) . '"',
					$block_content,
					1
				);
			} else {
				$block_content = preg_replace(
					'/<([a-z0-9]+)([^>]*)>/i',
					'<$1$2 class="' . esc_attr( $unique_class ) . '">',
					$block_content,
					1
				);
			}
		}

		// CSS is already generated in extract_styles_from_blocks for classic themes
		// Only generate here if not already done
		if ( ! self::$content_parsed ) {
			$css                  = str_replace(
				'selector',
				'.' . $unique_class,
				$block['attrs']['customCss']
			);
			self::$frontend_css[] = $css;
		}

		// Debug: uncomment to see what CSS is being applied
		// error_log( 'Apply Custom CSS - Block: ' . $block['blockName'] . ', UniqueClass: ' . $unique_class . ', CSS: ' . $css );

		return $block_content;
	}

	private function apply_animation( $block_content, $block, $client_id ) {
		if ( ! empty( $block['attrs']['animationType'] ) && $block['attrs']['animationType'] !== 'none' ) {
			self::$has_animation = true;

			$animation_type = sanitize_html_class( $block['attrs']['animationType'] );

			if ( strpos( $block_content, 'thim-animated' ) === false ) {
				if ( preg_match( '/<([a-z0-9]+)([^>]*)class="([^"]*)"/i', $block_content ) ) {
					$block_content = preg_replace(
						'/class="([^"]*)"/i',
						'class="$1 thim-animated ' . esc_attr( $animation_type ) . '"',
						$block_content,
						1
					);
				} else {
					$block_content = preg_replace(
						'/<([a-z0-9]+)([^>]*)>/i',
						'<$1$2 class="thim-animated ' . esc_attr( $animation_type ) . '">',
						$block_content,
						1
					);
				}
			}
		}

		return $block_content;
	}

	public function print_styles() {
		if ( empty( self::$frontend_css ) ) {
			return;
		}

		$css = array_unique( self::$frontend_css );
		echo "<style id='thim-blocks-styles'>" . implode( "\n", $css ) . '</style>';
	}

	private static $content_parsed = false;

	public function parse_current_post_content() {
		// Avoid parsing multiple times
		if ( self::$content_parsed ) {
			return;
		}

		global $post;

		if ( ! is_singular() || ! $post || ! has_blocks( $post->post_content ) ) {
			return;
		}

		$blocks = parse_blocks( $post->post_content );
		$this->extract_styles_from_blocks( $blocks );
		self::$content_parsed = true;
	}

	private static $block_id_mapping = array();

	private function extract_styles_from_blocks( $blocks ) {
		foreach ( $blocks as $block ) {
			if ( ! empty( $block['blockName'] ) ) {
				// Create a stable key based on block attributes that should be consistent
				$attrs_for_key = $block['attrs'] ?? array();
				// Remove dynamic attributes that might change between parse and render
				unset( $attrs_for_key['className'] );

				$block_key = $block['blockName'] . '_' . md5( json_encode( $attrs_for_key ) );

				// Use consistent client_id - store mapping for later use
				if ( ! isset( self::$block_id_mapping[ $block_key ] ) ) {
					$client_id                            = ! empty( $block['attrs']['id'] ) ? $block['attrs']['id'] : uniqid();
					self::$block_id_mapping[ $block_key ] = $client_id;
				} else {
					$client_id = self::$block_id_mapping[ $block_key ];
				}

				// Custom CSS
				if ( ! empty( $block['attrs']['customCss'] ) ) {
					$unique_class         = ! empty( $block['attrs']['uniqueClass'] ) ? $block['attrs']['uniqueClass'] : 'thim-css-' . $client_id;
					$css                  = str_replace( 'selector', '.' . $unique_class, $block['attrs']['customCss'] );
					self::$frontend_css[] = $css;
				}

				// Animation - just set the flag
				if ( ! empty( $block['attrs']['animationType'] ) && $block['attrs']['animationType'] !== 'none' ) {
					self::$has_animation = true;
				}

				// Responsive CSS
				if ( $this->has_responsive_styles( $block['attrs'] ?? array() ) ) {
					$unique_class = 'thim-responsive-' . $client_id;
					$css_lines    = array();

					foreach ( array( 'Desktop', 'Tablet', 'Mobile' ) as $device ) {
						$values   = $block['attrs']['responsiveSettings'][ $device ] ?? array();
						$padding  = $values['padding'] ?? array();
						$margin   = $values['margin'] ?? array();
						$fontSize = $values['fontSize'] ?? '';

						$padding  = array_map( array( $this, 'format_responsive_value' ), $padding );
						$margin   = array_map( array( $this, 'format_responsive_value' ), $margin );
						$fontSize = $this->format_responsive_value( $fontSize );

						$padding = array(
							$padding['top'] ?? '',
							$padding['right'] ?? '',
							$padding['bottom'] ?? '',
							$padding['left'] ?? '',
						);

						$margin = array(
							$margin['top'] ?? '',
							$margin['right'] ?? '',
							$margin['bottom'] ?? '',
							$margin['left'] ?? '',
						);

						$css_content = '';

						if ( implode( '', $padding ) !== '' ) {
							$css_content .= ' padding:' . implode( ' ', $padding ) . ';';
						}

						if ( implode( '', $margin ) !== '' ) {
							$css_content .= ' margin:' . implode( ' ', $margin ) . ';';
						}

						if ( ! empty( $fontSize ) ) {
							$css_content .= ' font-size:' . $fontSize . ';';
						}

						if ( empty( $css_content ) ) {
							continue;
						}

						$css_line = ".$unique_class {" . $css_content . '}';

						if ( $device === 'Desktop' ) {
							$css_lines[] = $css_line;
						} elseif ( $device === 'Tablet' ) {
							$css_lines[] = "@media(max-width:991px){ $css_line }";
						} elseif ( $device === 'Mobile' ) {
							$css_lines[] = "@media(max-width:767px){ $css_line }";
						}
					}

					if ( ! empty( $block['attrs']['hideDesktop'] ) ) {
						$css_lines[] = "@media (min-width: 992px) { .$unique_class { display: none !important; } }";
					}
					if ( ! empty( $block['attrs']['hideTablet'] ) ) {
						$css_lines[] = "@media (min-width: 768px) and (max-width: 991px) { .$unique_class { display: none !important; } }";
					}
					if ( ! empty( $block['attrs']['hideMobile'] ) ) {
						$css_lines[] = "@media (max-width: 767px) { .$unique_class { display: none !important; } }";
					}

					if ( $css_lines ) {
						self::$frontend_css[] = implode( "\n", $css_lines );
					}
				}
			}

			// Process inner blocks recursively
			if ( ! empty( $block['innerBlocks'] ) ) {
				$this->extract_styles_from_blocks( $block['innerBlocks'] );
			}
		}
	}

	private function format_responsive_value( $val ) {
		if ( is_array( $val ) && isset( $val['value'] ) ) {
			return $val['value'] . ( $val['unit'] ?? 'px' );
		}

		if ( is_numeric( $val ) ) {
			return $val . 'px';
		}

		if ( is_string( $val ) && $val !== '' ) {
			if ( preg_match( '/^(xx|x|small|medium|large|xl|xx-large|x-large)$/i', $val ) ) {
				return "var(--wp--preset--font-size--{$val})";
			}
			return $val;
		}

		return '';
	}
}
