<?php
/**
 * Image Hotspot Marker element.
 *
 * @package BricksExtras
 */

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

/**
 * Image Hotspot Marker element class.
 */
class X_Image_Hotspot_Marker extends \Bricks\Element {

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

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

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

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

	/**
	 * Required scripts.
	 *
	 * @var array
	 */
	public $scripts = array( 'xImageHotspots' );

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

	/**
	 * Get element label.
	 *
	 * @return string
	 */
	public function get_label() {
		return esc_html__( 'Image Hotspot Marker', 'bricksextras' );
	}

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

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

		$this->control_groups['icon'] = array(
			'title' => esc_html__( 'Icon', 'bricks' ) . ' / ' . esc_html__( 'Image', 'bricks' ),
			'tab'   => 'content',
		);

		$this->control_groups['markers'] = array(
			'title' => esc_html__( 'Marker style', 'bricksextras' ),
			'tab'   => 'content',
		);

		$this->control_groups['popover'] = array(
			'title' => esc_html__( 'Popover style', 'bricksextras' ),
			'tab'   => 'content',
		);

		$this->control_groups['behaviour'] = array(
			'title' => esc_html__( 'Behavior', 'bricksextras' ),
			'tab'   => 'content',
		);

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

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

		$this->controls['info'] = array(
			'tab'         => 'content',
			'type'        => 'separator',
			'description' => esc_html__( 'This element must be placed inside of an Image Hotspot element.', 'bricksextras' ),
		);

		// Position.
		$this->controls['position_x'] = array(
			'tab'         => 'content',
			'inline'      => true,
			'label'       => esc_html__( 'Position', 'bricks' ) . ' (X)',
			'type'        => 'text',
			'placeholder' => esc_html__( '0%', 'bricksextras' ),
		);

		$this->controls['position_y'] = array(
			'tab'         => 'content',
			'inline'      => true,
			'label'       => esc_html__( 'Position', 'bricks' ) . ' (Y)',
			'type'        => 'text',
			'placeholder' => esc_html__( '0%', 'bricksextras' ),
		);

		// Marker text.
		$this->controls['title'] = array(
			'tab'    => 'content',
			'label'  => esc_html__( 'Button text', 'bricks' ),
			'inline' => true,
			'type'   => 'text',
		);

		// Link.
		$this->controls['link'] = array(
			'tab'      => 'content',
			'label'    => esc_html__( 'Link', 'bricks' ),
			'type'     => 'link',
			'required' => array( 'markerType', '=', array( 'link', 'both' ) ),
		);

		// Aria label.
		$this->controls['aria_label'] = array(
			'tab'         => 'content',
			'inline'      => true,
			'label'       => 'aria-label',
			'type'        => 'text',
			'placeholder' => esc_html__( 'Toggle popover', 'bricksextras' ),
		);

		// Marker type.
		$this->controls['markerType'] = array(
			'tab'         => 'content',
			'inline'      => true,
			'label'       => esc_html__( 'Action', 'bricks' ),
			'type'        => 'text',
			'info'        => 'popover | link | both',
			'placeholder' => esc_html__( 'popover', 'bricksextras' ),
		);

		$marker       = '.x-marker_marker';
		$marker_inner = '.x-marker_marker .x-marker_marker-inner';

		$this->controls['markerIconSep'] = array(
			'tab'   => 'content',
			'label' => esc_html__( 'Icon', 'bricks' ),
			'type'  => 'separator',
			'group' => 'icon',
		);

		$this->controls['icon'] = array(
			'tab'     => 'content',
			'label'   => esc_html__( 'Icon', 'bricks' ),
			'type'    => 'icon',
			'default' => array(
				'icon'    => 'ion-ios-pin',
				'library' => 'ionicons',
			),
			'css'     => array(
				array(
					'selector' => $marker_inner . '> *:not(.x-marker_marker-title)',
				),
			),
			'group'   => 'icon',
		);

		$this->controls['iconColor'] = array(
			'tab'   => 'content',
			'label' => esc_html__( 'Icon color', 'bricks' ),
			'type'  => 'color',
			'css'   => array(
				array(
					'property' => 'color',
					'selector' => $marker_inner . '> *:not(.x-marker_marker-title)',
				),
			),
			'group' => 'icon',
		);

