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

if ( fusion_is_element_enabled( 'fusion_tb_woo_filters_categories' ) ) {

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

			/**
			 * Cached term map for thumbnail lookups (keyed by slug).
			 *
			 * @var array|null
			 */
			private $cat_term_map = null;

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

				add_filter( $this->shortcode_handle . '_widget_content', [ $this, 'adjust_category_filter_html' ], 10, 3 );
			}

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

				$args = wp_parse_args(
					[
						'display_type'                       => 'list',
						'display_checkboxes'                 => 'no',
						'checkbox_border_color'              => $fusion_settings->get( 'sep_color' ),
						'display_cat_thumbs'                 => 'no',
						'show_count'                         => 'yes',
						'orderby'                            => 'name',
						'hierarchical'                       => 'yes',
						'show_children_only'                 => 'no',
						'display_names'                      => 'yes',
						'hide_empty'                         => 'no',
						'max_depth'                          => '',
						'columns'                            => '3',
						'column_gap'                         => '15',
						'column_max_width'                   => '150',
						'align_items'                        => 'center',
						'category_thumb_size'                => 'thumbnail',
						'cat_opacity'                        => '1',
						'cat_hover_opacity'                  => '1',
						'cat_border_size'                    => '0',
						'cat_border_color'                   => $fusion_settings->get( 'link_color' ),
						'cat_border_hover_color'             => $fusion_settings->get( 'link_hover_color' ),
						'cat_border_radius'                  => $fusion_settings->get( 'form_border_radius' ),
						'list_color'                         => $fusion_settings->get( 'link_color' ),
						'list_hover_color'                   => $fusion_settings->get( 'link_hover_color' ),
						'list_bgcolor'                       => '',
						'list_hover_bgcolor'                 => '',
						'list_sep_color'                     => $fusion_settings->get( 'sep_color' ),
						'list_padding_top'                   => '',
						'list_padding_right'                 => '',
						'list_padding_bottom'                => '',
						'list_padding_left'                  => '',
						'list_align'                         => 'space-between',
						'fusion_font_family_list_item_font'  => '',
						'fusion_font_variant_list_item_font' => '',
						'list_item_font_size'                => '',
						'list_item_line_height'              => '',
						'list_item_letter_spacing'           => '',
						'list_item_text_transform'           => '',
						'fusion_font_family_count_font'      => '',
						'fusion_font_variant_count_font'     => '',
						'count_font_size'                    => '',
						'count_line_height'                  => '',
						'count_letter_spacing'               => '',
						'count_text_transform'               => '',
						'count_color'                        => '',
						'count_hover_color'                  => '',
						'dd_color'                           => $fusion_settings->get( 'form_text_color' ),
						'dd_bgcolor'                         => $fusion_settings->get( 'form_bg_color' ),
						'dd_hover_color'                     => '',
						'dd_hover_bgcolor'                   => '',
						'dd_border_color'                    => $fusion_settings->get( 'form_border_color' ),
					],
					$defaults
				);

				return $args;
			}

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

				$params = [
					'fusion_font_family_list_item_font'  => 'list_item_fonts',
					'fusion_font_variant_list_item_font' => 'list_item_fonts',
					'list_item_font_size'                => 'list_item_fonts',
					'list_item_line_height'              => 'list_item_fonts',
					'list_item_letter_spacing'           => 'list_item_fonts',
					'list_item_text_transform'           => 'list_item_fonts',
					'fusion_font_family_count_font'      => 'count_fonts',
					'fusion_font_variant_count_font'     => 'count_fonts',
					'count_font_size'                    => 'count_fonts',
					'count_line_height'                  => 'count_fonts',
					'count_letter_spacing'               => 'count_fonts',
					'count_text_transform'               => 'count_fonts',
				];

				return array_merge( $options, $params );
			}

			/**
			 * Gets the widget instance options passed to WC_Widget_Product_Categories.
			 *
			 * @access public
			 * @since 3.15.1
			 * @return array
			 */
			public function get_widget_instance() {
				return [
					'title'              => $this->args['title'],
					'orderby'            => $this->args['orderby'],
					'dropdown'           => 'dropdown' === $this->args['display_type'] ? 1 : 0,
					'count'              => 'yes' === $this->args['show_count'] ? 1 : 0,
					'hierarchical'       => ( 'yes' === $this->args['hierarchical'] && 'grid' !== $this->args['display_type'] ) ? 1 : 0,
					'show_children_only' => 'yes' === $this->args['show_children_only'] ? 1 : 0,
					'hide_empty'         => 'yes' === $this->args['hide_empty'] ? 1 : 0,
					'max_depth'          => absint( $this->args['max_depth'] ),
				];
			}

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

				$units = [
					'list_padding_top',
					'list_padding_right',
					'list_padding_bottom',
					'list_padding_left',
					'list_item_font_size',
					'list_item_letter_spacing',
					'count_font_size',
					'column_max_width',
				];

				$colors = [
					'checkbox_border_color',
					'list_color',
					'list_hover_color',
					'list_bgcolor',
					'list_hover_bgcolor',
					'list_sep_color',
					'dd_color',
					'dd_bgcolor',
					'dd_hover_color',
					'dd_hover_bgcolor',
					'dd_border_color',
					'count_color',
					'count_hover_color',
				];

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

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

			/**
			 * Builds the attributes array.
			 *
			 * @access public
			 * @since 3.15.1
			 * @return array
			 */
			public function attr() {
				$attr = parent::attr();
				if ( 'yes' === $this->args['display_checkboxes'] ) {
					$attr['class'] .= ' awb-checkboxes';
				}

				if ( 'grid' === $this->args['display_type'] ) {
					$attr['class'] .= ' awb-grid awb-columns-' . $this->args['columns'];
				} else if ( 'yes' === $this->args['hierarchical'] ) {
					$attr['class'] .= ' awb-hierarchical';
				}

				return $attr;
			}


			/**
			 * Fetch general options.
			 *
			 * @access public
			 * @since 3.15.1
			 * @return array
			 */
			public function fetch_general_options() {
				$options = parent::fetch_general_options();

				$params = [
					[
						'type'        => 'select',
						'heading'     => esc_attr__( 'Display Type', 'fusion-builder' ),
						'param_name'  => 'display_type',
						'default'     => 'list',
						'value'       => [
							'list'     => esc_html__( 'List', 'fusion-builder' ),
							'dropdown' => esc_html__( 'Dropdown', 'fusion-builder' ),
							'grid'     => esc_html__( 'Grid', 'fusion-builder' ),
						],
						'description' => esc_attr__( 'Select the display type for the category filter.', 'fusion-builder' ),
						'callback'    => [
							'function' => 'fusion_ajax',
							'action'   => 'get_fusion_tb_woo_filters_categories',
							'ajax'     => true,
						],
					],
					[
						'type'        => 'radio_button_set',
						'heading'     => esc_attr__( 'Display Checkboxes', 'fusion-builder' ),
						'description' => esc_attr__( 'Choose to display checkboxes in front of the category names.', 'fusion-builder' ),
						'param_name'  => 'display_checkboxes',
						'default'     => 'no',
						'value'       => [
							'yes' => esc_attr__( 'Yes', 'fusion-builder' ),
							'no'  => esc_attr__( 'No', 'fusion-builder' ),
						],
						'dependency'  => [
							[
								'element'  => 'display_type',
								'value'    => 'list',
								'operator' => '=',
							],
						],
					],
					[
						'type'        => 'radio_button_set',
						'heading'     => esc_attr__( 'Display Category Thumbnails', 'fusion-builder' ),
						'description' => esc_attr__( 'Choose to display the category thumbnail image before the category name.', 'fusion-builder' ),
						'param_name'  => 'display_cat_thumbs',
						'default'     => 'no',
						'value'       => [
							'yes' => esc_attr__( 'Yes', 'fusion-builder' ),
							'no'  => esc_attr__( 'No', 'fusion-builder' ),
						],
						'callback'    => [
							'function' => 'fusion_ajax',
							'action'   => 'get_fusion_tb_woo_filters_categories',
							'ajax'     => true,
						],
						'dependency'  => [
							[
								'element'  => 'display_type',
								'value'    => 'list',
								'operator' => '=',
							],
						],
					],
					[
						'type'        => 'radio_button_set',
						'heading'     => esc_attr__( 'Order By', 'fusion-builder' ),
						'description' => esc_attr__( 'Select how categories are ordered.', 'fusion-builder' ),
						'param_name'  => 'orderby',
						'default'     => 'name',
						'value'       => [
							'name'  => esc_html__( 'Name', 'fusion-builder' ),
							'order' => esc_html__( 'Category Order', 'fusion-builder' ),
						],
						'callback'    => [
							'function' => 'fusion_ajax',
							'action'   => 'get_fusion_tb_woo_filters_categories',
							'ajax'     => true,
						],
					],
					[
						'type'        => 'radio_button_set',
						'heading'     => esc_attr__( 'Hierarchical', 'fusion-builder' ),
						'description' => esc_attr__( 'Choose whether to display child categories in a nested hierarchy.', 'fusion-builder' ),
						'param_name'  => 'hierarchical',
						'default'     => 'no',
						'value'       => [
							'yes' => esc_attr__( 'Yes', 'fusion-builder' ),
							'no'  => esc_attr__( 'No', 'fusion-builder' ),
						],
						'dependency'  => [
							[
								'element'  => 'display_type',
								'value'    => 'list',
								'operator' => '=',
							],
						],						
						'callback'    => [
							'function' => 'fusion_ajax',
							'action'   => 'get_fusion_tb_woo_filters_categories',
							'ajax'     => true,
						],
					],
					[
						'type'        => 'radio_button_set',
						'heading'     => esc_attr__( 'Show Children Only', 'fusion-builder' ),
						'description' => esc_attr__( 'Only show children of the currently viewed category. This will hide children of all other categories.', 'fusion-builder' ),
						'param_name'  => 'show_children_only',
						'default'     => 'no',
						'value'       => [
							'yes' => esc_attr__( 'Yes', 'fusion-builder' ),
							'no'  => esc_attr__( 'No', 'fusion-builder' ),
						],
						'callback'    => [
							'function' => 'fusion_ajax',
							'action'   => 'get_fusion_tb_woo_filters_categories',
							'ajax'     => true,
						],
					],
					[
						'type'        => 'textfield',
						'heading'     => esc_attr__( 'Maximum Depth', 'fusion-builder' ),
						'description' => esc_attr__( 'Set the maximum depth of category hierarchy to display. Leave empty for unlimited.', 'fusion-builder' ),
						'param_name'  => 'max_depth',
						'value'       => '',
						'dependency'  => [
							[
								'element'  => 'display_type',
								'value'    => 'list',
								'operator' => '=',
							],							
							[
								'element'  => 'hierarchical',
								'value'    => 'yes',
								'operator' => '=',
							],
						],
						'callback'    => [
							'function' => 'fusion_ajax',
							'action'   => 'get_fusion_tb_woo_filters_categories',
							'ajax'     => true,
						],
					],					
					[
						'type'        => 'radio_button_set',
						'heading'     => esc_attr__( 'Hide Empty Categories', 'fusion-builder' ),
						'description' => esc_attr__( 'Choose to hide categories that contain no products.', 'fusion-builder' ),
						'param_name'  => 'hide_empty',
						'default'     => 'no',
						'value'       => [
							'yes' => esc_attr__( 'Yes', 'fusion-builder' ),
							'no'  => esc_attr__( 'No', 'fusion-builder' ),
						],
						'callback'    => [
							'function' => 'fusion_ajax',
							'action'   => 'get_fusion_tb_woo_filters_categories',
							'ajax'     => true,
						],
					],

				];

				$return = [];
				foreach ( $options as $opt ) {
					if ( 'title' === $opt['param_name'] ) {
						$opt['value'] = esc_html__( 'Product Categories', '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_size param.
					if ( 'title_size' === $opt['param_name'] ) {
						foreach ( $params as $param ) {
							$return[] = $param;
						}
					}
				}

				return $return;
			}

			/**
			 * Fetch design options.
			 *
			 * @access public
			 * @since 3.15.1
			 * @return array
			 */
			public function fetch_design_options() {
				$options             = parent::fetch_design_options();
				$fusion_settings     = awb_get_fusion_settings();
				$is_go_backend       = is_admin() && isset( $_GET['page'] ) && 'avada_options' === $_GET['page'];
				$is_live_builder     = ( function_exists( 'fusion_is_preview_frame' ) && fusion_is_preview_frame() ) || ( function_exists( 'fusion_is_builder_frame' ) && fusion_is_builder_frame() );
				$image_sizes_options = [];

				if ( $is_go_backend || $is_live_builder ) {				
					$image_sizes = get_intermediate_image_sizes();
					
					foreach ( $image_sizes as $size ) {
						$label                        = ucwords( str_replace( '_', ' ', $size ) );
						$image_sizes_options[ $size ] = $label;
					}
				}

				$params = [
					[
						'type'        => 'range',
						'heading'     => esc_html__( 'Number of Columns', 'fusion-builder' ),
						'description' => esc_html__( 'Set the number of columns. Set to 0 to use auto-fit, based on column max-width, instead of a fixed number of columns.', 'fusion-builder' ),
						'param_name'  => 'columns',
						'value'       => '3',
						'min'         => '0',
						'max'         => '15',
						'step'        => '1',
						'group'       => esc_html__( 'Design', 'fusion-builder' ),
						'dependency'  => [
							[
								'element'  => 'display_type',
								'value'    => 'grid',
								'operator' => '=',
							],
						],
					],
					[
						'type'        => 'range',
						'heading'     => esc_html__( 'Column Gap', 'fusion-builder' ),
						'description' => esc_html__( 'Set the gap size between columns. In Pixels.', 'fusion-builder' ),
						'param_name'  => 'column_gap',
						'value'       => '15',
						'min'         => '0',
						'max'         => '75',
						'step'        => '1',
						'group'       => esc_html__( 'Design', 'fusion-builder' ),
						'dependency'  => [
							[
								'element'  => 'display_type',
								'value'    => 'grid',
								'operator' => '=',
							],
						],
					],
					[
						'type'        => 'range',
						'heading'     => esc_attr__( 'Column Max Width', 'fusion-builder' ),
						'description' => esc_attr__( 'Set the maximum width of a column. In Pixels.', 'fusion-builder' ),
						'param_name'  => 'column_max_width',
						'value'       => '150',
						'min'         => '0',
						'max'         => '400',
						'step'        => '10',
						'group'       => esc_html__( 'Design', 'fusion-builder' ),
						'dependency'  => [
							[
								'element'  => 'display_type',
								'value'    => 'grid',
								'operator' => '=',
							],
						],
					],
					[
						'type'        => 'radio_button_set',
						'heading'     => esc_html__( 'Align Items', 'fusion-builder' ),
						'description' => esc_html__( 'Defines the cell alignment within the grid.', 'fusion-builder' ),
						'param_name'  => 'align_items',
						'default'     => 'center',
						'back_icons'  => true,
						'grid_layout' => true,
						'group'       => esc_html__( 'Design', 'fusion-builder' ),
						'value'       => [
							'flex-start' => esc_html__( 'Flex Start', 'fusion-builder' ),
							'center'     => esc_html__( 'Center', 'fusion-builder' ),
							'flex-end'   => esc_html__( 'Flex End', 'fusion-builder' ),
						],
						'icons'       => [
							'flex-start' => '<span class="fusiona-align-top-columns"></span>',
							'center'     => '<span class="fusiona-align-center-columns"></span>',
							'flex-end'   => '<span class="fusiona-align-bottom-columns"></span>',
						],
						'dependency'  => [
							[
								'element'  => 'display_type',
								'value'    => 'grid',
								'operator' => '=',
							],
						],
					],
					'category_thumb_size' => [
						'type'        => 'select',
						'heading'     => esc_html__( 'Category Thumb Size', 'fusion-builder' ),
						'description' => esc_html__( 'Select the image size of the category thumbnail.', 'fusion-builder' ),
						'group'       => esc_html__( 'Design', 'fusion-builder' ),
						'param_name'  => 'category_thumb_size',
						'default'     => ! empty( $image_sizes_options ) ? array_keys( $image_sizes_options )[0] : 'thumbnail',
						'value'       => $image_sizes_options,
						'callback'    => [
							'function' => 'fusion_ajax',
							'action'   => 'get_fusion_tb_woo_filters_categories',
							'ajax'     => true,
						],					
						'dependency'  => [
							[
								'element'  => 'display_type',
								'value'    => 'grid',
								'operator' => '=',
							],
						],
					],
					[
						'type'        => 'colorpickeralpha',
						'heading'     => esc_attr__( 'Checkbox Border Color', 'fusion-builder' ),
						'description' => esc_attr__( 'Controls the border color of the checkboxes, when not active.', 'fusion-builder' ),
						'param_name'  => 'checkbox_border_color',
						'value'       => '',
						'default'     => $fusion_settings->get( 'sep_color' ),
						'group'       => esc_html__( 'Design', 'fusion-builder' ),
						'dependency'  => [
							[
								'element'  => 'display_checkboxes',
								'value'    => 'yes',
								'operator' => '=',
							],
							[
								'element'  => 'display_type',
								'value'    => 'dropdown',
								'operator' => '!=',
							],
						],
					],
					[
						'type'        => 'radio_button_set',
						'heading'     => esc_html__( 'Display Category Names', 'fusion-builder' ),
						'description' => esc_html__( 'Select if you want to display the category names.', 'fusion-builder' ),
						'group'       => esc_html__( 'Design', 'fusion-builder' ),
						'param_name'  => 'display_names',
						'default'     => 'yes',
						'value'       => [
							'yes' => esc_html__( 'Yes', 'fusion-builder' ),
							'no'  => esc_html__( 'No', 'fusion-builder' ),
						],
						'callback'    => [
							'function' => 'fusion_ajax',
							'action'   => 'get_fusion_tb_woo_filters_categories',
							'ajax'     => true,
						],
						'dependency'  => [
							[
								'element'  => 'display_type',
								'value'    => 'dropdown',
								'operator' => '!=',
							],
						],
					],					
					[
						'type'             => 'typography',
						'heading'          => esc_attr__( 'Category Item Typography', 'fusion-builder' ),
						'description'      => esc_html__( 'Controls the typography of the category list item. Leave empty for the global font family.', 'fusion-builder' ),
						'param_name'       => 'list_item_fonts',
						'choices'          => [
							'font-family'    => 'list_item_font',
							'font-size'      => 'list_item_font_size',
							'text-transform' => 'list_item_text_transform',
							'line-height'    => 'list_item_line_height',
							'letter-spacing' => 'list_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' ),
						'dependency'       => [
							[
								'element'  => 'display_type',
								'value'    => 'dropdown',
								'operator' => '!=',
							],
							[
								'element'  => 'display_names',
								'value'    => 'yes',
								'operator' => '=',
							],
						],
					],
					[
						'type'             => 'dimension',
						'remove_from_atts' => true,
						'heading'          => esc_attr__( 'Category Item Padding', 'fusion-builder' ),
						'description'      => esc_attr__( 'In pixels or percentage, ex: 10px or 10%.', 'fusion-builder' ),
						'param_name'       => 'list_padding',
						'value'            => [
							'list_padding_top'    => '',
							'list_padding_right'  => '',
							'list_padding_bottom' => '',
							'list_padding_left'   => '',
						],
						'group'            => esc_attr__( 'Design', 'fusion-builder' ),
						'dependency'       => [
							[
								'element'  => 'display_type',
								'value'    => 'list',
								'operator' => '=',
							],
						],
					],
					[
						'type'        => 'radio_button_set',
						'heading'     => esc_attr__( 'Category Item Alignment', 'fusion-builder' ),
						'description' => esc_attr__( 'Select the content alignment within the list item.', 'fusion-builder' ),
						'param_name'  => 'list_align',
						'default'     => 'space-between',
						'grid_layout' => true,
						'back_icons'  => true,
						'icons'       => [
							'flex-start'    => '<span class="fusiona-horizontal-flex-start"></span>',
							'center'        => '<span class="fusiona-horizontal-flex-center"></span>',
							'flex-end'      => '<span class="fusiona-horizontal-flex-end"></span>',
							'space-between' => '<span class="fusiona-horizontal-space-between"></span>',
							'space-around'  => '<span class="fusiona-horizontal-space-around"></span>',
							'space-evenly'  => '<span class="fusiona-horizontal-space-evenly"></span>',
						],
						'value'       => [
							'flex-start'    => esc_html__( 'Flex Start', 'fusion-builder' ),
							'center'        => esc_html__( 'Center', 'fusion-builder' ),
							'flex-end'      => esc_html__( 'Flex End', 'fusion-builder' ),
							'space-between' => esc_html__( 'Space Between', 'fusion-builder' ),
							'space-around'  => esc_html__( 'Space Around', 'fusion-builder' ),
							'space-evenly'  => esc_html__( 'Space Evenly', 'fusion-builder' ),
						],
						'group'       => esc_attr__( 'Design', 'fusion-builder' ),
						'dependency'  => [
							[
								'element'  => 'display_type',
								'value'    => 'list',
								'operator' => '=',
							],
						],
					],
					[
						'type'        => 'colorpickeralpha',
						'heading'     => esc_attr__( 'Category Separator Color', 'fusion-builder' ),
						'description' => esc_attr__( 'Controls the separator color between category items.', 'fusion-builder' ),
						'param_name'  => 'list_sep_color',
						'value'       => '',
						'default'     => $fusion_settings->get( 'sep_color' ),
						'group'       => esc_html__( 'Design', 'fusion-builder' ),
						'dependency'  => [
							[
								'element'  => 'display_type',
								'value'    => 'list',
								'operator' => '=',
							],
						],
					],
					[
						'type'          => 'colorpickeralpha',
						'heading'       => esc_attr__( 'Category Background Color', 'fusion-builder' ),
						'description'   => esc_attr__( 'Controls the background color of each category item.', 'fusion-builder' ),
						'param_name'    => 'list_bgcolor',
						'value'         => '',
						'default'       => '',
						'group'         => esc_html__( 'Design', 'fusion-builder' ),
						'dependency'    => [
							[
								'element'  => 'display_type',
								'value'    => 'list',
								'operator' => '=',
							],
						],
						'states'        => [
							'hover' => [
								'label'      => __( 'Hover', 'fusion-builder' ),
								'param_name' => 'list_hover_bgcolor',
								'preview'    => [
									'selector' => '.widget_product_categories li',
									'type'     => 'class',
									'toggle'   => 'hover',
								],
							],
						],
						'connect-state' => [ 'list_color' ],
					],
					[
						'type'          => 'colorpickeralpha',
						'heading'       => esc_attr__( 'Category Color', 'fusion-builder' ),
						'description'   => esc_attr__( 'Controls the text/link color of each category item.', 'fusion-builder' ),
						'param_name'    => 'list_color',
						'value'         => '',
						'default'       => $fusion_settings->get( 'link_color' ),
						'group'         => esc_html__( 'Design', 'fusion-builder' ),
						'dependency'    => [
							[
								'element'  => 'display_type',
								'value'    => 'dropdown',
								'operator' => '!=',
							],
						],
						'states'        => [
							'hover' => [
								'label'      => __( 'Hover', 'fusion-builder' ),
								'param_name' => 'list_hover_color',
								'default'    => $fusion_settings->get( 'link_hover_color' ),
								'preview'    => [
									'selector' => '.widget_product_categories li',
									'type'     => 'class',
									'toggle'   => 'hover',
								],
							],
						],
						'connect-state' => [ 'list_bgcolor' ],
					],
					[
						'type'        => 'radio_button_set',
						'heading'     => esc_attr__( 'Display Count Number', 'fusion-builder' ),
						'description' => esc_attr__( 'Display the product count next to each category.', 'fusion-builder' ),
						'param_name'  => 'show_count',
						'default'     => 'yes',
						'value'       => [
							'yes' => esc_attr__( 'Yes', 'fusion-builder' ),
							'no'  => esc_attr__( 'No', 'fusion-builder' ),
						],
						'group'       => esc_attr__( 'Design', 'fusion-builder' ),
						'callback'    => [
							'function' => 'fusion_ajax',
							'action'   => 'get_fusion_tb_woo_filters_categories',
							'ajax'     => true,
						],
						'dependency'  => [
							[
								'element'  => 'display_type',
								'value'    => 'dropdown',
								'operator' => '!=',
							],							
						],
					],
					[
						'type'             => 'typography',
						'heading'          => esc_attr__( 'Count Number Typography', 'fusion-builder' ),
						'description'      => esc_html__( 'Controls the typography of the count number.', 'fusion-builder' ),
						'param_name'       => 'count_fonts',
						'choices'          => [
							'font-family'    => 'count_font',
							'font-size'      => 'count_font_size',
							'text-transform' => 'count_text_transform',
							'line-height'    => 'count_line_height',
							'letter-spacing' => 'count_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' ),
						'dependency'       => [
							[
								'element'  => 'display_type',
								'value'    => 'dropdown',
								'operator' => '!=',
							],
							[
								'element'  => 'show_count',
								'value'    => 'no',
								'operator' => '!=',
							],
						],
					],
					[
						'type'        => 'colorpickeralpha',
						'heading'     => esc_attr__( 'Count Number Color', 'fusion-builder' ),
						'description' => esc_attr__( 'Controls the color of the count number.', 'fusion-builder' ),
						'param_name'  => 'count_color',
						'value'       => '',
						'default'     => '',
						'group'       => esc_html__( 'Design', 'fusion-builder' ),
						'dependency'  => [
							[
								'element'  => 'display_type',
								'value'    => 'dropdown',
								'operator' => '!=',
							],
							[
								'element'  => 'show_count',
								'value'    => 'no',
								'operator' => '!=',
							],
						],
						'states'      => [
							'hover' => [
								'label'      => __( 'Hover', 'fusion-builder' ),
								'param_name' => 'count_hover_color',
								'preview'    => [
									'selector' => '.widget_product_categories li',
									'type'     => 'class',
									'toggle'   => 'hover',
								],
							],
						],
					],
					[
						'type'        => 'colorpickeralpha',
						'heading'     => esc_attr__( 'Dropdown Border Color', 'fusion-builder' ),
						'description' => esc_attr__( 'Controls the dropdown border color.', 'fusion-builder' ),
						'param_name'  => 'dd_border_color',
						'value'       => '',
						'default'     => $fusion_settings->get( 'form_border_color' ),
						'group'       => esc_html__( 'Design', 'fusion-builder' ),
						'dependency'  => [
							[
								'element'  => 'display_type',
								'value'    => 'dropdown',
								'operator' => '=',
							],
						],
					],
					[
						'type'          => 'colorpickeralpha',
						'heading'       => esc_attr__( 'Dropdown Background Color', 'fusion-builder' ),
						'description'   => esc_attr__( 'Controls the dropdown background color.', 'fusion-builder' ),
						'param_name'    => 'dd_bgcolor',
						'value'         => '',
						'default'       => $fusion_settings->get( 'form_bg_color' ),
						'group'         => esc_html__( 'Design', 'fusion-builder' ),
						'dependency'    => [
							[
								'element'  => 'display_type',
								'value'    => 'dropdown',
								'operator' => '=',
							],
						],
						'states'        => [
							'hover' => [
								'label'      => __( 'Hover', 'fusion-builder' ),
								'param_name' => 'dd_hover_bgcolor',
							],
						],
						'connect-state' => [ 'dd_color' ],
					],
					[
						'type'          => 'colorpickeralpha',
						'heading'       => esc_attr__( 'Dropdown Text Color', 'fusion-builder' ),
						'description'   => esc_attr__( 'Controls the dropdown text color.', 'fusion-builder' ),
						'param_name'    => 'dd_color',
						'value'         => '',
						'default'       => $fusion_settings->get( 'form_text_color' ),
						'group'         => esc_html__( 'Design', 'fusion-builder' ),
						'dependency'    => [
							[
								'element'  => 'display_type',
								'value'    => 'dropdown',
								'operator' => '=',
							],
						],
						'states'        => [
							'hover' => [
								'label'      => __( 'Hover', 'fusion-builder' ),
								'param_name' => 'dd_hover_color',
							],
						],
						'connect-state' => [ 'dd_bgcolor' ],
					],
					[
						'type'        => 'range',
						'heading'     => esc_html__( 'Category Thumb Opacity', 'fusion-builder' ),
						'description' => esc_html__( 'Controls the opacity of the category thumbs. In percentage, 1 = 100%.', 'fusion-builder' ),
						'param_name'  => 'cat_opacity',
						'group'       => esc_html__( 'Design', 'fusion-builder' ),
						'value'       => '1',
						'min'         => '0',
						'max'         => '1',
						'step'        => '0.05',
						'states'        => [
							'hover' => [
								'label'      => __( 'Hover', 'fusion-builder' ),
								'param_name' => 'cat_hover_opacity',
								'value'      => '1',
								'preview'    => [
									'selector' => '.widget_product_categories li',
									'type'     => 'class',
									'toggle'   => 'hover',
								],
							],
						],
						'dependency'  => [
							[
								'element'  => 'display_type',
								'value'    => 'grid',
								'operator' => '=',
							],
						],
					],
					[
						'type'        => 'range',
						'heading'     => esc_html__( 'Category Thumb Border Size', 'fusion-builder' ),
						'description' => esc_html__( 'Controls the border size of the category thumbs. In pixels.', 'fusion-builder' ),
						'param_name'  => 'cat_border_size',
						'group'       => esc_html__( 'Design', 'fusion-builder' ),
						'value'       => '0',
						'min'         => '0',
						'max'         => '25',
						'step'        => '1',
						'dependency'  => [
							[
								'element'  => 'display_type',
								'value'    => 'grid',
								'operator' => '=',
							],
						],
					],
					[
						'type'          => 'colorpickeralpha',
						'heading'       => esc_html__( 'Category Thumb Border Color', 'fusion-builder' ),
						'description'   => esc_html__( 'Controls the border color of the category thumbs.', 'fusion-builder' ),
						'param_name'    => 'cat_border_color',
						'value'         => '',
						'default'       => $fusion_settings->get( 'link_color' ),
						'group'         => esc_html__( 'Design', 'fusion-builder' ),
						'states'        => [
							'hover' => [
								'label'      => __( 'Hover', 'fusion-builder' ),
								'param_name' => 'cat_border_hover_color',
								'default'    => $fusion_settings->get( 'link_hover_color' ),
								'preview'    => [
									'selector' => '.widget_product_categories li',
									'type'     => 'class',
									'toggle'   => 'hover',
								],
							],
						],
						'dependency'  => [
							[
								'element'  => 'cat_border_size',
								'value'    => '0',
								'operator' => '!=',
							],
							[
								'element'  => 'display_type',
								'value'    => 'grid',
								'operator' => '=',
							],
						],
					],
					[
						'type'        => 'range',
						'heading'     => esc_html__( 'Category Thumb Border Radius', 'fusion-builder' ),
						'param_name'  => 'cat_border_radius',
						'description' => esc_html__( 'Controls the border radius of the category thumbs. In pixels.', 'fusion-builder' ),
						'min'         => '0',
						'max'         => '300',
						'step'        => '1',
						'value'       => '',
						'default'     => $fusion_settings->get( 'form_border_radius' ),
						'group'       => esc_html__( 'Design', 'fusion-builder' ),
						'dependency'  => [
							[
								'element'  => 'display_type',
								'value'    => 'grid',
								'operator' => '=',
							],
						],
					],
				];

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

				return $options;
			}

			/**
			 * Get the style variables.
			 *
			 * @access protected
			 * @since 3.15.1
			 * @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 );

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

				// List Item Typography.
				$custom_vars = $this->get_typo_variables(
					[
						'list_item_font'           => 'font',
						'list_item_font_size'      => 'size',
						'list_item_line_height'    => 'line_height',
						'list_item_letter_spacing' => 'letter_spacing',
						'list_item_text_transform' => 'text_transform',
					],
					$custom_vars
				);

				// Count Typography.
				$custom_vars = $this->get_typo_variables(
					[
						'count_font'           => 'font',
						'count_font_size'      => 'size',
						'count_line_height'    => 'line_height',
						'count_letter_spacing' => 'letter_spacing',
						'count_text_transform' => 'text_transform',
					],
					$custom_vars
				);

				if ( ! $this->is_default( 'list_align' ) ) {
					$custom_vars['list-align'] = $this->args['list_align'];
				}

				if ( ! $this->is_default( 'show_count' ) ) {
					$custom_vars['show-count'] = 'none';
				}

				// CSS custom properties.
				$css_vars_options = [
					'checkbox_border_color'  => [ 'callback' => [ 'Fusion_Sanitize', 'color' ] ],
					'list_color'             => [ 'callback' => [ 'Fusion_Sanitize', 'color' ] ],
					'list_hover_color'       => [ 'callback' => [ 'Fusion_Sanitize', 'color' ] ],
					'list_bgcolor'           => [ 'callback' => [ 'Fusion_Sanitize', 'color' ] ],
					'list_hover_bgcolor'     => [ 'callback' => [ 'Fusion_Sanitize', 'color' ] ],
					'list_sep_color'         => [ 'callback' => [ 'Fusion_Sanitize', 'color' ] ],
					'dd_color'               => [ 'callback' => [ 'Fusion_Sanitize', 'color' ] ],
					'dd_bgcolor'             => [ 'callback' => [ 'Fusion_Sanitize', 'color' ] ],
					'dd_hover_color'         => [ 'callback' => [ 'Fusion_Sanitize', 'color' ] ],
					'dd_hover_bgcolor'       => [ 'callback' => [ 'Fusion_Sanitize', 'color' ] ],
					'dd_border_color'        => [ 'callback' => [ 'Fusion_Sanitize', 'color' ] ],
					'count_color'            => [ 'callback' => [ 'Fusion_Sanitize', 'color' ] ],
					'count_hover_color'      => [ 'callback' => [ 'Fusion_Sanitize', 'color' ] ],
					'columns',
					'column_gap'             => [ 'callback' => [ 'Fusion_Sanitize', 'get_value_with_unit' ] ],
					'column_max_width'       => [ 'callback' => [ 'Fusion_Sanitize', 'get_value_with_unit' ] ],
					'align_items',
					'cat_opacity',
					'cat_hover_opacity',
					'cat_border_size'        => [ 'callback' => [ 'Fusion_Sanitize', 'get_value_with_unit' ] ],
					'cat_border_color'       => [ 'callback' => [ 'Fusion_Sanitize', 'color' ] ],
					'cat_border_hover_color' => [ 'callback' => [ 'Fusion_Sanitize', 'color' ] ],
					'cat_border_radius'      => [ 'callback' => [ 'Fusion_Sanitize', 'get_value_with_unit' ] ],
				];

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

				return $styles;
			}

			/**
			 * Build a slug-keyed term map for category thumbnail lookups.
			 *
			 * @access protected
			 * @since 3.15.1
			 * @return array
			 */
			protected function get_cat_term_map() {
				if ( null !== $this->cat_term_map ) {
					return $this->cat_term_map;
				}

				$terms = get_terms( [
					'taxonomy'   => 'product_cat',
					'hide_empty' => false,
				] );

				$this->cat_term_map = [];

				if ( is_wp_error( $terms ) || empty( $terms ) ) {
					return $this->cat_term_map;
				}

				foreach ( $terms as $term ) {
					// Index by both name (lowercased) and slug for flexible matching.
					$this->cat_term_map[ strtolower( $term->name ) ] = $term;
					$this->cat_term_map[ $term->slug ]               = $term;
				}

				return $this->cat_term_map;
			}

			/**
			 * Adjusts the widget HTML output to inject category thumbnail images before the link text.
			 *
			 * @access public
			 * @since 3.15.1
			 * @param string $content      Widget HTML output.
			 * @param array  $args         Element args.
			 * @param string $element_name Shortcode handle.
			 * @return string
			 */
			public function adjust_category_filter_html( $content, $args, $element_name ) {
				if ( 'fusion_tb_woo_filters_categories' !== $element_name ) {
					return $content;
				}

				if ( false === strpos( $content, '<li' ) ) {
					return $content;
				}

				$display_type  = $args['display_type'];
				$show_thumbs   = ( isset( $args['display_cat_thumbs'] ) && 'yes' === $args['display_cat_thumbs'] ) || ( isset( $args['display_type'] ) && 'grid' === $args['display_type'] );
				$display_name  = isset( $args['display_names'] ) ? $args['display_names'] : 'yes';
				$display_count = isset( $args['show_count'] ) ? $args['show_count'] : 'yes';
				$thumb_size    = isset( $args['category_thumb_size'] ) ? $args['category_thumb_size'] : 'thumbnail';

				if ( ! class_exists( 'DOMDocument' ) || ! function_exists( 'libxml_use_internal_errors' ) ) {
					return $content;
				}

				$term_map = $this->get_cat_term_map();
				if ( empty( $term_map ) ) {
					return $content;
				}

				libxml_use_internal_errors( true );

				$dom = new DOMDocument();
				// Use mb_convert_encoding or similar if content has special chars, but for now simple wrapper.
				$dom->loadHTML(
					'<?xml encoding="utf-8" ?><div id="awb-cat-root">' . $content . '</div>',
					LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD
				);

				$xpath = new DOMXPath( $dom );

				// --- Inject category thumbnails before link text ---
				$anchors = $xpath->query( '//li[contains(@class,"cat-item")]/a' );

				foreach ( $anchors as $a ) {
					$label = trim( $a->textContent );

					if ( ! $label ) {
						continue;
					}

					// Try name lookup first, then slug from href.
					$key  = strtolower( $label );
					$term = isset( $term_map[ $key ] ) ? $term_map[ $key ] : null;

					if ( ! $term ) {
						continue;
					}

					$a->setAttribute( 'data-slug', $term->slug );

					// Check if active.
					$current_cat = get_query_var( 'product_cat' );
					if ( $current_cat === $term->slug || ( is_array( $current_cat ) && in_array( $term->slug, $current_cat ) ) ) {
						$parent_li = $a->parentNode;
						if ( $parent_li instanceof DOMElement && 'li' === $parent_li->tagName ) {
							$li_class = $parent_li->getAttribute( 'class' );
							$parent_li->setAttribute( 'class', $li_class . ' chosen' );
						}
					}

					// Find count span if it exists as a sibling.
					$count_node = null;
					$next       = $a->nextSibling;

					// Skip text nodes (whitespace).
					while ( $next && XML_TEXT_NODE === $next->nodeType ) {
						$next = $next->nextSibling;
					}

					if ( $next instanceof DOMElement && 'span' === $next->tagName && 'count' === $next->getAttribute( 'class' ) ) {
						$count_node = $next;
					}

					$img_html = '';
					if ( $show_thumbs ) {
						$thumbnail_id = get_term_meta( $term->term_id, 'thumbnail_id', true );

						if ( $thumbnail_id ) {
							$img_html = wp_get_attachment_image( $thumbnail_id, $thumb_size, false, [ 'class' => 'cat-thumbnail' ] );
						} else {
							$img_html = wc_placeholder_img( $thumb_size, [ 'class' => 'cat-thumbnail' ] );
						}
					}

					// Wrap image and label together.
					$attr_wrapper = $dom->createElement( 'span' );
					$attr_wrapper->setAttribute( 'class', 'awb-woo-attr-wrapper' );

					if ( $img_html ) {
						$img_frag = $dom->createDocumentFragment();
						@$img_frag->appendXML( $img_html );
						$attr_wrapper->appendChild( $img_frag );
					}

					if ( 'yes' === $display_name ) {
						$label_span = $dom->createElement( 'span' );
						$label_span->setAttribute( 'class', 'awb-cat-label' );
						$label_span->appendChild( $dom->createTextNode( $label ) );
						$attr_wrapper->appendChild( $label_span );
					}

					// Clear existing anchor contents.
					while ( $a->firstChild ) {
						$a->removeChild( $a->firstChild );
					}

					// Inject the wrapper.
					$a->appendChild( $attr_wrapper );

					// Include count into anchor if present and enabled.
					if ( $count_node ) {
						if ( 'yes' === $display_count ) {
							$a->appendChild( $dom->createTextNode( ' ' ) );
							$a->appendChild( $count_node );
						} else if ( $count_node->parentNode ) {
							$count_node->parentNode->removeChild( $count_node );
						}
					}
				}

				// Extract inner content of our root wrapper.
				$root = $dom->getElementById( 'awb-cat-root' );

				if ( ! $root ) {
					libxml_clear_errors();
					return $content;
				}

				$output = '';
				foreach ( $root->childNodes as $child ) {
					$output .= $dom->saveHTML( $child );
				}

				libxml_clear_errors();

				return $output;
			}

			/**
			 * Emulate filter element for Live Editor.
			 *
			 * @access public
			 * @since 3.15.1
			 * @return void
			 */
			public function emulate_filter_element() {
				// WC_Widget_Product_Categories does not require a product query.
			}

			/**
			 * Restore filter element for Live Editor.
			 *
			 * @access public
			 * @since 3.15.1
			 * @return void
			 */
			public function restore_filter_element() {
				// Nothing to restore.
			}
		}
	}

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

	// Instantiate.
	awb_woo_filter_categories();
}

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

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

		fusion_builder_map(
			fusion_builder_frontend_data(
				'FusionTB_WooFiltersCategories',
				[
					'name'         => esc_attr__( 'Woo Filter By Category', 'fusion-builder' ),
					'shortcode'    => 'fusion_tb_woo_filters_categories',
					'help_url'     => 'https://avada.com/documentation/woo-filter-by-category-element/',
					'icon'         => 'fusiona-woo-filters-cats',
					'component'    => true,
					'templates'    => [ 'content', 'awb_off_canvas' ],
					'subparam_map' => $subparams,
					'params'       => $params,
					'callback'     => [
						'function' => 'fusion_ajax',
						'action'   => 'get_fusion_tb_woo_filters_categories',
						'ajax'     => true,
					],
				]
			)
		);
	}
}
add_action( 'fusion_builder_wp_loaded', 'fusion_element_woo_filters_categories' );
