<?php
/**
 * Elementor Global Style Integration for Wira Theme
 *
 * @package Wira
 * @since 1.0.0
 */

namespace Wira;

if ( ! class_exists( 'Elementor_Compatibility' ) ) {

	/**
	 * Class Elementor_Compatibility
	 *
	 * Add Global Style Setting to Elementor
	 */
	class Elementor_Compatibility {

		/**
		 * Theme configuration instance
		 *
		 * @var object
		 */
		protected $theme_config;

		/**
		 * Theme slug (prefix for global variables)
		 *
		 * @var string
		 */
		protected $theme_slug;

		/**
		 * Theme options/settings
		 *
		 * @var array
		 */
		protected $settings;

		/**
		 * Default global colors
		 *
		 * @var array
		 */
		protected $color_defaults;

		/**
		 * Responsive typography sets (mapping tabs & breakpoints)
		 *
		 * @var array
		 */
		protected $responsive_sets;

		/**
		 * Default typography values
		 *
		 * @var array
		 */
		protected $typography_defaults;

		/**
		 * Constructor
		 *
		 * Initializes theme config, defaults, and registers hooks.
		 */
		public function __construct() {
			// Get theme configuration instance.
			$this->theme_config = \ThemeConfig\Main_Theme_Config::get_instance();

			// Get theme slug.
			$this->theme_slug = $this->theme_config->get_config( 'slug' );

			// Theme options CSF.
			$this->settings = get_option( $this->theme_slug . '_theme_options' );

			// ============================
			// Default Global Colors
			// ============================
			$this->color_defaults = array(
				'wira_color_primary'         => '#F98400',
				'wira_color_secondary'       => '#1090D2',
				'wira_color_secondary20'     => '#1090D233',
				'wira_color_text'            => '#6e6e6e',
				'wira_color_accent'          => '#00050a',
				'wira_color_placeholder'     => '#A0A0A0',
				'wira_color_tertiary'        => '#004da3',
				'wira_color_secondaryaccent' => '#53b1ff',
				'wira_color_primaryaccent'   => '#ffcfb2',
				'wira_color_primary20'       => '#F9840033',
				'wira_color_border'          => '#dee2e6',
				'wira_color_borderoverlay'   => '#ffffff38',
				'wira_color_whitesmoke'      => '#f4fbfe',
				'wira_color_white'           => '#ffffff',
				'wira_color_whiteoverlay'    => '#ffffffc2',
				'wira_color_white10'         => '#ffffff1a',
				'wira_color_tertiarydark'    => '#001D3D',
				'wira_color_tertiarydark90'  => '#001D3De6',
				'wira_color_tertiarydark60'  => '#001D3D99',
				'wira_color_tertiarydark20'  => '#001D3D33',
				'wira_color_transparent'     => '#ffffff00',
			);

			// ============================
			// Responsive Typography Sets
			// ============================
			$this->responsive_sets = array(
				'wira_body_typography'  => array(
					'tab' => 'tab_body_typography',
					'md'  => 'body_typography_md',
					'sm'  => 'body_typography_sm',
				),
				'wira_body_small_typography' => array(
					'tab' => 'tab_body_small_typography',
					'md'  => 'body_small_typography_md',
					'sm'  => 'body_small_typography_sm',
				),
				'wira_accent_text' => array(
					'tab' => 'tab_accent_text',
					'md'  => 'accent_text_md',
					'sm'  => 'accent_text_sm',
				),
				'wira_subheading_text' => array(
					'tab' => 'tab_subheading_text',
					'md'  => 'subheading_text_md',
					'sm'  => 'subheading_text_sm',
				),
				'wira_xs_subheading_text' => array(
					'tab' => 'tab_xs_subheading_text',
					'md'  => 'xs_subheading_text_md',
					'sm'  => 'xs_subheading_text_sm',
				),
				'wira_notfound_text_big' => array(
					'tab' => 'tab_notfound_text_big',
					'md'  => 'notfound_text_big_md',
					'sm'  => 'notfound_text_big_sm',
				),
				'wira_very_big_title' => array(
					'tab' => 'tab_very_big_title',
					'md'  => 'very_big_title_md',
					'sm'  => 'very_big_title_sm',
				),
				'wira_big_title' => array(
					'tab' => 'tab_big_title',
					'md'  => 'big_title_md',
					'sm'  => 'big_title_sm',
				),
				'wira_medium_title' => array(
					'tab' => 'tab_medium_title',
					'md'  => 'medium_title_md',
					'sm'  => 'medium_title_sm',
				),
				'wira_standard_title' => array(
					'tab' => 'tab_standard_title',
					'md'  => 'standard_title_md',
					'sm'  => 'standard_title_sm',
				),
				'wira_small_title' => array(
					'tab' => 'tab_small_title',
					'md'  => 'small_title_md',
					'sm'  => 'small_title_sm',
				),
				'wira_extra_small_title' => array(
					'tab' => 'tab_extra_small_title',
					'md'  => 'extra_small_title_md',
					'sm'  => 'extra_small_title_sm',
				),
				'wira_block_quote' => array(
					'tab' => 'tab_block_quote',
					'md'  => 'block_quote_md',
					'sm'  => 'block_quote_sm',
				),
				'wira_small_quote' => array(
					'tab' => 'tab_small_quote',
					'md'  => 'small_quote_md',
					'sm'  => 'small_quote_sm',
				),
				'wira_form_label' => array(
					'tab' => 'tab_form_label',
					'md'  => 'form_label_md',
					'sm'  => 'form_label_sm',
				),
			);

			// ============================
			// Default Typography Values
			// ============================
			$this->typography_defaults = array(
				'wira_body_typography'       => array(
					'typography_font_family'    => 'Outfit',
					'typography_font_weight'    => '400',
					'typography_text_transform' => '',
					'typography_font_size'      => array(
						'desktop' => '--theme-font-size-body',
						'tablet'  => '',
						'mobile'  => '',
					),
					'typography_line_height'    => '1.5em',
					'typography_letter_spacing' => '',
				),
				'wira_body_small_typography' => array(
					'typography_font_family'    => 'Outfit',
					'typography_font_weight'    => '400',
					'typography_text_transform' => '',
					'typography_font_size'      => array(
						'desktop' => '--theme-font-size-body-small',
						'tablet'  => '',
						'mobile'  => '',
					),
					'typography_line_height'    => '1.5em',
					'typography_letter_spacing' => '',
				),
				'wira_accent_text'           => array(
					'typography_font_family'    => 'Outfit',
					'typography_font_weight'    => '600',
					'typography_text_transform' => '',
					'typography_font_size'      => array(
						'desktop' => '16px',
						'tablet'  => '',
						'mobile'  => '',
					),
					'typography_line_height'    => '1.3em',
					'typography_letter_spacing' => '-0.3',
				),
				'wira_subheading_text'       => array(
					'typography_font_family'    => 'Outfit',
					'typography_font_weight'    => '500',
					'typography_text_transform' => 'uppercase',
					'typography_font_size'      => array(
						'desktop' => '14px',
						'tablet'  => '',
						'mobile'  => '',
					),
					'typography_line_height'    => '1.3em',
					'typography_letter_spacing' => '1px',
				),
				'wira_xs_subheading_text'    => array(
					'typography_font_family'    => 'Outfit',
					'typography_font_weight'    => '500',
					'typography_text_transform' => 'uppercase',
					'typography_font_size'      => array(
						'desktop' => '10px',
						'tablet'  => '',
						'mobile'  => '',
					),
					'typography_line_height'    => '1.3em',
					'typography_letter_spacing' => '1px',
				),
				'wira_notfound_text_big'     => array(
					'typography_font_family'    => 'Outfit',
					'typography_font_weight'    => '700',
					'typography_text_transform' => 'Capitalize',
					'typography_font_size'      => array(
						'desktop' => '--theme-font-size-xxl',
						'tablet'  => '--theme-font-size-xxl-md',
						'mobile'  => '',
					),
					'typography_line_height'    => '1.3em',
					'typography_letter_spacing' => '-2',
				),
				'wira_very_big_title'        => array(
					'typography_font_family'    => 'Outfit',
					'typography_font_weight'    => '700',
					'typography_text_transform' => 'Capitalize',
					'typography_font_size'      => array(
						'desktop' => '--theme-font-size-xl',
						'tablet'  => '--theme-font-size-xl-md',
						'mobile'  => '--theme-font-size-xl-sm',
					),
					'typography_line_height'    => '1.3em',
					'typography_letter_spacing' => '-1',
				),
				'wira_big_title'             => array(
					'typography_font_family'    => 'Outfit',
					'typography_font_weight'    => '700',
					'typography_text_transform' => 'Capitalize',
					'typography_font_size'      => array(
						'desktop' => '--theme-font-size-large',
						'tablet'  => '--theme-font-size-large-md',
						'mobile'  => '--theme-font-size-large-sm',
					),
					'typography_line_height'    => '1.3em',
					'typography_letter_spacing' => '-0.7',
				),
				'wira_medium_title'          => array(
					'typography_font_family'    => 'Outfit',
					'typography_font_weight'    => '700',
					'typography_text_transform' => 'Capitalize',
					'typography_font_size'      => array(
						'desktop' => '--theme-font-size-medium',
						'tablet'  => '--theme-font-size-medium-md',
						'mobile'  => '--theme-font-size-medium-sm',
					),
					'typography_line_height'    => '1.3em',
					'typography_letter_spacing' => '-0.6',
				),
				'wira_standard_title'        => array(
					'typography_font_family'    => 'Outfit',
					'typography_font_weight'    => '700',
					'typography_text_transform' => 'Capitalize',
					'typography_font_size'      => array(
						'desktop' => '--theme-font-size-standar',
						'tablet'  => '',
						'mobile'  => '--theme-font-size-standar-sm',
					),
					'typography_line_height'    => '1.3em',
					'typography_letter_spacing' => '-0.5',
				),
				'small_title'           => array(
					'typography_font_family'    => 'Outfit',
					'typography_font_weight'    => '700',
					'typography_text_transform' => 'Capitalize',
					'typography_font_size'      => array(
						'desktop' => '--theme-font-size-small',
						'tablet'  => '',
						'mobile'  => '--theme-font-size-small-sm',
					),
					'typography_line_height'    => '1.3em',
					'typography_letter_spacing' => '-0.4',
				),
				'wira_extra_small_title' => array(
					'typography_font_family'    => 'Outfit',
					'typography_font_weight'    => '700',
					'typography_text_transform' => 'Capitalize',
					'typography_font_size'      => array(
						'desktop' => '--theme-font-size-xsmall',
						'tablet'  => '',
						'mobile'  => '',
					),
					'typography_line_height'    => '1.3em',
					'typography_letter_spacing' => '-0.3',
				),
				'wira_block_quote' => array(
					'typography_font_family'    => 'Outfit',
					'typography_font_weight'    => '700',
					'typography_text_transform' => '',
					'typography_font_style'     => 'italic',
					'typography_font_size'      => array(
						'desktop' => '--theme-font-size-small',
						'tablet'  => '--theme-font-size-standar',
						'mobile'  => '--theme-font-size-standar-sm',
					),
					'typography_line_height'    => '1.5em',
					'typography_letter_spacing' => '',
				),
				'wira_small_quote' => array(
					'typography_font_family'    => 'Outfit',
					'typography_font_weight'    => '700',
					'typography_text_transform' => '',
					'typography_font_style'     => 'italic',
					'typography_font_size'      => array(
						'desktop' => '--theme-font-size-body',
						'tablet'  => '--theme-font-size-body',
						'mobile'  => '--theme-font-size-body',
					),
					'typography_line_height'    => '1.5em',
					'typography_letter_spacing' => '',
				),
				'wira_form_label' => array(
					'typography_font_family'    => 'Outfit',
					'typography_font_weight'    => '600',
					'typography_text_transform' => '',
					'typography_font_size'      => array(
						'desktop' => '--theme-font-size-xsmall',
						'tablet'  => '--theme-font-size-xsmall',
						'mobile'  => '--theme-font-size-xsmall',
					),
					'typography_line_height'    => '1.3em',
					'typography_letter_spacing' => '',
				),
			);

			// ============================
			// Override Defaults (Advanced Typography)
			// ============================
			if ( ! empty( $this->settings['enable_advanced_typography'] ) ) {
				foreach ( $this->responsive_sets as $key => $data ) {
					$tab_key     = $data['tab'];
					$setting_key = $key;
					$legacy_key  = preg_replace( '/^wira_/', '', $key );

					if ( ! isset( $this->settings[ $tab_key ][ $setting_key ] ) && isset( $this->settings[ $tab_key ][ $legacy_key ] ) ) {
						$setting_key = $legacy_key;
					}

					if ( isset( $this->settings[ $tab_key ][ $setting_key ] ) ) {
						$item = $this->settings[ $tab_key ][ $setting_key ];

						$this->typography_defaults[ $key ] = array(
							'typography_font_family'    => ! empty( $item['font-family'] ) ? $item['font-family'] : 'Outfit',
							'typography_font_weight'    => ! empty( $item['font-weight'] ) ? $item['font-weight'] : '400',
							'typography_text_transform' => ! empty( $item['text-transform'] ) ? $item['text-transform'] : 'none',
							'typography_font_style'     => ! empty( $item['font-style'] ) ? $item['font-style'] : 'none',
							'typography_font_size'      => array(
								'desktop' => ! empty( $item['font-size'] ) ? $item['font-size'] . 'px' : '',
								'tablet'  => ! empty( $this->settings[ $tab_key ][ $data['md'] ]['font-size'] )
											? $this->settings[ $tab_key ][ $data['md'] ]['font-size'] . 'px' : '',
								'mobile'  => ! empty( $this->settings[ $tab_key ][ $data['sm'] ]['font-size'] )
											? $this->settings[ $tab_key ][ $data['sm'] ]['font-size'] . 'px' : '',
							),
							'typography_line_height'    => ! empty( $item['line-height'] ) ? $item['line-height'] . 'em' : '1.3',
							'typography_letter_spacing' => ! empty( $item['letter-spacing'] ) ? $item['letter-spacing'] . 'px' : '',
						);
					}
				}
			}

			// Register hooks.
			$this->load_hooks();
		}

		/**
		 * Register Elementor and frontend CSS hooks
		 */
		private function load_hooks() {
			if ( defined( 'ELEMENTOR_VERSION' ) ) {
				// Elementor globals REST API integration.
				add_action( 'rest_request_after_callbacks', array( $this, 'add_theme_globals' ), 20, 3 );
				add_filter( 'rest_request_after_callbacks', array( $this, 'display_global_colors_front_end' ), 20, 3 );
			}

			// Enqueue dynamic inline styles.
			add_action( 'wp_enqueue_scripts', array( $this, 'apply_dynamic_styles' ), 20 );
		}

		/**
		 * Inject theme globals (colors + typography) into Elementor REST API.
		 *
		 * Hooked into the Elementor REST API response (`/elementor/v1/globals`).
		 * This ensures theme-defined colors and typography options are available
		 * inside Elementor’s Global Styles panel.
		 *
		 * @since 1.0.0
		 *
		 * @param \WP_REST_Response|array $response Original REST API response.
		 * @param \WP_HTTP_Response       $handler  Response handler.
		 * @param \WP_REST_Request        $request  Current REST API request.
		 * @return \WP_REST_Response|array Modified response with injected globals.
		 */
		public function add_theme_globals( $response, $handler, $request ) {
			$route = $request->get_route();

			// Only modify the Elementor globals endpoint.
			if ( '/elementor/v1/globals' !== $route ) {
				return $response;
			}

			$data = $response->get_data();

			// --- Register theme global colors ---
			foreach ( $this->color_defaults as $color_var => $default_color ) {
				// Get user-defined value or fallback to default.
				$value = get_theme_mod( $color_var, $default_color );

				// Slug & title mapping for Elementor.
				$clean_color_var = preg_replace( '/^wira_/', '', $color_var );
				$slug            = 'theme' . str_replace( 'color_', '', $clean_color_var );
				$title           = ucwords( str_replace( '_', ' ', str_replace( 'color_', '', $clean_color_var ) ) );

				$data['colors'][ $slug ] = array(
					'id'    => $slug,
					'title' => 'Theme ' . $title,
					'value' => $value,
				);
			}

			// --- Register theme global typography ---
			foreach ( $this->typography_defaults as $typo_var => $default_typo ) {
				// Slug & title mapping for Elementor.
				$clean_typo_var = preg_replace( '/^wira_/', '', $typo_var );
				$slug           = str_replace( '_', '', $clean_typo_var );
				$title          = ucwords( str_replace( '_', ' ', $clean_typo_var ) );

				// Get user-defined value or fallback to default.
				$value = get_theme_mod( $typo_var, $default_typo );

				$data['typography'][ $slug ] = array(
					'id'    => $slug,
					'title' => 'Theme ' . $title,
					'value' => $value,
				);
			}

			// Return updated response.
			return rest_ensure_response( $data );
		}

		/**
		 * Display theme global values (colors + typography) in Elementor frontend.
		 *
		 * This method hooks into the Elementor REST API response for globals
		 * (`/elementor/v1/globals/...`) and replaces the returned values with
		 * theme-defined defaults (from Customizer) for colors and typography.
		 *
		 * @since 1.0.0
		 *
		 * @param \WP_REST_Response|array $response Response to replace or augment.
		 * @param \WP_HTTP_Response       $handler  Response handler.
		 * @param \WP_REST_Request        $request  Current REST request instance.
		 * @return \WP_REST_Response|array Modified response containing theme global values.
		 */
		public function display_global_colors_front_end( $response, $handler, $request ) {
			$route = $request->get_route();

			// Only target Elementor globals endpoint.
			if ( 0 !== strpos( $route, '/elementor/v1/globals' ) ) {
				return $response;
			}

			// Extract the last segment of the route (the global ID).
			$rest_id = substr( $route, strrpos( $route, '/' ) + 1 );

			// --- Build slug map for colors ---
			$slug_map = array();
			foreach ( $this->color_defaults as $color_var => $default_color ) {
				$clean_color_var = preg_replace( '/^wira_/', '', $color_var );
				$slug            = 'theme' . str_replace( 'color_', '', $clean_color_var );
				$title           = ucwords( str_replace( '_', ' ', str_replace( 'color_', '', $clean_color_var ) ) );

				$slug_map[ $slug ] = array(
					'var'     => $color_var,
					'title'   => 'Theme ' . $title,
					'default' => $default_color,
				);
			}

			// --- Build slug map for typography ---
			foreach ( $this->typography_defaults as $typo_var => $default_typo ) {
				$clean_typo_var = preg_replace( '/^wira_/', '', $typo_var );
				$slug           = str_replace( '_', '', $clean_typo_var );
				$title          = ucwords( str_replace( '_', ' ', $clean_typo_var ) );

				$slug_map[ $slug ] = array(
					'var'     => $typo_var,
					'title'   => 'Theme ' . $title,
					'default' => $default_typo,
				);
			}

			// Bail early if the requested ID is not in our slug map.
			if ( ! isset( $slug_map[ $rest_id ] ) ) {
				return $response;
			}

			// Get theme_mod value, fallback to default.
			$map   = $slug_map[ $rest_id ];
			$value = get_theme_mod( $map['var'], $map['default'] );

			// Return modified response.
			return rest_ensure_response(
				array(
					'id'    => esc_attr( $rest_id ),
					'title' => $map['title'],
					'value' => $value,
				)
			);
		}

		/**
		 * Apply dynamic CSS variables (colors + typography) to :root
		 */
		public function apply_dynamic_styles() {
			$root_css   = ':root {' . PHP_EOL;
			$tablet_css = '@media (max-width: 1024px) {:root {' . PHP_EOL;
			$mobile_css = '@media (max-width: 767px) {:root {' . PHP_EOL;

			/** =========================
			 *  COLOR VARIABLES
			 * ========================= */
			foreach ( $this->color_defaults as $color_var => $default_color ) {
				$value          = get_theme_mod( $color_var, $default_color );
				$clean_color_var = preg_replace( '/^wira_/', '', $color_var );
				$css_color_var  = str_replace( 'color_', '', $clean_color_var );

				// Sanitize color (hex), fallback ke esc_attr untuk rgba/var().
				$sanitized_value = sanitize_hex_color( $value );
				if ( ! $sanitized_value ) {
					$sanitized_value = esc_attr( $value );
				}

				$root_css .= "  --e-global-color-theme{$css_color_var}: {$sanitized_value};" . PHP_EOL;
			}

			// Helper: wrap custom property values with var() if prefixed with `--`.
			$to_var = function ( $val ) {
				if ( is_string( $val ) && strpos( $val, '--' ) === 0 ) {
					return "var({$val})";
				}
				return $val;
			};

			/** =========================
			 *  TYPOGRAPHY VARIABLES
			 * ========================= */
			foreach ( $this->typography_defaults as $typo_key => $settings ) {
				$clean_typo_key = preg_replace( '/^wira_/', '', $typo_key );
				$slug           = str_replace( '_', '', strtolower( $clean_typo_key ) );

				foreach ( $settings as $prop => $default_value ) {
					// Map property to kebab-case.
					$prop_slug = str_replace(
						array(
							'typography_font_family',
							'typography_font_weight',
							'typography_text_transform',
							'typography_font_style',
							'typography_font_size',
							'typography_line_height',
							'typography_letter_spacing',
						),
						array(
							'font-family',
							'font-weight',
							'text-transform',
							'font-style',
							'font-size',
							'line-height',
							'letter-spacing',
						),
						$prop
					);

					$option_key = "{$typo_key}_{$prop}";
					$value      = get_theme_mod( $option_key, $default_value );

					// Handle responsive font-size via media queries.
					if ( 'font-size' === $prop_slug ) {
						if ( is_array( $value ) ) {
							if ( ! empty( $value['desktop'] ) ) {
								$root_css .= "  --e-global-typography-{$slug}-font-size: " . esc_attr( $to_var( $value['desktop'] ) ) . ';' . PHP_EOL;
							}
							if ( ! empty( $value['tablet'] ) ) {
								$tablet_css .= "  --e-global-typography-{$slug}-font-size: " . esc_attr( $to_var( $value['tablet'] ) ) . ';' . PHP_EOL;
							}
							if ( ! empty( $value['mobile'] ) ) {
								$mobile_css .= "  --e-global-typography-{$slug}-font-size: " . esc_attr( $to_var( $value['mobile'] ) ) . ';' . PHP_EOL;
							}
						} elseif ( '' !== $value ) {
								$root_css .= "  --e-global-typography-{$slug}-font-size: " . esc_attr( $to_var( $value ) ) . ';' . PHP_EOL;
						}
						continue;
					}

					// Line-height → angka float dengan satuan em.
					if ( 'line-height' === $prop_slug ) {
						$line_height = floatval( $value );
						if ( $line_height > 0 ) {
							$root_css .= "  --e-global-typography-{$slug}-line-height: {$line_height}em;" . PHP_EOL;
						}
						continue;
					}

					// Letter-spacing → angka float dengan px.
					if ( 'letter-spacing' === $prop_slug ) {
						$letter_space = floatval( $value );
						$root_css    .= "  --e-global-typography-{$slug}-letter-spacing: {$letter_space}px;" . PHP_EOL;
						continue;
					}

					// Font-family, weight, transform, style → esc_attr.
					if ( '' !== $value ) {
						$root_css .= "  --e-global-typography-{$slug}-{$prop_slug}: " . esc_attr( $to_var( $value ) ) . ';' . PHP_EOL;
					}
				}
			}

			// Close CSS blocks.
			$root_css   .= '}' . PHP_EOL;
			$tablet_css .= '}}' . PHP_EOL;
			$mobile_css .= '}}' . PHP_EOL;

			// Final CSS output.
			$final_css = $root_css . $tablet_css . $mobile_css;

			if ( ! empty( $final_css ) ) {
				wp_enqueue_style( 'wira-inline-style', get_template_directory_uri() . '/assets/css/inline-style.css' );
				wp_add_inline_style( 'wira-inline-style', $final_css );
			}
		}
	}

	// Initialize class only if Elementor is active.
	if ( class_exists( '\Elementor\Plugin' ) ) {
		new Elementor_Compatibility();
	}
}