		$this->controls['iconSize'] = array(
			'tab'   => 'content',
			'label' => esc_html__( 'Icon size', 'bricks' ),
			'type'  => 'number',
			'units' => true,
			'css'   => array(
				array(
					'property' => 'font-size',
					'selector' => $marker_inner . '> *:not(.x-marker_marker-title)',
				),
			),
			'group' => 'icon',
		);

		// Marker Image.
		$this->controls['markerImage'] = array(
			'tab'   => 'content',
			'label' => esc_html__( 'Image', 'bricks' ),
			'type'  => 'image',
			'group' => 'icon',
		);

		$this->controls['markerImageAltText'] = array(
			'tab'      => 'content',
			'group'    => 'icon',
			'label'    => esc_html__( 'Custom alt text', 'bricks' ),
			'type'     => 'text',
			'required' => array( 'markerImage', '!=', '' ),
		);

		$this->controls['imageWidth'] = array(
			'tab'      => 'content',
			'group'    => 'icon',
			'label'    => esc_html__( 'Image width', 'bricks' ),
			'type'     => 'number',
			'units'    => true,
			'css'      => array(
				array(
					'property' => 'width',
					'selector' => $marker_inner . ' .x-hotspots_marker-image',
				),
			),
			'required' => array( 'markerImage', '!=', '' ),
		);

		$this->controls['imageHeight'] = array(
			'tab'      => 'content',
			'group'    => 'icon',
			'label'    => esc_html__( 'Image height', 'bricks' ),
			'type'     => 'number',
			'units'    => true,
			'css'      => array(
				array(
					'property' => 'height',
					'selector' => $marker_inner . ' .x-hotspots_marker-image',
				),
			),
			'required' => array( 'markerImage', '!=', '' ),
		);

		$this->controls['imageObjectFit'] = array(
			'tab'      => 'content',
			'group'    => 'icon',
			'label'    => esc_html__( 'Object fit', 'bricks' ),
			'type'     => 'select',
			'inline'   => true,
			'options'  => array(
				'fill'       => esc_html__( 'Fill', 'bricks' ),
				'contain'    => esc_html__( 'Contain', 'bricks' ),
				'cover'      => esc_html__( 'Cover', 'bricks' ),
				'none'       => esc_html__( 'None', 'bricks' ),
				'scale-down' => esc_html__( 'Scale down', 'bricks' ),
			),
			'css'      => array(
				array(
					'property' => 'object-fit',
					'selector' => $marker_inner . ' .x-hotspots_marker-image',
				),
			),
			'required' => array( 'markerImage', '!=', '' ),
		);

		$this->controls['imageBorder'] = array(
			'tab'      => 'content',
			'group'    => 'icon',
			'label'    => esc_html__( 'Image border', 'bricks' ),
			'type'     => 'border',
			'css'      => array(
				array(
					'property' => 'border',
					'selector' => $marker_inner . ' .x-hotspots_marker-image',
				),
			),
			'required' => array( 'markerImage', '!=', '' ),
		);

		$this->controls['imageShadow'] = array(
			'tab'      => 'content',
			'group'    => 'icon',
			'label'    => esc_html__( 'Box shadow', 'bricks' ),
			'type'     => 'box-shadow',
			'css'      => array(
				array(
					'property' => 'box-shadow',
					'selector' => $marker_inner . ' .x-hotspots_marker-image',
				),
			),
			'required' => array( 'markerImage', '!=', '' ),
		);

		$this->controls['marker_start'] = array(
			'tab'   => 'content',
			'group' => 'markers',
			'label' => esc_html__( 'Button', 'bricks' ),
			'type'  => 'separator',
		);

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

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

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

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

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

		$this->controls['markerWidth'] = array(
			'tab'   => 'content',
			'group' => 'markers',
			'label' => esc_html__( 'Width', 'bricks' ) . ' (' . esc_html__( 'Button', 'bricks' ) . ')',
			'type'  => 'number',
			'units' => true,
			'css'   => array(
				array(
					'property' => 'width',
					'selector' => $marker_inner,
				),
			),
		);

