<?php
/**
 * Product Carousel Widget — render functions
 *
 * All render functions are prefixed ggmc_product_carousel_ to avoid
 * coupling with the Product Grid widget. The data query layer
 * (GGM_Commerce_Product_Data_Handler) remains shared.
 *
 * @package GGM_Commerce
 */

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

// ───────────────────────────────────────────────────────────────
// Available components (for component_order repeater)
// ───────────────────────────────────────────────────────────────

function ggmc_product_carousel_get_available_components() {
	$wishlist_active = \GGM_Commerce_License::instance()->is_widget_activated( 'wishlist' );
	$compare_active  = \GGM_Commerce_License::instance()->is_widget_activated( 'compare' );
	$reviews_active  = \GGM_Commerce_License::instance()->is_widget_activated( 'product-reviews' );

	$components = array(
		array( 'component_id' => 'image',      'component_label' => __( 'Image', 'ggm-commerce' ) ),
		array( 'component_id' => 'badges',     'component_label' => __( 'Badges', 'ggm-commerce' ) ),
		array( 'component_id' => 'categories', 'component_label' => __( 'Categories', 'ggm-commerce' ) ),
		array( 'component_id' => 'title',      'component_label' => __( 'Title', 'ggm-commerce' ) ),
	);

	if ( $reviews_active ) {
		$components[] = array( 'component_id' => 'rating', 'component_label' => __( 'Rating', 'ggm-commerce' ) );
	}

	$components[] = array( 'component_id' => 'price',       'component_label' => __( 'Price', 'ggm-commerce' ) );
	$components[] = array( 'component_id' => 'description', 'component_label' => __( 'Description', 'ggm-commerce' ) );
	$components[] = array( 'component_id' => 'stock',        'component_label' => __( 'Stock Status', 'ggm-commerce' ) );

	$attributes_active = \GGM_Commerce_License::instance()->is_widget_activated( 'custom-attributes' );
	if ( $attributes_active ) {
		$components[] = array( 'component_id' => 'attributes', 'component_label' => __( 'Attributes', 'ggm-commerce' ) );
	}

	$components[] = array( 'component_id' => 'details_link', 'component_label' => __( 'Details Link', 'ggm-commerce' ) );

	$actions_parts = array( __( 'Cart', 'ggm-commerce' ) );
	if ( $wishlist_active ) {
		$actions_parts[] = __( 'Wishlist', 'ggm-commerce' );
	}
	if ( $compare_active ) {
		$actions_parts[] = __( 'Compare', 'ggm-commerce' );
	}

	$components[] = array(
		'component_id'    => 'actions',
		'component_label' => sprintf( __( 'Actions (%s)', 'ggm-commerce' ), implode( ', ', $actions_parts ) ),
	);

	return $components;
}

// ───────────────────────────────────────────────────────────────
// Settings → query args mapper
// ───────────────────────────────────────────────────────────────

function ggmc_product_carousel_map_settings_to_args( $settings ) {
	return array(
		'posts_per_page'  => intval( $settings['products_per_page'] ?? 8 ),
		'orderby'         => $settings['orderby'] ?? 'created_at',
		'order'           => $settings['order'] ?? 'DESC',
		'featured_only'   => ! empty( $settings['show_featured_only'] ) && 'yes' === $settings['show_featured_only'],
		'category_filter' => $settings['filter_by_category'] ?? array(),
		'tag_filter'      => $settings['filter_by_tag'] ?? array(),
		'stock_status'    => $settings['stock_filter'] ?? 'all',
		'attribute_filters' => ! empty( $settings['filter_by_attribute'] ) && ! empty( $settings['filter_by_attribute_value'] )
			? array( intval( $settings['filter_by_attribute'] ) => $settings['filter_by_attribute_value'] )
			: array(),
		'status'          => 'active',
	);
}

// ───────────────────────────────────────────────────────────────
// Component visibility check
// ───────────────────────────────────────────────────────────────

