<?php
/**
 * Favorite Button element.
 *
 * @package BricksExtras
 */

if ( ! defined( 'ABSPATH' ) ) {
	exit; // Exit if accessed directly.
}

/**
 * Favorite Button element class.
 */
class X_Favorite extends \Bricks\Element {

	/**
	 * Element category.
	 *
	 * @var string
	 */
	public $category = 'extras';

	/**
	 * Element name.
	 *
	 * @var string
	 */
	public $name = 'xfavorite';

	/**
	 * Element icon.
	 *
	 * @var string
	 */
	public $icon = 'ti-heart';

	/**
	 * CSS selector.
	 *
	 * @var string
	 */
	public $css_selector = '';

	/**
	 * Element is nestable.
	 *
	 * @var bool
	 */
	public $nestable = true;

	/**
	 * Script localized flag.
	 *
	 * @var bool
	 */
	private static $script_localized = false;

	/**
	 * Get element label.
	 */
	public function get_label() {
		return esc_html__( 'Favorite Button', 'bricksextras' );
	}

	/**
	 * Get element keywords.
	 */
	public function get_keywords() {
		return array( 'favorite', 'wishlist' );
	}

	/**
	 * Set control groups.
	 */
	public function set_control_groups() {

		$this->control_groups['icons'] = array(
			'title' => esc_html__( 'Icons', 'bricks' ),
			'tab'   => 'content',
		);

		$this->control_groups['button'] = array(
			'title' => esc_html__( 'Button', 'bricks' ),
			'tab'   => 'content',
		);

		$this->control_groups['animation'] = array(
			'title'    => esc_html__( 'Animation', 'bricks' ),
			'tab'      => 'content',
			'required' => array( 'buttonType', '!=', 'count' ),
		);

		$this->control_groups['count'] = array(
			'title'    => esc_html__( 'Count', 'bricks' ),
			'tab'      => 'content',
			'required' => array( 'buttonType', '=', 'count' ),
		);

		$this->control_groups['tooltip'] = array(
			'title' => esc_html__( 'Tooltip', 'bricks' ),
			'tab'   => 'content',
		);
	}

