<?php
/**
 * Add an element to fusion-builder.
 *
 * @package fusion-builder
 * @since 3.8
 */

if ( fusion_is_element_enabled( 'fusion_tb_woo_filters_active' ) ) {

	if ( ! class_exists( 'FusionTB_WooFiltersActive' ) ) {
		/**
		 * Shortcode class.
		 *
		 * @since 3.8
		 */
		class FusionTB_WooFiltersActive extends AWB_Woo_Filters {

			/**
			 * Constructor.
			 *
			 * @access public
			 * @since 3.8
			 */
			public function __construct() {
				$this->shortcode_handle = 'fusion_tb_woo_filters_active';
				parent::__construct();

				add_filter( 'fusion_tb_woo_filters_active_widget_content', [ $this, 'render_clear_all' ], 10, 3 );
				add_filter( 'fusion_tb_woo_filters_active_widget_content', [ $this, 'render_custom_active_filters' ], 5, 3 );
			}

			/**
			 * Gets the default values.
			 *
			 * @static
			 * @access public
			 * @since 3.8
			 * @return array
			 */
			public static function get_element_defaults() {
				$defaults        = parent::get_element_defaults();
				$fusion_settings = awb_get_fusion_settings();

				$args = wp_parse_args(
					[
						'item_color'                    => $fusion_settings->get( 'button_accent_color' ),
						'item_bgcolor'                  => $fusion_settings->get( 'button_gradient_top_color' ),
						'item_hover_color'              => $fusion_settings->get( 'button_accent_hover_color' ),
						'item_hover_bgcolor'            => $fusion_settings->get( 'button_gradient_top_color_hover' ),
						'fusion_font_family_item_font'  => '',
						'fusion_font_variant_item_font' => '',
						'item_font_size'                => '',
						'item_line_height'              => '',
						'item_letter_spacing'           => '',
						'item_text_transform'           => '',
						'item_padding_top'              => '',
						'item_padding_right'            => '',
						'item_padding_bottom'           => '',
						'item_padding_left'             => '',
						'show_clear'                    => 'no',
					],
					$defaults
				);

				return $args;
			}

			/**
			 * Get element subparams.
			 *
			 * @access public
			 * @since 3.8
			 * @return array
			 */
			public function get_element_subparams() {
				$options = parent::get_element_subparams();

				$params = [
					'fusion_font_family_item_font'  => 'item_fonts',
					'fusion_font_variant_item_font' => 'item_fonts',
					'item_font_size'                => 'item_fonts',
					'item_line_height'              => 'item_fonts',
					'item_letter_spacing'           => 'item_fonts',
					'item_text_transform'           => 'item_fonts',
				];

				return array_merge( $options, $params );
			}

			/**
			 * Validate the arguments into correct format.
			 *
			 * @access public
			 * @since 3.8
			 * @return void
			 */
			public function validate_args() {
				parent::validate_args();

				$units = [
					'item_font_size',
					'item_letter_spacing',
					'item_padding_top',
					'item_padding_right',
					'item_padding_bottom',
					'item_padding_left',
				];

				foreach ( $units as $unit ) {
					if ( ! $this->is_default( $unit ) ) {
						$this->args[ $unit ] = fusion_library()->sanitize->get_value_with_unit( $this->args[ $unit ] );
					}
				}
			}

			/**
			 * Fetch general options.
			 *
			 * @access public
			 * @since 3.8
			 * @return array
			 */
			public function fetch_general_options() {
				$options = parent::fetch_general_options();
				$return  = [];
				$params  = [
					[
						'type'        => 'radio_button_set',
						'heading'     => esc_attr__( 'Show Clear All', 'fusion-builder' ),
						'description' => esc_attr__( 'Choose to show or hide the clear all filters link.', 'fusion-builder' ),
						'param_name'  => 'show_clear',
						'default'     => 'no',
						'group'       => esc_attr__( 'General', 'fusion-builder' ),
						'value'       => [
							'yes' => esc_attr__( 'Yes', 'fusion-builder' ),
							'no'  => esc_attr__( 'No', 'fusion-builder' ),
						],
					]
				];

				foreach ( $options as $opt ) {
					if ( 'title' === $opt['param_name'] ) {
						$opt['value'] = esc_html__( 'Active filters', 'fusion-builder' );
					}
					if ( in_array( $opt['param_name'], [ 'title', 'title_size' ], true ) ) {
						$opt['callback']['action'] = "get_{$this->shortcode_handle}";
					}
					$return[] = $opt;

					// Insert element params after title param.
					if ( 'title_size' === $opt['param_name'] ) {
						foreach ( $params as $param ) {
							$return[] = $param;
						}
					}
				}

				return $return;
			}

			/**
			 * Fetch design options.
			 *
			 * @access public
			 * @since 3.8
			 * @return array
			 */
			public function fetch_design_options() {
				$options         = parent::fetch_design_options();
				$fusion_settings = awb_get_fusion_settings();

				$params = [
					[
						'type'             => 'typography',
						'heading'          => esc_attr__( 'Active Filter Typography', 'fusion-builder' ),
						'description'      => esc_html__( 'Controls the typography of the active filter. Leave empty for the global font family.', 'fusion-builder' ),
						'param_name'       => 'item_fonts',
						'choices'          => [
							'font-family'    => 'item_font',
							'font-size'      => 'item_font_size',
							'text-transform' => 'item_text_transform',
							'line-height'    => 'item_line_height',
							'letter-spacing' => 'item_letter_spacing',
						],
						'default'          => [
							'font-family'    => '',
							'variant'        => '400',
							'font-size'      => '',
							'text-transform' => '',
							'line-height'    => '',
							'letter-spacing' => '',
						],
						'remove_from_atts' => true,
						'global'           => true,
						'group'            => esc_attr__( 'Design', 'fusion-builder' ),
					],
					[
						'type'             => 'dimension',
						'remove_from_atts' => true,
						'heading'          => esc_attr__( 'Active Filter Padding', 'fusion-builder' ),
						'description'      => esc_attr__( 'In pixels or percentage, ex: 10px or 10%.', 'fusion-builder' ),
						'param_name'       => 'item_padding',
						'value'            => [
							'item_padding_top'    => '',
							'item_padding_right'  => '',
							'item_padding_bottom' => '',
							'item_padding_left'   => '',
						],
						'group'            => esc_attr__( 'Design', 'fusion-builder' ),
					],
					[
						'type'          => 'colorpickeralpha',
						'heading'       => esc_attr__( 'Active Filter Background Color', 'fusion-builder' ),
						'description'   => esc_attr__( 'Controls the item background color of active filter.', 'fusion-builder' ),
						'param_name'    => 'item_bgcolor',
						'value'         => '',
						'default'       => $fusion_settings->get( 'button_gradient_top_color' ),
						'group'         => esc_html__( 'Design', 'fusion-builder' ),
						'states'        => [
							'hover' => [
								'label'      => __( 'Hover / Active', 'fusion-builder' ),
								'param_name' => 'item_hover_bgcolor',
								'default'    => $fusion_settings->get( 'button_gradient_top_color_hover' ),
								'preview'    => [
									'selector' => 'li.chosen a',
									'type'     => 'class',
									'toggle'   => 'hover',
								],
							],
						],
						'connect-state' => [ 'item_color' ],
					],
					[
						'type'          => 'colorpickeralpha',
						'heading'       => esc_attr__( 'Active Filter Color', 'fusion-builder' ),
						'description'   => esc_attr__( 'Controls the item color of active filter.', 'fusion-builder' ),
						'param_name'    => 'item_color',
						'value'         => '',
						'default'       => $fusion_settings->get( 'button_accent_color' ),
						'group'         => esc_html__( 'Design', 'fusion-builder' ),
						'states'        => [
							'hover' => [
								'label'      => __( 'Hover / Active', 'fusion-builder' ),
								'param_name' => 'item_hover_color',
								'default'    => $fusion_settings->get( 'button_accent_hover_color' ),
								'preview'    => [
									'selector' => 'li.chosen a',
									'type'     => 'class',
									'toggle'   => 'hover',
								],
							],
						],
						'connect-state' => [ 'item_bgcolor' ],
					],
				];

				foreach ( $params as $param ) {
					$options[] = $param;
				}

				return $options;
			}

			/**
			 * Get the style variables.
			 *
			 * @access protected
			 * @since 3.8
			 * @param array $custom_vars The custom CSS vars array.
			 * @return string
			 */
			protected function get_style_variables( $custom_vars = [] ) {
				$custom_vars = parent::get_style_variables( $custom_vars );

				// Item Typo.
				$custom_vars = $this->get_typo_variables(
					[
						'item_font'           => 'font',
						'item_font_size'      => 'size',
						'item_line_height'    => 'line_height',
						'item_letter_spacing' => 'letter_spacing',
						'item_text_transform' => 'text_transform',
					],
					$custom_vars
				);

				// Item Padding.
				$custom_vars = $this->get_dimension_variables( 'item_padding', $custom_vars );

				$css_vars_options = [
					'item_color'         => [ 'callback' => [ 'Fusion_Sanitize', 'color' ] ],
					'item_bgcolor'       => [ 'callback' => [ 'Fusion_Sanitize', 'color' ] ],
					'item_hover_color'   => [ 'callback' => [ 'Fusion_Sanitize', 'color' ] ],
					'item_hover_bgcolor' => [ 'callback' => [ 'Fusion_Sanitize', 'color' ] ],
				];

				$styles = $this->get_css_vars_for_options( $css_vars_options ) . $this->get_custom_css_vars( $custom_vars );

				return $styles;
			}

			/**
			 * Emulate filter element for LE.
			 *
			 * @access public
			 * @since 3.8
			 * @return void
			 */
			public function emulate_filter_element() {
				$_GET['min_price'] = 1;
				$_GET['max_price'] = 100;
			}

			/**
			 * Restore filter element for LE.
			 *
			 * @access public
			 * @since 3.8
			 * @return void
			 */
			public function restore_filter_element() {
				unset( $_GET['min_price'] ); // phpcs:ignore WordPress.Security.NonceVerification
				unset( $_GET['max_price'] ); // phpcs:ignore WordPress.Security.NonceVerification
			}

			/**
			 * Inject active filter items for product_cat and product_brand query params.
			 *
			 * When `filter_directly` mode is active, WooCommerce's own active-filter
			 * widget doesn't know about product_cat set via query param. Also, it doesn't
			 * natively handle the custom product_brand taxonomy unless explicitly requested.
			 * This method appends the matching <li>s so the user can remove them.
			 *
			 * @access public
			 * @since 3.15.2
			 * @param string $content          The widget content.
			 * @param array  $args             The element args.
			 * @param string $shortcode_handle The shortcode handle.
			 * @return string
			 */
			public function render_custom_active_filters( $content, $args, $shortcode_handle ) {

				$custom_items     = '';
				$ajax_categories  = fusion_library()->get_option( 'woocommerce_ajax_categories' );
				
				// Process category filter — only in filter_directly mode, where product_cat is a query param.
				// phpcs:ignore WordPress.Security.NonceVerification.Recommended
				if ( 'filter_directly' === $ajax_categories ) {
					$cat_slug = isset( $_GET['product_cat'] ) ? sanitize_text_field( wp_unslash( $_GET['product_cat'] ) ) : '';
					if ( $cat_slug ) {
						$term = get_term_by( 'slug', $cat_slug, 'product_cat' );
						if ( $term && ! is_wp_error( $term ) ) {
							// Build the removal URL for category.
							$params = isset( $_SERVER['QUERY_STRING'] ) ? $_SERVER['QUERY_STRING'] : ''; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput
							parse_str( $params, $query_args );
							$query_args['product_cat'] = ''; // explicit empty.
							unset( $query_args['paged'], $query_args['page'] );
							$removal_url = esc_url( add_query_arg( $query_args, strtok( home_url( $_SERVER['REQUEST_URI'] ), '?' ) ) ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput

							$custom_items .= '<li class="chosen awb-active-cat-filter">' .
								'<a href="' . $removal_url . '">' . esc_html( $term->name ) . '</a>' .
							'</li>';
						}
					}
				}
				
				// Process brand filters — active in any AJAX mode.
				// phpcs:ignore WordPress.Security.NonceVerification.Recommended
				$brand_slugs = isset( $_GET['filter_product_brand'] ) ? sanitize_text_field( wp_unslash( $_GET['filter_product_brand'] ) ) : '';
				if ( $brand_slugs ) {
					$brand_slugs_array = explode( ',', $brand_slugs );
					foreach ( $brand_slugs_array as $brand_selection ) {
						$brand_selection = trim( $brand_selection );
						$term            = false;

						// Try to get term by slug first (standard for Woo attribute filters).
						if ( ! is_numeric( $brand_selection ) ) {
							$term = get_term_by( 'slug', $brand_selection, 'product_brand' );
						}

						// Fallback to ID if not found or if selection was numeric.
						if ( ! $term || is_wp_error( $term ) ) {
							$term = get_term_by( 'id', absint( $brand_selection ), 'product_brand' );
						}

						if ( $term && ! is_wp_error( $term ) ) {
							// Build the removal URL for this specific brand.
							$params = isset( $_SERVER['QUERY_STRING'] ) ? $_SERVER['QUERY_STRING'] : ''; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput
							parse_str( $params, $query_args );
							
							// Remove this specific selection from the string.
							if ( isset( $query_args['filter_product_brand'] ) ) {
								$current_brands = explode( ',', $query_args['filter_product_brand'] );
								$current_brands = array_filter( $current_brands, function( $b ) use ( $brand_selection ) {
									return trim( $b ) !== $brand_selection;
								} );
								
								$query_args['filter_product_brand'] = empty( $current_brands ) ? '' : implode( ',', $current_brands );
							}
							
							unset( $query_args['paged'], $query_args['page'] );
							$removal_url = esc_url( add_query_arg( $query_args, strtok( home_url( $_SERVER['REQUEST_URI'] ), '?' ) ) ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput

							$custom_items .= '<li class="chosen awb-active-brand-filter">' .
								'<a href="' . $removal_url . '">' . esc_html( $term->name ) . '</a>' .
							'</li>';
						}
					}
				}

				if ( ! $custom_items ) {
					return $content;
				}

				// Inject before the closing </ul> if there is one, otherwise reconstruct the widget wrapper.
				if ( false !== strpos( $content, '</ul>' ) ) {
					$content = str_replace( '</ul>', $custom_items . '</ul>', $content );
				} else {
					$widget_wrapper = '<div class="widget woocommerce widget_layered_nav_filters">';
					
					// Reconstruct the missing title formatting based on element args.
					$show_title = isset( $args['show_title'] ) ? $args['show_title'] : 'yes';
					$ul_style   = '';
					
					if ( 'yes' === $show_title ) {
						$title_tag = isset( $args['title_size'] ) && 'div' === $args['title_size'] ? 'div' : ( isset( $args['title_size'] ) ? 'h' . $args['title_size'] : 'h4' );
						$title     = isset( $args['title'] ) ? $args['title'] : esc_html__( 'Active filters', 'fusion-builder' );
						$toggle    = '';
						
						if ( isset( $args['is_collapsible'] ) && 'yes' === $args['is_collapsible'] ) {
							if ( isset( $args['collapsed_on_load'] ) && 'yes' === $args['collapsed_on_load'] ) {
								$toggle   = '<button type="button" class="awb-toggle-filter awb-rotate" aria-expanded="false" aria-label="' . esc_attr__( 'Toggle Filter', 'fusion-builder' ) . '"><i class="awb-icon-angle-up"></i></button>';
								$ul_style = ' style="display:none;"';
							} else {
								$toggle   = '<button type="button" class="awb-toggle-filter" aria-expanded="true" aria-label="' . esc_attr__( 'Toggle Filter', 'fusion-builder' ) . '"><i class="awb-icon-angle-up"></i></button>';
							}
						}
						
						$widget_wrapper .= '<div class="heading"><' . $title_tag . ' class="widget-title">' . $title . '</' . $title_tag . '>' . $toggle . '</div>';
					}

					$widget_wrapper .= '<ul class="woocommerce-widget-layered-nav-list"' . $ul_style . '>' . $custom_items . '</ul>';
					$widget_wrapper .= '</div>';
					
					$content .= $widget_wrapper;
				}

				return $content;
			}

			/**
			 * Render clear all link.
			 *
			 * @access public
			 * @since 3.15.0
			 * @param string $content         The content.
			 * @param array  $args            The arguments.
			 * @param string $shortcode_handle The shortcode handle.
			 * @return string
			 */
			public function render_clear_all( $content, $args, $shortcode_handle ) {
				if ( 'yes' === $args['show_clear'] && ! empty( $content ) ) {
					$clear_all_link = '<li class="chosen awb-clear-all-filters"><a href="#">' . esc_html__( 'Clear All', 'fusion-builder' ) . '</a></li>';
					$content        = str_replace( '</ul>', $clear_all_link . '</ul>', $content );
				}

				return $content;
			}
		}
	}

	/**
	 * Instantiates the class.
	 *
	 * @return object
	 */
	function awb_woo_filter_active() { // phpcs:ignore WordPress.NamingConventions
		return FusionTB_WooFiltersActive::get_instance();
	}

	// Instantiate.
	awb_woo_filter_active();
}

/**
 * Map shortcode to Avada Builder.
 */
function fusion_element_woo_filters_active() {
	if ( class_exists( 'WooCommerce' ) ) {
		$params    = [];
		$subparams = [];

		// We only need options if element is active.
		if ( function_exists( 'awb_woo_filter_active' ) ) {
			$params    = awb_woo_filter_active()->get_element_params();
			$subparams = awb_woo_filter_active()->get_element_subparams();
		}

		fusion_builder_map(
			fusion_builder_frontend_data(
				'FusionTB_WooFiltersActive',
				[
					'name'         => esc_attr__( 'Woo Active Filters', 'fusion-builder' ),
					'shortcode'    => 'fusion_tb_woo_filters_active',
					'help_url'     => 'https://avada.com/documentation/woo-active-filters-element/',
					'icon'         => 'fusiona-active-filters',
					'component'    => true,
					'templates'    => [ 'content', 'awb_off_canvas' ],
					'subparam_map' => $subparams,
					'params'       => $params,
					'callback'     => [
						'function' => 'fusion_ajax',
						'action'   => 'get_fusion_tb_woo_filters_active',
						'ajax'     => true,
					],
				]
			)
		);
	}
}
add_action( 'fusion_builder_before_init', 'fusion_element_woo_filters_active' );