function ggmc_product_carousel_is_component_visible( $component_id, $settings ) {
	$map = array(
		'image'       => 'show_image',
		'badges'      => 'show_badge',
		'categories'  => 'show_categories',
		'title'       => 'show_title',
		'rating'      => 'show_rating',
		'price'       => 'show_price',
		'description' => 'show_description',
		'stock'        => 'show_stock',
		'attributes'   => 'show_attributes',
		'details_link' => 'show_details_link',
		'actions'      => 'show_add_to_cart',
	);

	$setting_key = $map[ $component_id ] ?? '';
	if ( empty( $setting_key ) ) {
		return true;
	}

	return ! empty( $settings[ $setting_key ] ) && 'yes' === $settings[ $setting_key ];
}

// ───────────────────────────────────────────────────────────────
// Main render entry point
// ───────────────────────────────────────────────────────────────

function ggmc_product_carousel_render_premium_content( $widget ) {
	$settings = $widget->get_settings_for_display();

	// Fetch products
	$args     = ggmc_product_carousel_map_settings_to_args( $settings );
	$products = GGM_Commerce_Product_Data_Handler::get_products( $args );

	if ( empty( $products ) ) {
		if ( ggmc_is_editor_mode() ) {
			echo '<div class="ggmc-carousel-empty">';
			echo '<p>' . esc_html__( 'No products found. Adjust your query settings.', 'ggm-commerce' ) . '</p>';
			echo '</div>';
		}
		return;
	}

	// Build carousel config JSON for JS
	$config = ggmc_product_carousel_build_config( $settings );

	// Carousel settings
	$show_arrows = ! empty( $settings['arrows_show'] ) && 'yes' === $settings['arrows_show'];
	$show_dots   = ! empty( $settings['dots_show'] ) && 'yes' === $settings['dots_show'];
	$loop        = ! empty( $settings['infinite_loop'] ) && 'yes' === $settings['infinite_loop'];
	$spv         = intval( $config['slidesPerView'] );
	$total       = count( $products );

	// Number of clones needed for infinite loop (on each side)
	$clones_per_side = $loop && $total > $spv ? $spv + 1 : 0;

	// Card layout
	$card_layout      = $settings['card_layout'] ?? 'vertical';
	$image_position   = $settings['image_position'] ?? 'left';
	$overlay_position = $settings['overlay_position'] ?? 'bottom';

	// Dots shape class
	$dots_shape    = $settings['dots_shape'] ?? 'circle';
	$dots_position = $settings['dots_position'] ?? 'below';

	// Container
	echo '<div class="ggmc-product-carousel" data-carousel-config="' . esc_attr( wp_json_encode( $config ) ) . '">';

	// Viewport
	echo '<div class="ggmc-carousel-viewport">';
	echo '<div class="ggmc-carousel-track">';

	// Clone slides (end of list, prepended for infinite loop)
	if ( $clones_per_side > 0 ) {
		$clone_start = max( 0, $total - $clones_per_side );
		for ( $i = $clone_start; $i < $total; $i++ ) {
			ggmc_product_carousel_render_slide( $products[ $i ], $settings, $card_layout, $image_position, $overlay_position, -1, true );
		}
	}

	// Real slides
	foreach ( $products as $index => $product ) {
		ggmc_product_carousel_render_slide( $product, $settings, $card_layout, $image_position, $overlay_position, $index, false );
	}

	// Clone slides (start of list, appended for infinite loop)
	if ( $clones_per_side > 0 ) {
		for ( $i = 0; $i < $clones_per_side; $i++ ) {
			ggmc_product_carousel_render_slide( $products[ $i ], $settings, $card_layout, $image_position, $overlay_position, -1, true );
		}
	}

	echo '</div>'; // .ggmc-carousel-track
	echo '</div>'; // .ggmc-carousel-viewport

	// Navigation Arrows
	if ( $show_arrows ) {
		echo '<button class="ggmc-carousel-nav ggmc-carousel-prev" aria-label="' . esc_attr__( 'Previous slide', 'ggm-commerce' ) . '">';
		$prev_icon = $settings['arrows_prev_icon'] ?? array( 'value' => 'eicon-chevron-left', 'library' => 'eicons' );
		ggmc_render_icon( $prev_icon, array( 'aria-hidden' => 'true' ) );
		echo '</button>';

		echo '<button class="ggmc-carousel-nav ggmc-carousel-next" aria-label="' . esc_attr__( 'Next slide', 'ggm-commerce' ) . '">';
		$next_icon = $settings['arrows_next_icon'] ?? array( 'value' => 'eicon-chevron-right', 'library' => 'eicons' );
		ggmc_render_icon( $next_icon, array( 'aria-hidden' => 'true' ) );
		echo '</button>';
	}

	// Dot Indicators
	if ( $show_dots ) {
		$dot_count = intval( ceil( $total / max( 1, intval( $settings['slides_to_scroll'] ?? 1 ) ) ) );
		echo '<div class="ggmc-carousel-dots position-' . esc_attr( $dots_position ) . ' shape-' . esc_attr( $dots_shape ) . '">';
		for ( $i = 0; $i < $dot_count; $i++ ) {
			$active = 0 === $i ? ' active' : '';
			echo '<button class="ggmc-carousel-dot' . $active . '" data-index="' . esc_attr( $i ) . '" aria-label="' . esc_attr( sprintf( __( 'Go to slide %d', 'ggm-commerce' ), $i + 1 ) ) . '"></button>';
		}
		echo '</div>';
	}

	echo '</div>'; // .ggmc-product-carousel
}