		$this->controls['markerHeight'] = array(
			'tab'   => 'content',
			'group' => 'markers',
			'label' => esc_html__( 'Height', 'bricks' ) . ' (' . esc_html__( 'Button', 'bricks' ) . ')',
			'type'  => 'number',
			'units' => true,
			'css'   => array(
				array(
					'property' => 'height',
					'selector' => $marker_inner,
				),
			),
		);

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

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

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

		$this->controls['markerButtoncolumnGap'] = array(
			'tab'   => 'content',
			'label' => esc_html__( 'Gap', 'bricks' ),
			'group' => 'markers',
			'type'  => 'number',
			'units' => true,
			'css'   => array(
				array(
					'property' => 'gap',
					'selector' => $marker_inner,
				),
			),
		);

		/* popover content */

		$popover = '.x-marker_popover .tippy-content';

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

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

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

		$this->controls['popoverArrowColor'] = array(
			'tab'   => 'content',
			'group' => 'popover',
			'type'  => 'color',
			'label' => esc_html__( 'Color', 'bricks' ) . ' (' . esc_html__( 'Arrow', 'bricks' ) . ')',
			'css'   => array(
				array(
					'property' => 'color',
					'selector' => '.x-marker .tippy-arrow',
				),
			),
		);

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

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

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

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

		/* behaviour */

		$this->controls['behaviour_start'] = array(
			'tab'         => 'content',
			'group'       => 'behaviour',
			'description' => esc_html__( 'Leave blank if wanting to inherit from parent Image Hotspots settings', 'bricksextras' ),
			'type'        => 'separator',
		);

		$this->controls['placement'] = array(
			'tab'         => 'content',
			'label'       => esc_html__( 'Preferred placement', 'bricksextras' ),
			'description' => 'auto | top | bottom | left | right',
			'type'        => 'text',
			'group'       => 'behaviour',
			'inline'      => true,
		);

		$this->controls['interaction'] = array(
			'tab'         => 'content',
			'label'       => esc_html__( 'Trigger', 'bricks' ),
			'type'        => 'text',
			'group'       => 'behaviour',
			'description' => 'click | mouseenter | focus | mouseenter click',
			'inline'      => true,
		);

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

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

		$this->controls['moveTransition'] = array(
			'tab'   => 'content',
			'group' => 'behaviour',
			'label' => esc_html__( 'Transition', 'bricks' ) . ' (ms)',
			'type'  => 'number',
			'units' => false,
			'small' => true,
		);

		$this->controls['moveFocus'] = array(
			'tab'         => 'content',
			'label'       => esc_html__( 'Move focus inside popover content', 'bricksextras' ),
			'type'        => 'text',
			'group'       => 'behaviour',
			'description' => 'enable / disable',
			'inline'      => true,
		);

		/* animation */

		$this->controls['animationSep'] = array(
			'tab'   => 'content',
			'group' => 'animation',
			'label' => esc_html__( 'Animation', 'bricks' ),
			'type'  => 'separator',
		);

		$this->controls['popoverTransitionIn'] = array(
			'tab'            => 'content',
			'group'          => 'animation',
			'label'          => esc_html__( 'Transition', 'bricks' ) . ' (' . esc_html__( 'Show', 'bricks' ) . ')',
			'css'            => array(
				array(
					'property' => '--x-popover-transitionin',
					'selector' => '',
				),
			),
			'type'           => 'number',
			'inline'         => true,
			'unit'           => 'ms',
			'hasDynamicData' => false,
		);

		$this->controls['popoverTransitionOut'] = array(
			'tab'            => 'content',
			'group'          => 'animation',
			'label'          => esc_html__( 'Transition', 'bricks' ) . ' (' . esc_html__( 'Hide', 'bricks' ) . ')',
			'css'            => array(
				array(
					'property' => '--x-popover-transitionout',
					'selector' => '',
				),
			),
			'type'           => 'number',
			'unit'           => 'ms',
			'inline'         => true,
			'hasDynamicData' => false,
		);