	/**
	 * Set element controls.
	 */
	public function set_controls() {

		$inner_selector = '.x-favorite';

		$this->controls['_display']['css'][0]['selector']        = $inner_selector;
		$this->controls['_flexDirection']['css'][0]['selector']  = $inner_selector;
		$this->controls['_alignSelf']['css'][0]['selector']      = $inner_selector;
		$this->controls['_justifyContent']['css'][0]['selector'] = $inner_selector;
		$this->controls['_alignItems']['css'][0]['selector']     = $inner_selector;
		$this->controls['_gap']['css'][0]['selector']            = $inner_selector;
		$this->controls['_padding']['css'][0]['selector']        = $inner_selector;

		$this->controls['_border']['css'][0]['selector']    = $inner_selector;
		$this->controls['_boxShadow']['css'][0]['selector'] = $inner_selector;
		$this->controls['_gradient']['css'][0]['selector']  = $inner_selector;
		$this->controls['_transform']['css'][0]['selector'] = $inner_selector;

		$this->controls['access'] = array(
			'tab'         => 'content',
			'label'       => esc_html__( 'User access', 'bricksextras' ),
			'type'        => 'select',
			'inline'      => true,
			'options'     => array(
				'logged_in' => esc_html__( 'Logged in users', 'bricksextras' ),
				'all'       => esc_html__( 'All users', 'bricksextras' ),
			),
			'placeholder' => esc_html__( 'Logged in users', 'bricksextras' ),
		);

		$this->controls['accessInfo'] = array(
			'tab'         => 'content',
			'type'        => 'info',
			'description' => esc_html__( 'Users selections saves in user meta', 'bricksextras' ),
			'required'    => array( 'access', '!=', 'all' ),
		);

		$this->controls['accessInfoAll'] = array(
			'tab'         => 'content',
			'type'        => 'info',
			'description' => esc_html__( 'Users selections saves in user meta, logged out user saved as cookie', 'bricksextras' ),
			'required'    => array( 'access', '=', 'all' ),
		);

		$this->controls['accessSep'] = array(
			'tab'  => 'content',
			'type' => 'separator',
		);

		$this->controls['buttonType'] = array(
			'tab'         => 'content',
			'label'       => esc_html__( 'Type', 'bricks' ),
			'type'        => 'select',
			'inline'      => true,
			'options'     => array(
				'add_remove' => esc_html__( 'Add', 'bricks' ) . ' / ' . esc_html__( 'Remove', 'bricks' ),
				'remove'     => esc_html__( 'Clear', 'bricks' ),
				'clear'      => esc_html__( 'Clear all', 'bricks' ),
				'count'      => esc_html__( 'Count', 'bricks' ),
			),
			'placeholder' => esc_html__( 'Add', 'bricks' ) . ' / ' . esc_html__( 'Remove', 'bricks' ),
		);

		$list_options = bricks_is_builder() ? \Bricks\Helpers::get_registered_post_types() : array();

		$list_options['custom'] = esc_html__( 'Custom', 'bricks' );

		$this->controls['postType'] = array(
			'tab'         => 'content',
			'label'       => esc_html__( 'Post type', 'bricks' ),
			'type'        => 'select',
			'options'     => $list_options,
			'clearable'   => true,
			'inline'      => true,
			'searchable'  => true,
			'placeholder' => esc_html__( 'Select option', 'bricks' ),
		);

		$this->controls['newList'] = array(
			'tab'   => 'content',
			'type'  => 'checkbox',
			'label' => esc_html__( 'Custom list', 'bricksextras' ),
		);

		$this->controls['listSlug'] = array(
			'tab'      => 'content',
			'label'    => esc_html__( 'List identifier', 'bricksextras' ),
			'info'     => esc_html__( 'List that is being saved to', 'bricksextras' ),
			'type'     => 'text',
			'inline'   => true,
			'required' => array( 'newList', '=', true ),
		);

		$this->controls['listMaximum'] = array(
			'tab'      => 'content',
			'label'    => esc_html__( 'Max. number of posts in list', 'bricksextras' ),
			'type'     => 'number',
			'units'    => false,
			'inline'   => true,
			'small'    => true,
			'required' => array(
				array( 'newList', '=', true ),
				array( 'buttonType', '!=', array( 'remove', 'clear', 'count' ) ),
			),
		);

		$this->controls['buttonTextSep'] = array(
			'tab'  => 'content',
			'type' => 'separator',
		);

		$this->controls['addButtonText'] = array(
			'tab'      => 'content',
			'label'    => esc_html__( 'Button text', 'bricks' ),
			'type'     => 'text',
			'inline'   => true,
			'default'  => esc_html__( 'Add to favorites', 'bricksextras' ),
			'required' => array( 'buttonType', '!=', array( 'remove', 'clear', 'count' ) ),
		);

		$this->controls['removeButtonText'] = array(
			'tab'      => 'content',
			'label'    => esc_html__( 'Button text', 'bricks' ),
			'type'     => 'text',
			'inline'   => true,
			'default'  => esc_html__( 'Remove', 'bricksextras' ),
			'required' => array( 'buttonType', '=', 'remove' ),
		);

		$this->controls['addedButtonText'] = array(
			'tab'      => 'content',
			'label'    => esc_html__( 'Button text', 'bricks' ) . ' (' . esc_html__( 'Added', 'bricks' ) . ')',
			'type'     => 'text',
			'inline'   => true,
			'required' => array( 'buttonType', '!=', array( 'remove', 'clear', 'count' ) ),
		);

		$this->controls['maxReachedButtonText'] = array(
			'tab'      => 'content',
			'label'    => esc_html__( 'Button text', 'bricks' ) . ' (' . esc_html__( 'Maximum reached', 'bricksextras' ) . ')',
			'type'     => 'text',
			'inline'   => true,
			'default'  => esc_html__( 'Maximum reached', 'bricksextras' ),
			'required' => array(
				array( 'buttonType', '!=', array( 'remove', 'clear', 'count' ) ),
				array( 'listMaximum', '!=', '' ),
			),
		);

		$this->controls['clearButtonText'] = array(
			'tab'      => 'content',
			'label'    => esc_html__( 'Button text', 'bricks' ),
			'type'     => 'text',
			'inline'   => true,
			'required' => array( 'buttonType', '=', 'clear' ),
			'default'  => esc_html__( 'Clear all', 'bricks' ),
		);

		$this->controls['clearedButtonText'] = array(
			'tab'      => 'content',
			'label'    => esc_html__( 'Button text', 'bricks' ) . ' (' . esc_html__( 'Cleared', 'bricksextras' ) . ')',
			'type'     => 'text',
			'inline'   => true,
			'required' => array( 'buttonType', '=', 'clear' ),
		);

		$this->controls['countButtonText'] = array(
			'tab'      => 'content',
			'label'    => esc_html__( 'Button text', 'bricks' ),
			'type'     => 'text',
			'inline'   => true,
			'required' => array( 'buttonType', '=', 'count' ),
		);

		$this->controls['link'] = array(
			'label'    => esc_html__( 'Link to', 'bricks' ),
			'type'     => 'link',
			'required' => array( 'buttonType', '=', 'count' ),
		);

		$this->controls['ariaLabel'] = array(
			'tab'         => 'content',
			'label'       => 'aria-label',
			'type'        => 'text',
			'inline'      => true,
			'placeholder' => '',
			'required'    => array( 'buttonType', '!=', array( 'remove', 'clear', 'count' ) ),
		);

		$this->controls['removeariaLabel'] = array(
			'tab'         => 'content',
			'label'       => 'aria-label',
			'type'        => 'text',
			'inline'      => true,
			'placeholder' => esc_html__( 'Remove item', 'bricksextras' ),
			'required'    => array( 'buttonType', '=', array( 'remove' ) ),
		);

		$this->controls['clearariaLabel'] = array(
			'tab'         => 'content',
			'label'       => 'aria-label',
			'type'        => 'text',
			'inline'      => true,
			'placeholder' => esc_html__( 'Clear all', 'bricks' ),
			'required'    => array( 'buttonType', '=', array( 'clear' ) ),
		);

		$this->controls['countariaLabel'] = array(
			'tab'         => 'content',
			'label'       => 'aria-label',
			'type'        => 'text',
			'inline'      => true,
			'placeholder' => esc_html__( 'Go to favorite', 'bricksextras' ),
			'required'    => array( 'buttonType', '=', array( 'count' ) ),
		);

		/*  icons */

		$this->controls['maybeIcons'] = array(
			'tab'         => 'content',
			'label'       => esc_html__( 'Icons', 'bricks' ),
			'type'        => 'select',
			'group'       => 'icons',
			'options'     => array(
				'enable'  => esc_html__( 'Enable', 'bricks' ),
				'disable' => esc_html__( 'Disable', 'bricks' ),
			),
			'inline'      => true,
			'clearable'   => false,
			'placeholder' => esc_html__( 'Enable', 'bricks' ),
		);

		$this->controls['addIcon'] = array(
			'tab'      => 'content',
			'label'    => esc_html__( 'Icon', 'bricks' ),
			'group'    => 'icons',
			'type'     => 'icon',
			'css'      => array(
				array(
					'selector' => '.x_favorite-removed-icon > *',
				),
			),
			'default'  => array(
				'library' => 'themify',
				'icon'    => 'ti-heart',
			),
			'required' => array(
				array( 'maybeIcons', '!=', 'disable' ),
				array( 'buttonType', '!=', array( 'remove', 'clear' ) ),
			),
		);

		$this->controls['removeIcon'] = array(
			'tab'      => 'content',
			'label'    => esc_html__( 'Icon', 'bricks' ) . ' (' . esc_html__( 'Remove', 'bricks' ) . ')',
			'group'    => 'icons',
			'type'     => 'icon',
			'css'      => array(
				array(
					'selector' => '.x_favorite-added-icon > *',
				),
				array(
					'selector' => '.x_favorite-clear-icon > *',
				),
			),
			'required' => array(
				array( 'maybeIcons', '!=', 'disable' ),
				array( 'buttonType', '!=', array( 'count' ) ),
			),
		);

		$this->controls['clearedIcon'] = array(
			'tab'      => 'content',
			'label'    => esc_html__( 'Icon', 'bricks' ) . ' (' . esc_html__( 'Cleared', 'bricksextras' ) . ')',
			'group'    => 'icons',
			'type'     => 'icon',
			'css'      => array(
				array(
					'selector' => '.x_favorite-cleared-icon > *',
				),
			),
			'required' => array(
				array( 'maybeIcons', '!=', 'disable' ),
				array( 'buttonType', '=', array( 'clear' ) ),
			),
		);

		$this->controls['iconSize'] = array(
			'tab'      => 'content',
			'group'    => 'icons',
			'type'     => 'number',
			'units'    => true,
			'label'    => esc_html__( 'Icon size', 'bricks' ),
			'css'      => array(
				array(
					'property' => 'font-size',
					'selector' => '.x-favorite_icons',
				),
			),
			'required' => array( 'maybeIcons', '!=', 'disable' ),
		);

		/* count */

		$count = '.x-favorite_count';

		$this->controls['hideIfZeroCount'] = array(
			'tab'         => 'content',
			'label'       => esc_html__( 'Hide if zero', 'bricksextras' ),
			'type'        => 'select',
			'group'       => 'count',
			'options'     => array(
				'enable'  => esc_html__( 'Enable', 'bricks' ),
				'disable' => esc_html__( 'Disable', 'bricks' ),
			),
			'inline'      => true,
			'clearable'   => false,
			'placeholder' => esc_html__( 'Disable', 'bricks' ),
		);

		$this->controls['countBackgroundColor'] = array(
			'tab'   => 'content',
			'group' => 'count',
			'type'  => 'color',
			'label' => esc_html__( 'Background', 'bricks' ),
			'css'   => array(
				array(
					'property' => 'background-color',
					'selector' => $count,
				),
			),
		);

		$this->controls['countTypography'] = array(
			'tab'      => 'content',
			'group'    => 'count',
			'type'     => 'typography',
			'label'    => esc_html__( 'Typography', 'bricks' ),
			'rerender' => false,
			'css'      => array(
				array(
					'property' => 'font',
					'selector' => $count,
				),
			),
		);

		$this->controls['countBorder'] = array(
			'tab'      => 'content',
			'group'    => 'count',
			'type'     => 'border',
			'rerender' => false,
			'label'    => esc_html__( 'Border', 'bricks' ),
			'css'      => array(
				array(
					'property' => 'border',
					'selector' => $count,
				),
			),
		);

		$this->controls['countBoxShadow'] = array(
			'tab'      => 'content',
			'group'    => 'count',
			'label'    => esc_html__( 'Box Shadow', 'bricks' ),
			'type'     => 'box-shadow',
			'rerender' => false,
			'css'      => array(
				array(
					'property' => 'box-shadow',
					'selector' => $count,
				),
			),
		);

		$this->controls['countSize'] = array(
			'tab'         => 'content',
			'group'       => 'count',
			'type'        => 'number',
			'units'       => true,
			'label'       => esc_html__( 'Size', 'bricks' ),
			'placeholder' => '2em',
			'css'         => array(
				array(
					'property' => 'height',
					'selector' => $count,
				),
				array(
					'property' => 'width',
					'selector' => $count,
				),
			),
		);

		$this->controls['countTop'] = array(
			'tab'         => 'content',
			'group'       => 'count',
			'type'        => 'number',
			'units'       => true,
			'placeholder' => '-1em',
			'label'       => esc_html__( 'Top', 'bricks' ),
			'css'         => array(
				array(
					'property' => 'top',
					'selector' => $count,
				),
			),
		);

		$this->controls['countRight'] = array(
			'tab'         => 'content',
			'group'       => 'count',
			'type'        => 'number',
			'placeholder' => '-1em',
			'units'       => true,
			'label'       => esc_html__( 'Right', 'bricks' ),
			'css'         => array(
				array(
					'property' => 'right',
					'selector' => $count,
				),
			),
		);

		$this->controls['countBottom'] = array(
			'tab'   => 'content',
			'group' => 'count',
			'type'  => 'number',
			'units' => true,
			'label' => esc_html__( 'Bottom', 'bricks' ),
			'css'   => array(
				array(
					'property' => 'bottom',
					'selector' => $count,
				),
			),
		);

		$this->controls['countLeft'] = array(
			'tab'   => 'content',
			'group' => 'count',
			'type'  => 'number',
			'units' => true,
			'label' => esc_html__( 'Left', 'bricks' ),
			'css'   => array(
				array(
					'property' => 'left',
					'selector' => $count,
				),
			),
		);

		/* tooltip */

		$this->controls['maybeToolip'] = array(
			'tab'         => 'content',
			'label'       => esc_html__( 'Enable', 'bricks' ),
			'type'        => 'select',
			'group'       => 'tooltip',
			'options'     => array(
				'enable'  => esc_html__( 'Enable', 'bricks' ),
				'disable' => esc_html__( 'Disable', 'bricks' ),
			),
			'inline'      => true,
			'clearable'   => false,
			'placeholder' => esc_html__( 'Disable', 'bricks' ),
		);

		$this->controls['addTooltipText'] = array(
			'tab'         => 'content',
			'group'       => 'tooltip',
			'label'       => esc_html__( 'Text', 'bricks' ),
			'type'        => 'text',
			'inline'      => true,
			'placeholder' => esc_html__( 'Add to favorites', 'bricksextras' ),
			'required'    => array(
				array( 'maybeToolip', '=', 'enable' ),
				array( 'buttonType', '!=', array( 'remove', 'clear' ) ),
			),
		);

		$this->controls['addedTooltipText'] = array(
			'tab'         => 'content',
			'group'       => 'tooltip',
			'label'       => esc_html__( 'Text', 'bricks' ) . ' (' . esc_html__( 'Added', 'bricks' ) . ')',
			'type'        => 'text',
			'inline'      => true,
			'placeholder' => esc_html__( 'Added to favorite', 'bricksextras' ),
			'required'    => array(
				array( 'maybeToolip', '=', 'enable' ),
				array( 'buttonType', '!=', array( 'remove', 'clear', 'count' ) ),
			),
		);

		$this->controls['maxReachedTooltipText'] = array(
			'tab'         => 'content',
			'group'       => 'tooltip',
			'label'       => esc_html__( 'Text (max. reached)', 'bricksextras' ),
			'type'        => 'text',
			'inline'      => true,
			'placeholder' => esc_html__( 'Maximum Reached', 'bricksextras' ),
			'required'    => array(
				array( 'maybeToolip', '=', 'enable' ),
				array( 'buttonType', '!=', array( 'remove', 'clear', 'count' ) ),
				array( 'listMaximum', '!=', '' ),
			),
		);

		$this->controls['removedTooltipText'] = array(
			'tab'         => 'content',
			'group'       => 'tooltip',
			'label'       => esc_html__( 'Text', 'bricks' ) . ' (' . esc_html__( 'Removed', 'bricks' ) . ')',
			'type'        => 'text',
			'inline'      => true,
			'placeholder' => esc_html__( 'Removed from favorites', 'bricksextras' ),
			'description' => esc_html__( '(touch devices)', 'bricksextras' ),
			'required'    => array(
				array( 'maybeToolip', '=', 'enable' ),
				array( 'buttonType', '!=', array( 'remove', 'clear', 'count' ) ),
			),
		);

		$this->controls['tooltipSep'] = array(
			'tab'   => 'content',
			'group' => 'tooltip',
			'type'  => 'separator',
		);

		$this->controls['removeTooltipText'] = array(
			'tab'         => 'content',
			'group'       => 'tooltip',
			'label'       => esc_html__( 'Text', 'bricks' ) . ' (' . esc_html__( 'Remove', 'bricks' ) . ')',
			'type'        => 'text',
			'inline'      => true,
			'placeholder' => esc_html__( 'Remove', 'bricksextras' ),
			'required'    => array(
				array( 'maybeToolip', '=', 'enable' ),
				array( 'buttonType', '=', 'remove' ),
			),
		);

		$this->controls['clearTooltipText'] = array(
			'tab'         => 'content',
			'group'       => 'tooltip',
			'label'       => esc_html__( 'Text', 'bricks' ) . ' (' . esc_html__( 'Clear', 'bricks' ) . ')',
			'type'        => 'text',
			'inline'      => true,
			'placeholder' => esc_html__( 'Clear all', 'bricksextras' ),
			'required'    => array(
				array( 'maybeToolip', '=', 'enable' ),
				array( 'buttonType', '=', 'clear' ),
			),
		);

		$this->controls['clearedTooltipText'] = array(
			'tab'         => 'content',
			'group'       => 'tooltip',
			'label'       => esc_html__( 'Text', 'bricks' ) . ' (' . esc_html__( 'Cleared', 'bricks' ) . ')',
			'type'        => 'text',
			'inline'      => true,
			'placeholder' => esc_html__( 'Cleared', 'bricksextras' ),
			'required'    => array(
				array( 'maybeToolip', '=', 'enable' ),
				array( 'buttonType', '=', 'clear' ),
			),
		);

		$this->controls['disabledText'] = array(
			'tab'         => 'content',
			'group'       => 'tooltip',
			'label'       => esc_html__( 'Text', 'bricks' ) . ' (' . esc_html__( 'Disabled', 'bricks' ) . ')',
			'type'        => 'text',
			'inline'      => true,
			'placeholder' => esc_html__( 'Login to enable', 'bricksextras' ),
			'required'    => array(
				array( 'maybeToolip', '=', 'enable' ),
				array( 'access', '!=', 'all' ),
			),
		);

		$this->controls['placement'] = array(
			'tab'         => 'content',
			'label'       => esc_html__( 'Preferred placement', 'bricksextras' ),
			'type'        => 'select',
			'group'       => 'tooltip',
			'options'     => array(
				'top'          => esc_html__( 'Top', 'bricks' ),
				'right'        => esc_html__( 'Right', 'bricks' ),
				'bottom'       => esc_html__( 'Bottom', 'bricks' ),
				'left'         => esc_html__( 'Left', 'bricks' ),
				'auto'         => esc_html__( 'Auto', 'bricks' ) . ' (' . esc_html__( 'Where there is enough space', 'bricksextras' ) . ')',
				'auto-start'   => esc_html__( 'Auto Start', 'bricksextras' ),
				'auto-end'     => esc_html__( 'Auto End', 'bricksextras' ),
				'top-start'    => esc_html__( 'Top Start', 'bricksextras' ),
				'top-end'      => esc_html__( 'Top End', 'bricksextras' ),
				'right-start'  => esc_html__( 'Right Start', 'bricksextras' ),
				'right-end'    => esc_html__( 'Right End', 'bricksextras' ),
				'bottom-start' => esc_html__( 'Bottom Start', 'bricksextras' ),
				'bottom-end'   => esc_html__( 'Bottom End', 'bricksextras' ),
				'left-start'   => esc_html__( 'Left Start', 'bricksextras' ),
				'left-end'     => esc_html__( 'Left End', 'bricksextras' ),
			),
			'placeholder' => esc_html__( 'Top', 'bricks' ),
			'clearable'   => false,
			'required'    => array( 'maybeToolip', '=', 'enable' ),
		);

		$this->controls['delay'] = array(
			'tab'         => 'content',
			'group'       => 'tooltip',
			'label'       => esc_html__( 'Delay', 'bricks' ) . ' (ms)',
			'type'        => 'number',
			'placeholder' => '0',
			'units'       => false,
			'small'       => true,
			'required'    => array( 'maybeToolip', '=', 'enable' ),
		);

		$this->controls['offsetSkidding'] = array(
			'tab'         => 'content',
			'group'       => 'tooltip',
			'label'       => esc_html__( 'Offset skidding', 'bricksextras' ) . '  (px)',
			'info'        => esc_html__( 'Distance along the side of the button', 'bricksextras' ),
			'type'        => 'number',
			'placeholder' => '0',
			'units'       => false,
			'small'       => true,
			'required'    => array( 'maybeToolip', '=', 'enable' ),
		);

		$this->controls['offsetDistance'] = array(
			'tab'         => 'content',
			'group'       => 'tooltip',
			'label'       => esc_html__( 'Offset distance', 'bricksextras' ) . '  (px)',
			'info'        => esc_html__( 'Distance away from the button', 'bricksextras' ),
			'type'        => 'number',
			'placeholder' => '10',
			'units'       => false,
			'small'       => true,
			'required'    => array( 'maybeToolip', '=', 'enable' ),
		);

		/*  popover style */

		$this->controls['tooltipStyleSep'] = array(
			'tab'      => 'content',
			'group'    => 'tooltip',
			'type'     => 'separator',
			'label'    => esc_html__( 'Styling', 'bricks' ),
			'required' => array( 'maybeToolip', '=', 'enable' ),
		);

		$popover = '.tippy-content';

		$this->controls['popoverWidth'] = array(
			'tab'      => 'content',
			'label'    => esc_html__( 'Width', 'bricks' ),
			'inline'   => true,
			'group'    => 'tooltip',
			'type'     => 'number',
			'units'    => true,
			'css'      => array(
				array(
					'selector' => $popover,
					'property' => 'width',
				),
			),
			'required' => array( 'maybeToolip', '=', 'enable' ),
		);

		$this->controls['popoverTypography'] = array(
			'tab'      => 'content',
			'group'    => 'tooltip',
			'type'     => 'typography',
			'label'    => esc_html__( 'Typography', 'bricks' ),
			'rerender' => false,
			'css'      => array(
				array(
					'property' => 'font',
					'selector' => $popover,
				),
			),
			'required' => array( 'maybeToolip', '=', 'enable' ),
		);

		$this->controls['popoverBackgroundColor'] = array(
			'tab'      => 'content',
			'group'    => 'tooltip',
			'type'     => 'color',
			'label'    => esc_html__( 'Background', 'bricks' ),
			'css'      => array(
				array(
					'property' => '--x-favorite-background',
					'selector' => '',
				),
			),
			'required' => array( 'maybeToolip', '=', 'enable' ),
		);

		$this->controls['popoverBorder'] = array(
			'tab'      => 'content',
			'group'    => 'tooltip',
			'type'     => 'border',
			'rerender' => false,
			'label'    => esc_html__( 'Border', 'bricks' ),
			'css'      => array(
				array(
					'property' => 'border',
					'selector' => $popover,
				),
			),
			'required' => array( 'maybeToolip', '=', 'enable' ),
		);

		$this->controls['popoverBoxShadow'] = array(
			'tab'      => 'content',
			'group'    => 'tooltip',
			'label'    => esc_html__( 'Box Shadow', 'bricks' ),
			'type'     => 'box-shadow',
			'rerender' => false,
			'css'      => array(
				array(
					'property' => 'box-shadow',
					'selector' => $popover,
				),
			),
			'required' => array( 'maybeToolip', '=', 'enable' ),
		);

		$popover_copied = '&:has(.x-favorite[aria-pressed="true"]) .tippy-content';

		$this->controls['popoverCopiedSep'] = array(
			'tab'      => 'content',
			'group'    => 'tooltip',
			'type'     => 'separator',
			'label'    => esc_html__( 'Styling', 'bricks' ) . ' (' . esc_html__( 'Added', 'bricks' ) . ')',
			'required' => array(
				array( 'maybeToolip', '=', 'enable' ),
				array( 'buttonType', '!=', array( 'remove', 'clear', 'count' ) ),
			),
		);

		$this->controls['popoverCopiedTypography'] = array(
			'tab'      => 'content',
			'group'    => 'tooltip',
			'type'     => 'typography',
			'label'    => esc_html__( 'Typography', 'bricks' ),
			'rerender' => false,
			'css'      => array(
				array(
					'property' => 'font',
					'selector' => $popover_copied,
				),
			),
			'required' => array(
				array( 'maybeToolip', '=', 'enable' ),
				array( 'buttonType', '!=', array( 'remove', 'clear', 'count' ) ),
			),
		);

		$this->controls['popoverCopiedBackgroundColor'] = array(
			'tab'      => 'content',
			'group'    => 'tooltip',
			'type'     => 'color',
			'label'    => esc_html__( 'Background', 'bricks' ),
			'css'      => array(
				array(
					'property' => '--x-favorite-background-active',
					'selector' => '',
				),
			),
			'required' => array(
				array( 'maybeToolip', '=', 'enable' ),
				array( 'buttonType', '!=', array( 'remove', 'clear', 'count' ) ),
			),
		);

		$this->controls['popoverCopiedBorder'] = array(
			'tab'      => 'content',
			'group'    => 'tooltip',
			'type'     => 'border',
			'rerender' => false,
			'label'    => esc_html__( 'Border', 'bricks' ),
			'css'      => array(
				array(
					'property' => 'border',
					'selector' => $popover_copied,
				),
			),
			'required' => array(
				array( 'maybeToolip', '=', 'enable' ),
				array( 'buttonType', '!=', array( 'remove', 'clear', 'count' ) ),
			),
		);

		$this->controls['popoverCopiedBoxShadow'] = array(
			'tab'      => 'content',
			'group'    => 'tooltip',
			'label'    => esc_html__( 'Box Shadow', 'bricks' ),
			'type'     => 'box-shadow',
			'rerender' => false,
			'css'      => array(
				array(
					'property' => 'box-shadow',
					'selector' => $popover_copied,
				),
			),
			'required' => array(
				array( 'maybeToolip', '=', 'enable' ),
				array( 'buttonType', '!=', array( 'remove', 'clear', 'count' ) ),
			),
		);

		$this->controls['popover_start'] = array(
			'tab'      => 'content',
			'group'    => 'tooltip',
			'type'     => 'separator',
			'required' => array( 'maybeToolip', '=', 'enable' ),
		);

		$this->controls['popoverPadding'] = array(
			'tab'      => 'content',
			'group'    => 'tooltip',
			'label'    => esc_html__( 'Padding', 'bricks' ),
			'type'     => 'spacing',
			'css'      => array(
				array(
					'property' => 'padding',
					'selector' => $popover,
				),
			),
			'required' => array( 'maybeToolip', '=', 'enable' ),
		);

		/* animation */

		$this->controls['popoverTransitionIn'] = array(
			'tab'         => 'content',
			'group'       => 'tooltip',
			'label'       => esc_html__( 'Transition', 'bricks' ) . ' (' . esc_html__( 'Show', 'bricks' ) . ')',
			'css'         => array(
				array(
					'property' => '--x-favorite-transitionin',
					'selector' => '',
				),
			),
			'type'        => 'number',
			'placeholder' => '300',
			'inline'      => true,
			'unit'        => 'ms',
			'required'    => array( 'maybeToolip', '=', 'enable' ),
		);

		$this->controls['popoverTransitionOut'] = array(
			'tab'         => 'content',
			'group'       => 'tooltip',
			'label'       => esc_html__( 'Transition', 'bricks' ) . ' (' . esc_html__( 'Hide', 'bricks' ) . ')',
			'css'         => array(
				array(
					'property' => '--x-favorite-transitionout',
					'selector' => '',
				),
			),
			'type'        => 'number',
			'placeholder' => '300',
			'unit'        => 'ms',
			'inline'      => true,
			'required'    => array( 'maybeToolip', '=', 'enable' ),
		);

		$this->controls['popoverTranslateX'] = array(
			'tab'         => 'content',
			'group'       => 'tooltip',
			'label'       => esc_html__( 'Translate X', 'bricks' ),
			'css'         => array(
				array(
					'property' => '--x-favorite-translatex',
					'selector' => '',
				),
			),
			'type'        => 'number',
			'placeholder' => '0',
			'inline'      => true,
			'units'       => array(
				'px' => array(
					'min'  => 1,
					'max'  => 1000,
					'step' => 1,
				),
			),
			'required'    => array( 'maybeToolip', '=', 'enable' ),
		);

		$this->controls['popoverTranslateY'] = array(
			'tab'         => 'content',
			'group'       => 'tooltip',
			'label'       => esc_html__( 'Translate Y', 'bricks' ),
			'css'         => array(
				array(
					'property' => '--x-favorite-translatey',
					'selector' => '',
				),
			),
			'type'        => 'number',
			'placeholder' => '10',
			'inline'      => true,
			'units'       => array(
				'px' => array(
					'min'  => 1,
					'max'  => 1000,
					'step' => 1,
				),
			),
			'required'    => array( 'maybeToolip', '=', 'enable' ),
		);

		$this->controls['popoverScale'] = array(
			'tab'         => 'content',
			'group'       => 'tooltip',
			'label'       => esc_html__( 'Scale', 'bricks' ),
			'css'         => array(
				array(
					'property' => '--x-favorite-scale',
					'selector' => '',
				),
			),
			'type'        => 'number',
			'placeholder' => '0.95',
			'inline'      => true,
			'required'    => array( 'maybeToolip', '=', 'enable' ),
		);

		/* button */

		$button = '.x-favorite';

		$this->controls['buttonWidth'] = array(
			'tab'   => 'content',
			'group' => 'button',
			'label' => esc_html__( 'Button width', 'bricks' ),
			'type'  => 'number',
			'units' => true,
			'css'   => array(
				array(
					'property' => 'width',
					'selector' => '.x-favorite_inner',
				),
			),
		);

		$this->controls['buttonTypography'] = array(
			'tab'   => 'content',
			'group' => 'button',
			'type'  => 'typography',
			'label' => esc_html__( 'Typography', 'bricks' ),
			'css'   => array(
				array(
					'property' => 'font',
					'selector' => $button,
				),
			),
		);

		$this->controls['buttonBackgroundColor'] = array(
			'tab'   => 'content',
			'group' => 'button',
			'type'  => 'color',
			'label' => esc_html__( 'Background', 'bricks' ),
			'css'   => array(
				array(
					'property' => 'background-color',
					'selector' => $button,
				),
			),
		);

		$this->controls['buttonBorder'] = array(
			'tab'   => 'content',
			'group' => 'button',
			'type'  => 'border',
			'label' => esc_html__( 'Border', 'bricks' ),
			'css'   => array(
				array(
					'property' => 'border',
					'selector' => $button,
				),
			),
		);

		$this->controls['buttonBoxShadow'] = array(
			'tab'   => 'content',
			'group' => 'button',
			'label' => esc_html__( 'Box Shadow', 'bricks' ),
			'type'  => 'box-shadow',
			'css'   => array(
				array(
					'property' => 'box-shadow',
					'selector' => $button,
				),
			),
		);

		/* added styles */

		$this->controls['buttonCopiedSep'] = array(
			'tab'      => 'content',
			'group'    => 'button',
			'type'     => 'separator',
			'label'    => esc_html__( 'Button', 'bricks' ) . ' (' . esc_html__( 'Added', 'bricks' ) . ')',
			'required' => array( 'buttonType', '!=', array( 'remove', 'clear', 'count' ) ),
		);

		$button_copied = '.x-favorite[aria-pressed=true]';

		$this->controls['buttonCopiedTypography'] = array(
			'tab'      => 'content',
			'group'    => 'button',
			'type'     => 'typography',
			'label'    => esc_html__( 'Typography', 'bricks' ),
			'css'      => array(
				array(
					'property' => 'font',
					'selector' => $button_copied,
				),
			),
			'required' => array( 'buttonType', '!=', array( 'remove', 'clear', 'count' ) ),
		);

		$this->controls['buttonCopiedBackgroundColor'] = array(
			'tab'      => 'content',
			'group'    => 'button',
			'type'     => 'color',
			'label'    => esc_html__( 'Background', 'bricks' ),
			'css'      => array(
				array(
					'property' => 'background-color',
					'selector' => $button_copied,
				),
			),
			'required' => array( 'buttonType', '!=', array( 'remove', 'clear', 'count' ) ),
		);

		$this->controls['buttonCopiedBorder'] = array(
			'tab'      => 'content',
			'group'    => 'button',
			'type'     => 'border',
			'label'    => esc_html__( 'Border', 'bricks' ),
			'css'      => array(
				array(
					'property' => 'border',
					'selector' => $button_copied,
				),
			),
			'required' => array( 'buttonType', '!=', array( 'remove', 'clear', 'count' ) ),
		);

		$this->controls['buttonCopiedBoxShadow'] = array(
			'tab'      => 'content',
			'group'    => 'button',
			'label'    => esc_html__( 'Box Shadow', 'bricks' ),
			'type'     => 'box-shadow',
			'css'      => array(
				array(
					'property' => 'box-shadow',
					'selector' => $button_copied,
				),
			),
			'required' => array( 'buttonType', '!=', array( 'remove', 'clear', 'count' ) ),
		);

		/* cleared styles */

		$this->controls['buttonClearedSep'] = array(
			'tab'      => 'content',
			'group'    => 'button',
			'type'     => 'separator',
			'label'    => esc_html__( "Button 'cleared' state", 'bricksextras' ),
			'required' => array( 'buttonType', '=', array( 'clear' ) ),
		);

		$button_cleared = '.x-favorite_cleared';

		$this->controls['buttonClearedTypography'] = array(
			'tab'      => 'content',
			'group'    => 'button',
			'type'     => 'typography',
			'label'    => esc_html__( 'Typography', 'bricks' ),
			'css'      => array(
				array(
					'property' => 'font',
					'selector' => $button_cleared,
				),
			),
			'required' => array( 'buttonType', '=', array( 'clear' ) ),
		);

		$this->controls['buttonClearedBackgroundColor'] = array(
			'tab'      => 'content',
			'group'    => 'button',
			'type'     => 'color',
			'label'    => esc_html__( 'Background', 'bricks' ),
			'css'      => array(
				array(
					'property' => 'background-color',
					'selector' => $button_cleared,
				),
			),
			'required' => array( 'buttonType', '=', array( 'clear' ) ),
		);

		$this->controls['buttonClearedBorder'] = array(
			'tab'      => 'content',
			'group'    => 'button',
			'type'     => 'border',
			'label'    => esc_html__( 'Border', 'bricks' ),
			'css'      => array(
				array(
					'property' => 'border',
					'selector' => $button_cleared,
				),
			),
			'required' => array( 'buttonType', '=', array( 'clear' ) ),
		);

		$this->controls['buttonClearedBoxShadow'] = array(
			'tab'      => 'content',
			'group'    => 'button',
			'label'    => esc_html__( 'Box Shadow', 'bricks' ),
			'type'     => 'box-shadow',
			'css'      => array(
				array(
					'property' => 'box-shadow',
					'selector' => $button_cleared,
				),
			),
			'required' => array( 'buttonType', '=', array( 'clear' ) ),
		);

		$this->controls['buttonTransition'] = array(
			'tab'            => 'content',
			'group'          => 'button',
			'label'          => esc_html__( 'Duration', 'bricks' ),
			'type'           => 'text',
			'css'            => array(
				array(
					'property' => '--x-favorite-duration',
					'selector' => $button,
				),
			),
			'inline'         => true,
			'hasDynamicData' => false,
			'placeholder'    => '300ms',

		);

		$this->controls['buttonPaddingSep'] = array(
			'tab'   => 'content',
			'group' => 'button',
			'type'  => 'separator',
		);

		$this->controls['buttonPadding'] = array(
			'tab'         => 'content',
			'group'       => 'button',
			'label'       => esc_html__( 'Padding', 'bricks' ),
			'type'        => 'spacing',
			'placeholder' => array(
				'top'    => '20px',
				'right'  => '20px',
				'bottom' => '20px',
				'left'   => '20px',
			),
			'css'         => array(
				array(
					'property' => 'padding',
					'selector' => $button,
				),
			),
		);

		$this->controls['buttonFlexSep'] = array(
			'tab'   => 'content',
			'group' => 'button',
			'type'  => 'separator',
		);

		$this->controls['buttonDirection'] = array(
			'tab'     => 'content',
			'label'   => esc_html__( 'Direction', 'bricks' ),
			'group'   => 'button',
			'tooltip' => array(
				'content'  => 'flex-direction',
				'position' => 'top-left',
			),
			'type'    => 'direction',
			'css'     => array(
				array(
					'property' => 'flex-direction',
					'selector' => $button,
				),
			),
			'inline'  => true,
		);

		$this->controls['buttonJustifyContent'] = array(
			'tab'     => 'content',
			'label'   => esc_html__( 'Align main axis', 'bricks' ),
			'group'   => 'button',
			'tooltip' => array(
				'content'  => 'justify-content',
				'position' => 'top-left',
			),
			'type'    => 'justify-content',
			'css'     => array(
				array(
					'property' => 'justify-content',
					'selector' => $button,
				),
			),
		);

		$this->controls['buttonAlignItems'] = array(
			'tab'     => 'content',
			'label'   => esc_html__( 'Align cross axis', 'bricks' ),
			'group'   => 'button',
			'tooltip' => array(
				'content'  => 'align-items',
				'position' => 'top-left',
			),
			'type'    => 'align-items',
			'css'     => array(
				array(
					'property' => 'align-items',
					'selector' => $button,
				),
			),
		);

		$this->controls['_columnGap'] = array(
			'tab'   => 'content',
			'label' => esc_html__( 'Column gap', 'bricks' ),
			'group' => 'button',
			'type'  => 'number',
			'units' => true,
			'css'   => array(
				array(
					'property' => 'column-gap',
					'selector' => $button,
				),
			),
		);

		$this->controls['buttonRowGap'] = array(
			'tab'   => 'content',
			'label' => esc_html__( 'Row gap', 'bricks' ),
			'group' => 'button',
			'type'  => 'number',
			'units' => true,
			'css'   => array(
				array(
					'property' => 'row-gap',
					'selector' => $button,
				),
			),
		);

		/* loading animation */

		$this->controls['loadingSep'] = array(
			'tab'   => 'content',
			'group' => 'animation',
			'type'  => 'separator',
			'label' => esc_html__( 'Spinner', 'bricks' ) . ' (' . esc_html__( 'Loading', 'bricks' ) . ')',
		);

		$this->controls['maybeSpinner'] = array(
			'tab'         => 'content',
			'group'       => 'animation',
			'type'        => 'select',
			'label'       => esc_html__( 'Enable', 'bricks' ),
			'options'     => array(
				'enable'  => esc_html__( 'Enable', 'bricks' ),
				'disable' => esc_html__( 'Disable', 'bricks' ),
			),
			'inline'      => true,
			'placeholder' => esc_html__( 'Enable', 'bricks' ),
		);

		$this->controls['spinnerPrev'] = array(
			'tab'      => 'content',
			'group'    => 'animation',
			'type'     => 'checkbox',
			'label'    => esc_html__( 'Preview', 'bricks' ),
			'required' => array( 'maybeSpinner', '!=', 'disable' ),
		);

		$this->controls['spinnerColor'] = array(
			'tab'      => 'content',
			'group'    => 'animation',
			'type'     => 'color',
			'label'    => esc_html__( 'Color', 'bricks' ),
			'css'      => array(
				array(
					'property' => 'color',
					'selector' => '&[data-x-spinner] .x-favorite_icons::before',
				),
				array(
					'property' => 'color',
					'selector' => '&[data-x-spinner] .x-favorite_text:only-child::before',
				),
			),
			'required' => array( 'maybeSpinner', '!=', 'disable' ),
		);

		$this->controls['spinnerTrackColor'] = array(
			'tab'      => 'content',
			'group'    => 'animation',
			'type'     => 'color',
			'label'    => esc_html__( 'Track color', 'bricks' ),
			'css'      => array(
				array(
					'property' => '--x-spinner-track-color',
					'selector' => '',
				),
			),
			'required' => array( 'maybeSpinner', '!=', 'disable' ),
		);

		$this->controls['spinnerStrokeWidth'] = array(
			'tab'         => 'content',
			'group'       => 'animation',
			'type'        => 'number',
			'placeholder' => '1px',
			'units'       => true,
			'label'       => esc_html__( 'Width', 'bricks' ),
			'css'         => array(
				array(
					'property' => '--x-spinner-stroke-width',
					'selector' => '',
				),
			),
			'required'    => array( 'maybeSpinner', '!=', 'disable' ),
		);

		$this->controls['spinnerSize'] = array(
			'tab'         => 'content',
			'group'       => 'animation',
			'type'        => 'number',
			'units'       => true,
			'placeholder' => '0.8em',
			'label'       => esc_html__( 'Size', 'bricks' ),
			'css'         => array(
				array(
					'property' => '--x-spinner-size',
					'selector' => '',
				),
			),
			'required'    => array( 'maybeSpinner', '!=', 'disable' ),
		);
	}