// ───────────────────────────────────────────────────────────────
// Build carousel config JSON
// ───────────────────────────────────────────────────────────────

function ggmc_product_carousel_build_config( $settings ) {
	$config = array(
		'slidesPerView'  => intval( $settings['slides_per_view'] ?? 3 ),
		'slidesToScroll' => intval( $settings['slides_to_scroll'] ?? 1 ),
		'slideGap'       => intval( $settings['slide_gap']['size'] ?? 20 ),
		'peekWidth'      => intval( $settings['peek_width']['size'] ?? 40 ),
		'centerMode'     => ! empty( $settings['center_mode'] ) && 'yes' === $settings['center_mode'],
		'overflowVisible' => ! empty( $settings['overflow_visible'] ) && 'yes' === $settings['overflow_visible'],
		'autoplay'       => ! empty( $settings['autoplay'] ) && 'yes' === $settings['autoplay'],
		'autoplaySpeed'  => intval( $settings['autoplay_speed'] ?? 3000 ),
		'pauseOnHover'   => ! empty( $settings['pause_on_hover'] ) && 'yes' === $settings['pause_on_hover'],
		'loop'           => ! empty( $settings['infinite_loop'] ) && 'yes' === $settings['infinite_loop'],
		'speed'          => intval( $settings['transition_speed'] ?? 400 ),
		'easing'         => $settings['transition_easing'] ?? 'ease',
		'responsive'     => array(
			'tablet' => array(
				'slidesPerView' => intval( $settings['slides_per_view_tablet'] ?? 2 ),
				'slideGap'      => intval( $settings['slide_gap_tablet']['size'] ?? 15 ),
				'peekWidth'     => intval( $settings['peek_width_tablet']['size'] ?? 30 ),
			),
			'mobile' => array(
				'slidesPerView' => intval( $settings['slides_per_view_mobile'] ?? 1 ),
				'slideGap'      => intval( $settings['slide_gap_mobile']['size'] ?? 10 ),
				'peekWidth'     => intval( $settings['peek_width_mobile']['size'] ?? 20 ),
			),
		),
	);

	return $config;
}