		$this->controls['popoverTranslateX'] = array(
			'tab'            => 'content',
			'group'          => 'animation',
			'label'          => esc_html__( 'Translate X', 'bricks' ),
			'css'            => array(
				array(
					'property' => '--x-popover-translatex',
					'selector' => '',
				),
			),
			'type'           => 'number',
			'inline'         => true,
			'hasDynamicData' => false,
			'units'          => array(
				'px' => array(
					'min'  => 1,
					'max'  => 1000,
					'step' => 1,
				),
			),
		);

		$this->controls['popoverTranslateY'] = array(
			'tab'            => 'content',
			'group'          => 'animation',
			'label'          => esc_html__( 'Translate Y', 'bricks' ),
			'css'            => array(
				array(
					'property' => '--x-popover-translatey',
					'selector' => '',
				),
			),
			'type'           => 'number',
			'inline'         => true,
			'hasDynamicData' => false,
			'units'          => array(
				'px' => array(
					'min'  => 1,
					'max'  => 1000,
					'step' => 1,
				),
			),
		);

		$this->controls['popoverScale'] = array(
			'tab'            => 'content',
			'group'          => 'animation',
			'label'          => esc_html__( 'Scale', 'bricks' ),
			'css'            => array(
				array(
					'property' => '--x-popover-scale',
					'selector' => '',
				),
			),
			'type'           => 'number',
			'inline'         => true,
			'hasDynamicData' => false,
		);
	}

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

		$settings = $this->settings;
		$output   = '';

		// Icon from parent.
		$icon = false;
		if ( isset( $settings['icon'] ) ) {
			$icon = self::render_icon( $settings['icon'], array( 'x-marker_marker-icon' ) );
		}

		$this->set_attribute( 'x-marker', 'class', array( 'x-marker' ) );
		$this->set_attribute( 'x-marker_marker', 'class', array( 'x-marker_marker' ) );
		$this->set_attribute( 'x-marker_marker-inner', 'class', array( 'x-marker_marker-inner' ) );

		$identifier = \BricksExtras\Helpers::generate_unique_identifier( $this->element, $this->id );

		$this->set_attribute( 'x-marker', 'data-x-id', $identifier );

		$position_x = isset( $settings['position_x'] ) ? esc_attr( bricks_render_dynamic_data( $settings['position_x'] ) ) : '0%';
		$position_y = isset( $settings['position_y'] ) ? esc_attr( bricks_render_dynamic_data( $settings['position_y'] ) ) : '0%';

		$this->set_attribute(
			'x-marker_marker',
			'style',
			array(
				'left: ' . $position_x . ';',
				'top: ' . $position_y . ';',
			)
		);

		$marker_type_setting = isset( $settings['markerType'] ) ? $settings['markerType'] : 'popover';

		$marker_type = strstr( $marker_type_setting, '{' ) ? $this->render_dynamic_data_tag( $marker_type_setting, 'text' ) : $marker_type_setting;

		$marker_is_link = 'popover' !== $marker_type;

		$this->set_attribute( 'x-marker_popover', 'class', array( 'x-marker_popover' ) );
		$this->set_attribute( 'x-marker_popover-content', 'class', array( 'x-marker_popover-content' ) );
		$this->set_attribute( 'x-marker_marker-title', 'class', array( 'x-marker_marker-title' ) );

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

		if ( ! $marker_is_link ) {

			$this->set_attribute(
				'x-marker_marker',
				'role',
				array(
					'button',
				)
			);

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

			$aria_label = isset( $settings['aria_label'] ) ? bricks_render_dynamic_data( $settings['aria_label'] ) : esc_attr__( 'Toggle popover', 'bricksextras' );

			$this->set_attribute(
				'x-marker_marker',
				'aria-label',
				array(
					esc_attr( $aria_label ),
				)
			);

			$this->set_attribute(
				'x-marker_marker',
				'tabindex',
				array(
					'0',
				)
			);

		} else {
			$this->set_link_attributes( 'x-marker_marker', $link );

			if ( 'both' === $marker_type ) {
				$this->set_attribute( 'x-marker_marker', 'class', 'x-marker_marker-trigger' );
			}
		}

		$maybe_marker_image = false;
		$image_output       = '';

		$marker_image_alt_text = isset( $settings['markerImageAltText'] ) ? esc_attr( bricks_render_dynamic_data( $settings['markerImageAltText'] ) ) : '';

		if ( isset( $settings['markerImage'] ) ) {

			if ( ! empty( $settings['markerImageAltText'] ) ) {
				$marker_image_attr = array(
					'class' => 'x-hotspots_marker-image',
					'alt'   => $marker_image_alt_text,
				);
			} else {
				$marker_image_attr = array( 'class' => 'x-hotspots_marker-image' );
			}

			$marker_image      = \BricksExtras\Helpers::get_normalized_image_settings( $settings, 'markerImage' );
			$marker_image_id   = $marker_image['id'];
			$marker_image_url  = $marker_image['url'];
			$marker_image_size = $marker_image['size'];

			if ( $marker_image_id ) {

				$maybe_marker_image = true;

				$marker_image_output = wp_get_attachment_image(
					$marker_image_id,
					$marker_image_size,
					false,
					$marker_image_attr
				);

				$image_output .= $marker_image_output;

			} elseif ( '' !== $marker_image_url ) {

					$maybe_marker_image = true;

					$image_output .= \BricksExtras\Helpers::placeholder_image(
						array(
							'class' => 'x-hotspots_marker-image',
							'src'   => $marker_image_url,
							'alt'   => $marker_image_alt_text,
						)
					);
			}
		}

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

		$config = array();

		if ( isset( $this->settings['placement'] ) ) {
			$config['placement'] = bricks_render_dynamic_data( $this->settings['placement'] );
		}

		if ( isset( $this->settings['offsetSkidding'] ) ) {
			$config['offsetSkidding'] = intval( $this->settings['offsetSkidding'] );
		}

		if ( isset( $this->settings['offsetDistance'] ) ) {
			$config['offsetDistance'] = intval( $this->settings['offsetDistance'] );
		}

		if ( isset( $this->settings['moveTransition'] ) ) {
			$config['moveTransition'] = intval( $this->settings['moveTransition'] );
		}

		if ( isset( $this->settings['interaction'] ) ) {
			$config['interaction'] = bricks_render_dynamic_data( $this->settings['interaction'] );
		}

		if ( isset( $this->settings['pulseType'] ) ) {
			$config['pulseType'] = $this->settings['pulseType'];
		}

		if ( isset( $this->settings['moveFocus'] ) ) {
			$config['moveFocus'] = 'enable' === bricks_render_dynamic_data( $this->settings['moveFocus'] );
		}

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

		$this->set_attribute( '_root', 'class', array( 'x-marker' ) );

		$marker_tag = $marker_is_link ? 'a' : 'button';

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

			$output .= '<' . $marker_tag . " {$this->render_attributes( 'x-marker_marker' )}><span {$this->render_attributes( 'x-marker_marker-inner' )}>";

		if ( (bool) $maybe_marker_image ) {
			$output .= $image_output;
		} elseif ( $icon ) {
				$output .= $icon;
		}

		if ( ! empty( $settings['title'] ) ) {
				$output .= "<span {$this->render_attributes( 'x-marker_marker-title' )}>" . wp_kses_post( $settings['title'] ) . '</span>';
		}

			$output .= '</span></' . $marker_tag . '>';

		if ( method_exists( '\Bricks\Frontend', 'render_children' ) ) {

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

			// Add wrapper for Tippy in builder to match frontend structure.
			if ( \BricksExtras\Helpers::maybe_preview() ) {
				$output .= '<div class="x-marker_popover-wrapper">';
				$output .= '<div class="tippy-box" data-state="visible" tabindex="-1" data-theme="extras" data-animation="extras">';
				$output .= '<div class="tippy-content" data-state="visible" style="transition-duration: 300ms;">';
			}

			$output     .= "<div {$this->render_attributes( 'x-marker_popover-content' )}>";
				$output .= \Bricks\Frontend::render_children( $this );
			$output     .= '</div>';

			// Close wrapper in builder.
			if ( \BricksExtras\Helpers::maybe_preview() ) {
				$output .= '</div>';
				$output .= '<div class="tippy-arrow" style="position: absolute; top: 0px; transform: translate3d(0px, 36px, 0px);"></div>';
				$output .= '</div>';
				$output .= '</div>';
			}

			$output .= '</div>';

		}

		$output .= '</div>';

		echo $output;
	}
}