	/**
	 * Enqueue scripts.
	 */
	public function enqueue_scripts() {

		if ( bricks_is_builder_main() ) {
			return;
		}

		wp_enqueue_script( 'x-favorite', BRICKSEXTRAS_URL . 'components/assets/js/' . \BricksExtras\Helpers::maybe_minify_scripts( 'favorite' ) . '.js', array( 'bricks-scripts' ), \BricksExtras\Plugin::VERSION, true );

		if ( ! self::$script_localized ) {

			wp_localize_script(
				'x-favorite',
				'xFavoriteObject',
				array(
					'ajaxurl' => admin_url( 'admin-ajax.php' ),
					'sec'     => wp_create_nonce( 'favorite_nonce' ),
					'user'    => is_user_logged_in() ? 'true' : 'false',
				)
			);

			if ( ! BricksExtras\Helpers::maybe_preview() ) {

				wp_enqueue_script( 'x-popper', BRICKSEXTRAS_URL . 'components/assets/js/' . \BricksExtras\Helpers::maybe_minify_scripts( 'popper' ) . '.js', array( 'bricks-scripts' ), \BricksExtras\Plugin::VERSION, true );
				wp_enqueue_script( 'x-favorite-popover', BRICKSEXTRAS_URL . 'components/assets/js/' . \BricksExtras\Helpers::maybe_minify_scripts( 'favoritepopover' ) . '.js', array( 'x-popper', 'x-favorite' ), \BricksExtras\Plugin::VERSION, true );

				wp_localize_script(
					'x-favorite-popover',
					'xFavoriteTippy',
					array(
						'Instances' => array(),
					)
				);

			}

			self::$script_localized = true;

		}

		if ( ! \BricksExtras\Helpers::element_css_added( $this->name ) ) {
			wp_enqueue_style( 'x-favorite', BRICKSEXTRAS_URL . 'components/assets/css/favorite.css', array(), \BricksExtras\Plugin::VERSION );
		}
	}