// ───────────────────────────────────────────────────────────────
// Render a single slide
// ───────────────────────────────────────────────────────────────

function ggmc_product_carousel_render_slide( $product, $settings, $card_layout, $image_position, $overlay_position, $index, $is_clone ) {
	$clone_class = $is_clone ? ' is-clone' : '';
	$index_attr  = $is_clone ? '' : ' data-index="' . esc_attr( $index ) . '"';

	// Card layout classes
	$layout_class = 'layout-' . esc_attr( $card_layout );
	if ( 'horizontal' === $card_layout ) {
		$layout_class .= ' image-' . esc_attr( $image_position );
	}
	if ( 'overlay' === $card_layout ) {
		$layout_class .= ' overlay-' . esc_attr( $overlay_position );
	}

	$product_url = GGM_Commerce_Helpers::get_product_details_url( $product->id );

	echo '<div class="ggmc-carousel-slide' . esc_attr( $clone_class ) . '"' . $index_attr . '>';
	echo '<div class="ggmc-carousel-card ' . esc_attr( $layout_class ) . '">';

	// For overlay layout, image is rendered inside the card as a background-like element
	// For vertical/horizontal, image and content are separate sections
	$component_order = $settings['component_order'] ?? ggmc_product_carousel_get_available_components();

	// Separate image from content components
	$has_image = ggmc_product_carousel_is_component_visible( 'image', $settings );

	if ( $has_image ) {
		$image_hover = $settings['image_hover_effect'] ?? 'zoom';
		echo '<div class="carousel-card-image hover-' . esc_attr( $image_hover ) . '">';
		echo '<a href="' . esc_url( $product_url ) . '">';
		$image_size = $settings['image_size'] ?? 'large';
		echo ggmc_product_carousel_get_image_html( $product->image_id, $image_size, $product->name );
		echo '</a>';
		echo '</div>';
	}

	// Content section
	echo '<div class="carousel-card-content">';

	$order_index = 0;
	foreach ( $component_order as $component ) {
		$id = $component['component_id'] ?? '';

		// Image is rendered separately above
		if ( 'image' === $id ) {
			continue;
		}

		if ( ! ggmc_product_carousel_is_component_visible( $id, $settings ) ) {
			continue;
		}

		switch ( $id ) {
			case 'badges':
				ggmc_product_carousel_render_badges( $product, $order_index );
				break;
			case 'categories':
				ggmc_product_carousel_render_categories( $product, $settings, $order_index );
				break;
			case 'title':
				ggmc_product_carousel_render_title( $product, $product_url, $settings, $order_index );
				break;
			case 'rating':
				ggmc_product_carousel_render_rating( $product, $order_index );
				break;
			case 'price':
				ggmc_product_carousel_render_price( $product, $order_index );
				break;
			case 'description':
				ggmc_product_carousel_render_description( $product, $settings, $order_index );
				break;
			case 'stock':
				ggmc_product_carousel_render_stock( $product, $order_index, $settings );
				break;
			case 'attributes':
				ggmc_product_carousel_render_attributes( $product, $settings, $order_index );
				break;
			case 'details_link':
				ggmc_product_carousel_render_details_link( $product, $product_url, $settings, $order_index );
				break;
			case 'actions':
				ggmc_product_carousel_render_actions( $product, $settings, $order_index );
				break;
		}

		$order_index++;
	}

	echo '</div>'; // .carousel-card-content
	echo '</div>'; // .ggmc-carousel-card
	echo '</div>'; // .ggmc-carousel-slide
}

// ───────────────────────────────────────────────────────────────
// Individual component renderers
// ───────────────────────────────────────────────────────────────

function ggmc_product_carousel_get_image_html( $image_id, $size = 'medium', $alt = '' ) {
	if ( empty( $image_id ) ) {
		return '<div class="placeholder-image">' . esc_html__( 'No Image', 'ggm-commerce' ) . '</div>';
	}

	$image_url = wp_get_attachment_image_url( $image_id, $size );
	if ( ! $image_url ) {
		return '<div class="placeholder-image">' . esc_html__( 'No Image', 'ggm-commerce' ) . '</div>';
	}

	return '<img src="' . esc_url( $image_url ) . '" alt="' . esc_attr( $alt ) . '" loading="lazy" />';
}

function ggmc_product_carousel_render_badges( $product, $order ) {
	echo '<div class="carousel-product-badges" style="order: ' . esc_attr( $order ) . ';">';

	if ( $product->featured ) {
		echo '<span class="badge badge-featured">' . esc_html__( 'Featured', 'ggm-commerce' ) . '</span>';
	}

	if ( $product->sale_price && $product->sale_price < $product->price ) {
		$discount = round( ( ( $product->price - $product->sale_price ) / $product->price ) * 100 );
		echo '<span class="badge badge-sale">-' . esc_html( $discount ) . '%</span>';
	}

	if ( ! empty( $product->manage_stock ) && $product->stock <= 0 ) {
		echo '<span class="badge badge-out-of-stock">' . esc_html__( 'Out of Stock', 'ggm-commerce' ) . '</span>';
	}

	$created = new \DateTime( $product->created_at );
	$now     = new \DateTime();
	if ( $now->diff( $created )->days <= 30 ) {
		echo '<span class="badge badge-new">' . esc_html__( 'New', 'ggm-commerce' ) . '</span>';
	}

	echo '</div>';
}

function ggmc_product_carousel_render_categories( $product, $settings, $order ) {
	$link       = ! empty( $settings['link_categories'] ) && 'yes' === $settings['link_categories'];
	$taxonomy   = GGM_Commerce_Taxonomy::get_instance();
	$categories = $taxonomy->get_product_categories( $product->id );

	if ( empty( $categories ) ) {
		return;
	}

	echo '<div class="carousel-product-categories" style="order: ' . esc_attr( $order ) . ';">';
	foreach ( $categories as $cat ) {
		if ( $link ) {
			$url = GGM_Commerce_Helpers::get_category_url( $cat );
			echo '<a href="' . esc_url( $url ) . '" class="product-category-link"><span class="product-category">' . esc_html( $cat->name ) . '</span></a> ';
		} else {
			echo '<span class="product-category">' . esc_html( $cat->name ) . '</span> ';
		}
	}
	echo '</div>';
}

function ggmc_product_carousel_render_title( $product, $product_url, $settings, $order ) {
	$tag = $settings['title_html_tag'] ?? 'h3';
	echo '<' . esc_attr( $tag ) . ' class="carousel-product-title" style="order: ' . esc_attr( $order ) . ';">';
	echo '<a href="' . esc_url( $product_url ) . '">' . esc_html( $product->name ) . '</a>';
	echo '</' . esc_attr( $tag ) . '>';
}

function ggmc_product_carousel_render_rating( $product, $order ) {
	if ( ! function_exists( 'ggm_commerce_license' ) || ! ggm_commerce_license()->is_widget_activated( 'product-reviews' ) ) {
		return;
	}

	$rating       = isset( $product->average_rating ) ? floatval( $product->average_rating ) : 0;
	$rating_count = isset( $product->rating_count ) ? intval( $product->rating_count ) : 0;
	$full         = floor( $rating );
	$half         = ( $rating - $full ) >= 0.5;
	$empty        = 5 - $full - ( $half ? 1 : 0 );

	echo '<div class="carousel-product-rating" style="order: ' . esc_attr( $order ) . ';">';

	for ( $i = 0; $i < $full; $i++ ) {
		echo '<i class="eicon-star star"></i>';
	}
	if ( $half ) {
		echo '<i class="eicon-star-half star"></i>';
	}
	for ( $i = 0; $i < $empty; $i++ ) {
		echo '<i class="eicon-star-o star empty"></i>';
	}

	if ( $rating > 0 ) {
		echo '<span class="rating-text">(' . number_format( $rating, 1 );
		if ( $rating_count > 0 ) {
			echo ' <span class="rating-count">' . esc_html( $rating_count ) . '</span>';
		}
		echo ')</span>';
	}

	echo '</div>';
}