	/**
	 * Render element output.
	 */
	public function render() {

		\BricksExtras\Favorite::check_and_sync_favorites();

		$settings = $this->settings;

		$access      = isset( $settings['access'] ) ? esc_attr( $settings['access'] ) : 'logged_in';
		$button_type = isset( $settings['buttonType'] ) ? esc_attr( $settings['buttonType'] ) : 'add_remove';

		$maybe_icons  = isset( $settings['maybeIcons'] ) ? 'enable' === $settings['maybeIcons'] : true;
		$add_icon     = empty( $this->settings['addIcon'] ) ? false : self::render_icon( $this->settings['addIcon'] );
		$cleared_icon = empty( $this->settings['clearedIcon'] ) ? false : self::render_icon( $this->settings['clearedIcon'] );
		$remove_icon  = empty( $this->settings['removeIcon'] ) ? false : self::render_icon( $this->settings['removeIcon'] );

		if ( ! $add_icon ) {
			$add_icon = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--!Font Awesome Free 6.6.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--><path d="M458.4 64.3C400.6 15.7 311.3 23 256 79.3 200.7 23 111.4 15.6 53.6 64.3-21.6 127.6-10.6 230.8 43 285.5l175.4 178.7c10 10.2 23.4 15.9 37.6 15.9 14.3 0 27.6-5.6 37.6-15.8L469 285.6c53.5-54.7 64.7-157.9-10.6-221.3zm-23.6 187.5L259.4 430.5c-2.4 2.4-4.4 2.4-6.8 0L77.2 251.8c-36.5-37.2-43.9-107.6 7.3-150.7 38.9-32.7 98.9-27.8 136.5 10.5l35 35.7 35-35.7c37.8-38.5 97.8-43.2 136.5-10.6 51.1 43.1 43.5 113.9 7.3 150.8z"/></svg>';
		}

		if ( ! $remove_icon ) {
			$remove_icon = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--!Font Awesome Free 6.6.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--><path d="M462.3 62.6C407.5 15.9 326 24.3 275.7 76.2L256 96.5l-19.7-20.3C186.1 24.3 104.5 15.9 49.7 62.6c-62.8 53.6-66.1 149.8-9.9 207.9l193.5 199.8c12.5 12.9 32.8 12.9 45.3 0l193.5-199.8c56.3-58.1 53-154.3-9.8-207.9z"/></svg>';

			if ( 'remove' === $button_type || 'clear' === $button_type ) {
				$remove_icon = '<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 512 512"><path d="M405 136.798L375.202 107 256 226.202 136.798 107 107 136.798 226.202 256 107 375.202 136.798 405 256 285.798 375.202 405 405 375.202 285.798 256z" fill="currentColor"></path></svg>';
			}
		}

		if ( ! $cleared_icon ) {
			$cleared_icon = '<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 512 512"><path d="M405 136.798L375.202 107 256 226.202 136.798 107 107 136.798 226.202 256 107 375.202 136.798 405 256 285.798 375.202 405 405 375.202 285.798 256z" fill="currentColor"></path></svg>';
		}

		$add_button_text         = isset( $settings['addButtonText'] ) ? wp_kses_post( bricks_render_dynamic_data( $settings['addButtonText'] ) ) : false;
		$added_button_text       = isset( $settings['addedButtonText'] ) ? wp_kses_post( bricks_render_dynamic_data( $settings['addedButtonText'] ) ) : false;
		$remove_button_text      = isset( $settings['removeButtonText'] ) ? wp_kses_post( bricks_render_dynamic_data( $settings['removeButtonText'] ) ) : false;
		$max_reached_button_text = isset( $settings['maxReachedButtonText'] ) ? wp_kses_post( bricks_render_dynamic_data( $settings['maxReachedButtonText'] ) ) : false;

		$count_button_text = isset( $settings['countButtonText'] ) ? esc_attr( bricks_render_dynamic_data( $settings['countButtonText'] ) ) : false;

		$aria_label        = isset( $settings['ariaLabel'] ) ? esc_attr( bricks_render_dynamic_data( $settings['ariaLabel'] ) ) : esc_attr__( 'Add item to favorite', 'bricksextras' );
		$remove_aria_label = isset( $settings['removeariaLabel'] ) ? esc_attr( bricks_render_dynamic_data( $settings['removeariaLabel'] ) ) : esc_attr__( 'Remove item', 'bricksextras' );
		$clear_aria_label  = isset( $settings['clearariaLabel'] ) ? esc_attr( bricks_render_dynamic_data( $settings['clearariaLabel'] ) ) : esc_attr__( 'Clear all', 'bricks' );
		$count_aria_label  = isset( $settings['countariaLabel'] ) ? esc_attr( bricks_render_dynamic_data( $settings['countariaLabel'] ) ) : esc_attr__( 'Go to favorite', 'bricksextras' );

		$maybe_tooltip = isset( $settings['maybeToolip'] ) ? 'enable' === $settings['maybeToolip'] : false;

		$added_tooltip_text   = isset( $settings['addedTooltipText'] ) ? wp_kses_post( bricks_render_dynamic_data( $this->settings['addedTooltipText'] ) ) : esc_attr__( 'Added to favorites', 'bricksextras' );
		$removed_tooltip_text = isset( $settings['removedTooltipText'] ) ? wp_kses_post( bricks_render_dynamic_data( $this->settings['removedTooltipText'] ) ) : esc_attr__( 'Removed from favorites', 'bricksextras' );
		$add_tooltip_text     = isset( $settings['addTooltipText'] ) ? wp_kses_post( bricks_render_dynamic_data( $this->settings['addTooltipText'] ) ) : esc_attr__( 'Add to favorites', 'bricksextras' );
		$disabled_text        = isset( $settings['disabledText'] ) ? wp_kses_post( bricks_render_dynamic_data( $this->settings['disabledText'] ) ) : esc_attr__( 'Login to enable ', 'bricksextras' );
		$remove_tooltip_text  = isset( $settings['removeTooltipText'] ) ? wp_kses_post( bricks_render_dynamic_data( $this->settings['removeTooltipText'] ) ) : esc_attr__( 'Remove', 'bricksextras' );

		$clear_tooltip_text   = isset( $settings['clearTooltipText'] ) ? wp_kses_post( bricks_render_dynamic_data( $this->settings['clearTooltipText'] ) ) : esc_attr__( 'Clear all', 'bricksextras' );
		$cleared_tooltip_text = isset( $settings['clearedTooltipText'] ) ? wp_kses_post( bricks_render_dynamic_data( $this->settings['clearedTooltipText'] ) ) : esc_attr__( 'Cleared', 'bricksextras' );

		$clear_button_text   = isset( $settings['clearButtonText'] ) ? wp_kses_post( bricks_render_dynamic_data( $settings['clearButtonText'] ) ) : esc_attr__( 'Clear all', 'bricksextras' );
		$cleared_button_text = isset( $settings['clearedButtonText'] ) ? wp_kses_post( bricks_render_dynamic_data( $settings['clearedButtonText'] ) ) : '';

		$tooltip_show = isset( $settings['tooltipShow'] ) ? esc_attr( $settings['tooltipShow'] ) : 'hocus';

		$max_reached_tooltip_text = isset( $this->settings['maxReachedTooltipText'] ) ? wp_kses_post( bricks_render_dynamic_data( $this->settings['maxReachedTooltipText'] ) ) : esc_attr__( 'Maximum Reached', 'bricksextras' );

		$maybe_spinner = isset( $settings['maybeSpinner'] ) ? 'enable' === $settings['maybeSpinner'] : true;

		$hide_if_zero_count = isset( $settings['hideIfZeroCount'] ) ? 'enable' === $settings['hideIfZeroCount'] : false;

		if ( 'hocus' === $tooltip_show ) {
			$tooltip_reveal = 'mouseenter click focus';
		} else {
			$tooltip_reveal = 'manual';
		}

		$config = array();

		$post_type    = isset( $settings['postType'] ) ? esc_attr( $settings['postType'] ) : 'default';
		$list_slug    = isset( $settings['newList'] ) && isset( $settings['listSlug'] ) ? bricks_render_dynamic_data( $settings['listSlug'] ) : false;
		$list_maximum = isset( $settings['listMaximum'] ) ? $settings['listMaximum'] : false;

		if ( (bool) $list_maximum ) {
			$this->set_attribute( '_root', 'data-x-list-max', intval( $list_maximum ) );

			if ( 'add_remove' === $button_type && $max_reached_button_text ) {
				$config += array( 'maxReachedText' => $max_reached_button_text );
			}
		}

		if ( 'default' === $post_type ) {

			if ( method_exists( '\Bricks\Query', 'is_any_looping' ) && \Bricks\Query::is_any_looping() ) {

				if ( \Bricks\Query::is_any_looping() && \Bricks\Query::get_loop_object() ) {
					$post_type = get_post_type( \Bricks\Query::get_loop_object() );
				}
			} else {
					$post_type = 'post';
			}
		}

		if ( (bool) $list_slug && isset( $settings['newList'] ) ) {

			$list_slug = strtolower( $list_slug );                     // Convert to lowercase.
			$list_slug = preg_replace( '/\s+/', '_', $list_slug );      // Replace spaces with underscores.
			$suffix    = preg_replace( '/[^a-z0-9_]/', '', $list_slug );    // Remove characters that are not letters, numbers, or underscores.

			$list_name = $post_type . '__' . $suffix;

		} else {
			$list_name = $post_type;
		}

		$this->set_attribute( '_root', 'data-x-list', esc_attr( $list_name ) );

		$this->set_attribute( '_root', 'data-x-type', esc_attr( $button_type ) );

		if ( $maybe_spinner ) {
			$this->set_attribute( '_root', 'data-x-spinner', 'true' );
		}

		if ( $maybe_tooltip ) {
			$config += array(
				'placement'             => isset( $this->settings['placement'] ) ? esc_attr( $this->settings['placement'] ) : 'top',
				'offsetSkidding'        => isset( $this->settings['offsetSkidding'] ) ? intval( $this->settings['offsetSkidding'] ) : 0,
				'offsetDistance'        => isset( $this->settings['offsetDistance'] ) ? intval( $this->settings['offsetDistance'] ) : 10,
				'delay'                 => isset( $this->settings['delay'] ) ? intval( $this->settings['delay'] ) : 0,
				'followCursor'          => isset( $this->settings['followCursor'] ) ? $this->settings['followCursor'] : 'false',
				'tooltipAddedText'      => $added_tooltip_text,
				'removedTooltipText'    => $removed_tooltip_text,
				'removedText'           => $add_tooltip_text,
				'removeTooltipText'     => $remove_tooltip_text,
				'tooltipReveal'         => $tooltip_reveal,
				'clearTooltipText'      => $clear_tooltip_text,
				'clearedTooltipText'    => $cleared_tooltip_text,
				'maxReachedTooltipText' => $max_reached_tooltip_text,
			);
		}

		if ( $add_button_text && 'add_remove' === $button_type ) {
			$config += array( 'addText' => $add_button_text );
		}

		if ( $added_button_text && 'remove' !== $button_type ) {
			$config += array( 'addedText' => $added_button_text );
		}

		if ( 'clear' === $button_type ) {
			if ( $clear_button_text ) {
				$config += array( 'clearText' => $clear_button_text );
			}
			if ( $cleared_button_text ) {
				$config += array( 'clearedText' => $cleared_button_text );
			}
		}

		if ( 'count' === $button_type && $hide_if_zero_count ) {
			$config += array( 'hideZero' => 'true' );
		}

		if ( \BricksExtras\Helpers::get_parent_loop_id( $this->element ) ) {
			$config += array( 'isLooping' => \BricksExtras\Helpers::get_parent_loop_id( $this->element ) );
		}

		if ( \BricksExtras\Helpers::get_parent_loop_id( $this->element, true ) ) {
			$config += array( 'isLoopingComponent' => \BricksExtras\Helpers::get_parent_loop_id( $this->element, true ) );
		}

		// Generate and set a unique identifier for this instance.
		$unique_id = \BricksExtras\Helpers::set_identifier_attribute( $this );

		if ( 'logged_in' === $access && ! is_user_logged_in() ) {
			$this->set_attribute( 'x-favorite', 'disabled', '' );
			$this->set_attribute( 'x-favorite', 'data-disabled', '' );

			$config += array( 'disabledText' => htmlspecialchars( $disabled_text, ENT_QUOTES, 'UTF-8' ) );
		}

		$this->set_attribute( '_root', 'data-x-favorite', wp_json_encode( $config ) );

		$tag = 'count' === $button_type ? 'span' : 'button';

		$link = ! empty( $settings['link'] ) ? $settings['link'] : '';

		if ( $link ) {
			$tag = 'a';
		}

		$in_favorite = false;

		if ( 'count' !== $button_type ) {

			$post_id = intval( get_the_ID() );

			if ( $post_id ) {

				$x_favorite_ids = array();

				$this->set_attribute( '_root', 'data-post-id', intval( get_the_ID() ) );

				if ( ! is_user_logged_in() ) {

					if ( isset( $_COOKIE[ 'x_favorite_ids__' . $list_name ] ) ) {
						$cookie_data    = \BricksExtras\Helpers::get_cookie_value( 'x_favorite_ids__' . $list_name );
						$x_favorite_ids = json_decode( $cookie_data, true );

						if ( is_array( $x_favorite_ids ) ) {
							$x_favorite_ids = array_map( 'absint', $x_favorite_ids );

							if ( in_array( $post_id, $x_favorite_ids, true ) ) {
									$in_favorite = true;
							}
						}
					}
				} else {

					global $x_favorite_data_global;

					if ( $x_favorite_data_global && is_array( $x_favorite_data_global ) ) {
						if ( isset( $x_favorite_data_global[ $list_name ] ) && in_array( $post_id, $x_favorite_data_global[ $list_name ], true ) ) {
							$in_favorite = true;
						}
					}
				}
			}
		} elseif ( $link ) {

			$this->set_link_attributes( 'x-favorite', $link );
		}

		if ( $maybe_tooltip ) {
			$this->set_attribute( '_root', 'data-x-tooltip', 'true' );
		}

		$this->set_attribute( 'x-favorite', 'class', 'x-favorite' );

		if ( 'add_remove' === $button_type ) {

			$this->set_attribute( 'x_favorite-added-icon', 'class', 'x_favorite-added-icon' );

			$this->set_attribute( 'x_favorite-icon', 'class', 'x_favorite-removed-icon' );

			if ( $in_favorite ) {

				$this->set_attribute( 'x-favorite', 'class', 'x-favorite_added' );
				$this->set_attribute( 'x-favorite', 'aria-pressed', 'true' );

			} else {
				$this->set_attribute( 'x-favorite', 'aria-pressed', 'false' );
			}
		} elseif ( 'remove' === $button_type || 'clear' === $button_type ) {

				$this->set_attribute( 'x-favorite', 'aria-pressed', 'false' );
		}

		if ( isset( $settings['spinnerPrev'] ) && BricksExtras\Helpers::maybe_preview() ) {
			$this->set_attribute( 'x-favorite', 'class', 'x-favorite_busy' );
		}

		if ( 'clear' === $button_type ) {

			$this->set_attribute( 'x_favorite-added-icon', 'class', 'x_favorite-clear-icon' );
			$this->set_attribute( 'x_favorite-icon', 'class', 'x_favorite-cleared-icon' );

		}

		/* aria labels */
		if ( 'add_remove' === $button_type ) {
			$this->set_attribute( 'x-favorite', 'aria-label', $aria_label );
		} elseif ( 'remove' === $button_type ) {
			$this->set_attribute( 'x-favorite', 'aria-label', $remove_aria_label );
		} elseif ( 'clear' === $button_type ) {
			$this->set_attribute( 'x-favorite', 'aria-label', $clear_aria_label );
		} elseif ( 'count' === $button_type && $link ) {
			$this->set_attribute( 'x-favorite', 'aria-label', $count_aria_label );
		}

		$this->set_attribute( 'x-favorite-tooltip-content', 'id', esc_attr( 'x-favorite-tooltip-content_' . $unique_id ) );

		$this->set_attribute( 'x_favorite-icon', 'class', 'x-favorite_icon' );
		$this->set_attribute( 'x_favorite-icon', 'aria-hidden', 'true' );

		$this->set_attribute( 'x_favorite-added-icon', 'class', 'x-favorite_icon' );
		$this->set_attribute( 'x_favorite-added-icon', 'aria-hidden', 'true' );

		$this->set_attribute( 'x-favorite_icons', 'class', 'x-favorite_icons' );

		$this->set_attribute( 'x-favorite_count', 'class', 'x-favorite_count' );
		$this->set_attribute( 'x-favorite_count-inner', 'class', 'x-favorite_count-inner' );

		$this->set_attribute( 'x-favorite-tooltip-content', 'class', array( 'x-favorite-tooltip-content' ) );
		$this->set_attribute( 'x-favorite-tooltip-content', 'role', array( 'tooltip' ) );

		$this->set_attribute( 'tippy-content', 'class', array( 'tippy-content' ) );
		$this->set_attribute( 'tippy-content', 'data-state', array( 'visible' ) );

		$this->set_attribute( 'tippy-root', 'data-tippy-root', '' );

		$this->set_attribute( 'tippy-box', 'class', 'tippy-box' );
		$this->set_attribute( 'tippy-box', 'data-state', 'visible' );
		$this->set_attribute( 'tippy-box', 'tabindex', '1' );
		$this->set_attribute( 'tippy-box', 'data-theme', 'extras' );
		$this->set_attribute( 'tippy-box', 'data-animation', 'extras' );

		$this->set_attribute( 'x-favorite_text', 'class', 'x-favorite_text' );

		$this->set_attribute( 'x-favorite_text-inner', 'class', 'x-favorite_text-inner' );

		$output = '';

		$output .= "<div {$this->render_attributes( '_root' )}>";

		$output .= '<' . $tag . " {$this->render_attributes( 'x-favorite' )}>";

		if ( isset( $settings['addButtonText'] ) && $settings['addButtonText'] && 'add_remove' === $button_type ) {
			if ( isset( $settings['addedButtonText'] ) && $settings['addedButtonText'] && ( $in_favorite || ( 'remove' === $button_type || 'clear' === $button_type ) ) ) {
				$output .= "<span {$this->render_attributes( 'x-favorite_text' )}><span {$this->render_attributes( 'x-favorite_text-inner' )}>" . wp_kses_post( $settings['addedButtonText'] ) . '</span></span>';
			} else {
				$output .= "<span {$this->render_attributes( 'x-favorite_text' )}><span {$this->render_attributes( 'x-favorite_text-inner' )}>" . wp_kses_post( $settings['addButtonText'] ) . '</span></span>';
			}
		}

		if ( isset( $settings['removeButtonText'] ) && $settings['removeButtonText'] && 'remove' === $button_type ) {
			$output .= "<span {$this->render_attributes( 'x-favorite_text' )}><span {$this->render_attributes( 'x-favorite_text-inner' )}>" . wp_kses_post( $settings['removeButtonText'] ) . '</span></span>';
		}

		if ( isset( $settings['clearButtonText'] ) && $settings['clearButtonText'] && 'clear' === $button_type ) {
			$output .= "<span {$this->render_attributes( 'x-favorite_text' )}><span {$this->render_attributes( 'x-favorite_text-inner' )}>" . wp_kses_post( $settings['clearButtonText'] ) . '</span></span>';
		}

		if ( isset( $settings['countButtonText'] ) && $settings['countButtonText'] && 'count' === $button_type ) {
			$output .= "<span {$this->render_attributes( 'x-favorite_text' )}><span {$this->render_attributes( 'x-favorite_text-inner' )}>" . wp_kses_post( $settings['countButtonText'] ) . '</span></span>';
		}

		$output .= \Bricks\Frontend::render_children( $this );

		if ( $maybe_icons ) {
			$output .= "<span {$this->render_attributes( 'x-favorite_icons' )}>";
			if ( 'add_remove' === $button_type || 'clear' === $button_type || 'remove' === $button_type ) {
				$output .= "<span {$this->render_attributes( 'x_favorite-added-icon' )}> " . $remove_icon . ' </span>';
			}
			if ( 'add_remove' === $button_type || 'count' === $button_type ) {
				$output .= "<span {$this->render_attributes( 'x_favorite-icon' )}> " . $add_icon . '  </span>';
			}
			if ( 'clear' === $button_type ) {
				$output .= "<span {$this->render_attributes( 'x_favorite-icon' )}> " . $cleared_icon . '  </span>';
			}
			$output .= '</span>';
		}

		$output .= '</' . $tag . '>';

		if ( BricksExtras\Helpers::maybe_preview() ) {
			$output .= "<div {$this->render_attributes( 'x-favorite-tooltip-content' )}>";
			$output .= "<div {$this->render_attributes( 'tippy-root' )}>";
			$output .= "<div {$this->render_attributes( 'tippy-box' )}>";
			$output .= "<div {$this->render_attributes( 'tippy-content' )}>";
			if ( isset( $settings['addedTooltipText'] ) && $settings['addedTooltipText'] ) {
				$output .= "<div {$this->render_attributes( 'x-favorite-tooltip-content-inner' )}>" . wp_kses_post( $settings['addedTooltipText'] ) . '</div>';
			} else {
				$output .= "<div {$this->render_attributes( 'x-favorite-tooltip-content-inner' )}>" . esc_html__( 'Added to favorites', 'bricksextras' ) . '</div>';
			}
			$output .= '</div>';
			$output .= '</div>';
			$output .= '</div>';
			$output .= '</div>';
		}

		if ( 'count' === $button_type ) {

			if ( isset( $_COOKIE['x_favorite_ids'] ) ) {

				// Get favorite data from cookie.
				$post_array = \BricksExtras\Helpers::get_favorite_ids_array( $post_type );
				$count      = is_array( $post_array ) && is_user_logged_in() ? count( $post_array ) : 0;

			} else {
				$count = 0;
			}

			if ( ( 0 === $count ) && $hide_if_zero_count ) {
				$this->set_attribute( 'x-favorite_count', 'class', 'x-favorite_count-zero' );
			}

			$output .= "<span {$this->render_attributes( 'x-favorite_count' )}><span {$this->render_attributes( 'x-favorite_count-inner' )}>" . intval( $count ) . '</span></span>';

		}

		$output .= '</div>';

		echo $output;

		if ( $maybe_tooltip && ! BricksExtras\Helpers::maybe_preview() ) {

			wp_enqueue_script( 'x-popper', BRICKSEXTRAS_URL . 'components/assets/js/' . \BricksExtras\Helpers::maybe_minify_scripts( 'popper' ) . '.js', array( 'bricks-scripts' ), '1.0.0', true );
			wp_enqueue_script( 'x-favorite-popover', BRICKSEXTRAS_URL . 'components/assets/js/favoritepopover.js', array( 'x-popper', 'x-favorite' ), '1.0.5', true );

			wp_localize_script(
				'x-favorite-popover',
				'xFavoriteTippy',
				array(
					'Instances' => array(),
				)
			);

		}
	}
}