function ggmc_product_carousel_render_price( $product, $order ) {
	echo '<div class="carousel-product-price" style="order: ' . esc_attr( $order ) . ';">';
	// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- format_price() returns pre-escaped HTML
	echo GGM_Commerce_Helpers::format_price( $product );
	echo '</div>';
}

function ggmc_product_carousel_render_description( $product, $settings, $order ) {
	$length      = intval( $settings['description_length'] ?? 15 );
	$text        = $product->short_description ?? '';
	$description = wp_trim_words( wp_strip_all_tags( $text ), $length );

	if ( empty( $description ) ) {
		return;
	}

	echo '<div class="carousel-product-description" style="order: ' . esc_attr( $order ) . ';">';
	echo esc_html( $description );
	echo '</div>';
}

function ggmc_product_carousel_render_stock( $product, $order, $settings = array() ) {
	$stock     = isset( $product->stock ) ? intval( $product->stock ) : 999;
	$threshold = isset( $product->low_stock_threshold ) ? intval( $product->low_stock_threshold ) : 10;
	$class     = GGM_Commerce_Helpers::get_product_stock_class( $stock, $threshold );
	$extra_class = '';

	// Check for restock text — replaces "Out of Stock" when available
	$restock_text = '';
	if ( $stock <= 0 && ( $settings['show_restock_date'] ?? 'yes' ) === 'yes' ) {
		$restock_text = GGM_Commerce_Helpers::get_restock_display_text(
			$product->restock_date ?? null,
			$settings['restock_display_format'] ?? 'descriptive'
		);
		if ( $restock_text !== '' ) {
			$extra_class = ' restock-expected';
		}
	}

	echo '<div class="carousel-product-stock" style="order: ' . esc_attr( $order ) . ';">';
	echo '<span class="' . esc_attr( $class . $extra_class ) . '">';

	if ( $restock_text !== '' ) {
		echo esc_html( $restock_text );
	} elseif ( ! isset( $product->stock ) ) {
		echo esc_html__( 'In Stock', 'ggm-commerce' );
	} elseif ( $stock > 0 ) {
		/* translators: %d: stock quantity */
		echo esc_html( sprintf( __( '%d in stock', 'ggm-commerce' ), $stock ) );
	} else {
		echo esc_html__( 'Out of Stock', 'ggm-commerce' );
	}

	echo '</span></div>';
}

function ggmc_product_carousel_render_attributes( $product, $settings, $order ) {
	if ( ! class_exists( 'GGM_Commerce_Attributes' ) ) {
		return;
	}

	$attributes_manager = GGM_Commerce_Attributes::get_instance();
	$product_id = isset( $product->id ) ? $product->id : 0;
	$attributes = $product_id ? $attributes_manager->get_product_attributes( $product_id ) : array();

	if ( empty( $attributes ) ) {
		return;
	}

	// Filter to selected attributes only.
	$selected_ids = ! empty( $settings['carousel_selected_attributes'] ) ? array_map( 'intval', (array) $settings['carousel_selected_attributes'] ) : array();
	if ( ! empty( $selected_ids ) ) {
		$attributes = array_filter(
			$attributes,
			function ( $attr ) use ( $selected_ids ) {
				return in_array( (int) $attr->attribute_id, $selected_ids, true );
			}
		);
	}

	// Filter out empty values.
	$attributes = array_filter(
		$attributes,
		function ( $attr ) {
			return ! empty( $attr->attribute_value );
		}
	);

	if ( empty( $attributes ) ) {
		return;
	}

	$layout    = $settings['carousel_attributes_layout'] ?? 'inline';
	$show_units = ! empty( $settings['carousel_attributes_show_units'] ) && 'yes' === $settings['carousel_attributes_show_units'];

	echo '<div class="carousel-product-attributes carousel-attributes-' . esc_attr( $layout ) . '" style="order: ' . esc_attr( $order ) . ';">';

	foreach ( $attributes as $attr ) {
		$value = esc_html( $attr->attribute_value );
		if ( $show_units && ! empty( $attr->unit ) ) {
			$value .= ' ' . esc_html( $attr->unit );
		}

		echo '<div class="carousel-attr-item">';
		echo '<span class="carousel-attr-label">' . esc_html( $attr->name ) . '</span>';
		echo '<span class="carousel-attr-value">' . $value . '</span>';
		echo '</div>';
	}

	echo '</div>';
}

function ggmc_product_carousel_render_details_link( $product, $product_url, $settings, $order ) {
	$link_text = $settings['details_link_text'] ?? __( 'MORE DETAILS', 'ggm-commerce' );
	$icon      = $settings['details_link_icon'] ?? array( 'value' => 'eicon-chevron-right', 'library' => 'eicons' );

	echo '<div class="carousel-product-details-link" style="order: ' . esc_attr( $order ) . ';">';
	echo '<a href="' . esc_url( $product_url ) . '" class="details-link">';
	echo '<span class="details-link-text">' . esc_html( $link_text ) . '</span>';
	if ( ! empty( $icon['value'] ) ) {
		echo ' <span class="details-link-icon">';
		ggmc_render_icon( $icon, array( 'aria-hidden' => 'true' ) );
		echo '</span>';
	}
	echo '</a>';
	echo '</div>';
}

function ggmc_product_carousel_render_actions( $product, $settings, $order ) {
	$button_text    = $settings['add_to_cart_text'] ?? __( 'Add to Cart', 'ggm-commerce' );
	$button_size    = $settings['button_size'] ?? 'medium';
	$has_variations = ! empty( $product->has_variations ) && $product->has_variations;
	$display_text   = $has_variations ? __( 'Select Options', 'ggm-commerce' ) : $button_text;
	$product_url    = $has_variations ? GGM_Commerce_Helpers::get_product_details_url( $product->id ) : '';

	$data_attrs  = 'data-product-id="' . esc_attr( $product->id ) . '" ';
	$data_attrs .= 'data-has-variations="' . ( $has_variations ? '1' : '0' ) . '" ';
	$data_attrs .= 'data-variable-behavior="link_to_product" ';
	if ( $product_url ) {
		$data_attrs .= 'data-product-url="' . esc_url( $product_url ) . '" ';
	}

	echo '<div class="carousel-product-actions" style="order: ' . esc_attr( $order ) . ';">';

	echo '<button type="button" class="ggmc-add-to-cart-btn btn-' . esc_attr( $button_size ) . '" ';
	// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- $data_attrs built from esc_attr() calls
	echo $data_attrs . '>';
	echo esc_html( $display_text );
	echo '</button>';

	// Wishlist
	$wishlist_active = \GGM_Commerce_License::instance()->is_widget_activated( 'wishlist' );
	if ( $wishlist_active && ! empty( $settings['show_wishlist'] ) && 'yes' === $settings['show_wishlist'] ) {
		echo '<button type="button" class="wishlist-btn" data-product-id="' . esc_attr( $product->id ) . '">';
		echo '<i class="eicon-heart-o"></i>';
		echo '</button>';
	}

	// Compare
	$compare_active = \GGM_Commerce_License::instance()->is_widget_activated( 'product-comparison' );
	if ( $compare_active && ! empty( $settings['show_compare'] ) && 'yes' === $settings['show_compare'] ) {
		echo '<button type="button" class="compare-btn" data-product-id="' . esc_attr( $product->id ) . '">';
		echo '<i class="eicon-exchange"></i>';
		echo '</button>';
	}

	echo '</div>';
}
