<?php
/**
 * MenuX Free — WooCommerce Integration
 *
 * Renders a cart icon (with live item count, optional total and a mini-cart
 * dropdown) inside the MenuX navigation. The count/total/mini-cart refresh
 * without a page reload via WooCommerce's native add-to-cart fragments.
 *
 * All output is gated behind both the `woo_cart_enabled` setting AND the
 * presence of an active WooCommerce install, so the plugin remains fully
 * functional (and silent) when WooCommerce is not installed.
 *
 * @package MenuX
 */

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

/**
 * Whether WooCommerce is active and its cart is available in this request.
 *
 * @return bool
 */
function menux_woo_active() {
	return class_exists( 'WooCommerce' ) && function_exists( 'WC' );
}

/**
 * Whether the MenuX cart icon should be rendered.
 *
 * @param array $s Parsed style settings.
 * @return bool
 */
function menux_woo_cart_enabled( $s ) {
	return menux_woo_active() && ! empty( $s['woo_cart_enabled'] ) && $s['woo_cart_enabled'] === '1';
}

/**
 * Maps the icon setting to a Font Awesome 6 class.
 *
 * @param string $icon Setting value (cart|bag|basket).
 * @return string
 */
function menux_woo_cart_icon_class( $icon ) {
	switch ( $icon ) {
		case 'bag':    return 'fa-solid fa-bag-shopping';
		case 'basket': return 'fa-solid fa-basket-shopping';
		case 'cart':
		default:       return 'fa-solid fa-cart-shopping';
	}
}

/**
 * Current cart item count (0 when the cart is unavailable, e.g. in the editor).
 *
 * @return int
 */
function menux_woo_cart_count() {
	if ( ! menux_woo_active() || is_null( WC()->cart ) ) return 0;
	return (int) WC()->cart->get_cart_contents_count();
}

/**
 * Current cart subtotal as formatted HTML (empty when unavailable).
 *
 * @return string
 */
function menux_woo_cart_total() {
	if ( ! menux_woo_active() || is_null( WC()->cart ) ) return '';
	return WC()->cart->get_cart_subtotal();
}

/**
 * Builds the inner `.menux-woo-cart` element: link, icon, badge, optional
 * total and the mini-cart dropdown. This is reused verbatim by the add-to-cart
 * fragment so WooCommerce can swap it live.
 *
 * @param array $s Parsed style settings.
 * @return string
 */
function menux_woo_cart_inner_html( $s ) {
	$icon_class  = menux_woo_cart_icon_class( $s['woo_cart_icon'] ?? 'cart' );
	$minicart    = in_array( $s['woo_cart_minicart'] ?? 'hover', array( 'hover', 'click', 'off' ), true )
		? $s['woo_cart_minicart'] : 'hover';
	$show_count  = ! empty( $s['woo_cart_show_count'] ) && $s['woo_cart_show_count'] === '1';
	$show_total  = ! empty( $s['woo_cart_show_total'] ) && $s['woo_cart_show_total'] === '1';
	$hide_empty  = ! empty( $s['woo_cart_hide_empty'] ) && $s['woo_cart_hide_empty'] === '1';

	$count    = menux_woo_cart_count();
	$cart_url = function_exists( 'wc_get_cart_url' ) ? wc_get_cart_url() : '#';

	// Hidden entirely when empty and the option is on. We still emit the wrapper
	// (so the fragment can re-populate it once items are added) but mark it hidden.
	$wrap_hidden = ( $hide_empty && $count === 0 ) ? ' menux-woo-empty' : '';

	$badge = '';
	if ( $show_count ) {
		$badge = '<span class="menux-woo-count"' . ( $count === 0 ? ' data-empty="1"' : '' ) . '>'
			. esc_html( (string) $count ) . '</span>';
	}

	$total = '';
	if ( $show_total ) {
		// get_cart_subtotal() returns escaped currency HTML from WooCommerce.
		$total = '<span class="menux-woo-total">' . menux_woo_cart_total() . '</span>';
	}

	$aria = sprintf(
		/* translators: %d: number of items in the cart */
		_n( 'Cart, %d item', 'Cart, %d items', $count, 'giuliomax-menu-builder' ),
		$count
	);

	$html  = '<div class="menux-woo-cart' . $wrap_hidden . '" data-minicart="' . esc_attr( $minicart ) . '">';
	$html .= '<a class="menux-woo-cart-btn" href="' . esc_url( $cart_url ) . '" aria-label="' . esc_attr( $aria ) . '">';
	$html .= '<i class="' . esc_attr( $icon_class ) . '" aria-hidden="true"></i>';
	$html .= $badge;
	$html .= $total;
	$html .= '</a>';

	if ( $minicart !== 'off' ) {
		$html .= '<div class="menux-woo-minicart" aria-label="' . esc_attr__( 'Mini cart', 'giuliomax-menu-builder' ) . '">';
		$html .= menux_woo_minicart_html();
		$html .= '</div>';
	}

	$html .= '</div>';

	return $html;
}

/**
 * Mini-cart contents. Delegates to WooCommerce's themeable mini-cart template
 * so theme overrides and other plugins keep working. Returns a placeholder
 * when the cart isn't available (e.g. inside the block editor).
 *
 * @return string
 */
function menux_woo_minicart_html() {
	if ( ! menux_woo_active() || is_null( WC()->cart ) ) {
		return '<p class="menux-woo-minicart-empty">' . esc_html__( 'Your cart is empty.', 'giuliomax-menu-builder' ) . '</p>';
	}

	ob_start();
	woocommerce_mini_cart();
	return ob_get_clean();
}

/**
 * Full cart-button HTML including the position wrapper, for embedding in the nav.
 * Returns '' when the feature is disabled or WooCommerce is absent.
 *
 * @param array $s Parsed style settings.
 * @return string
 */
function menux_woo_cart_html( $s ) {
	if ( ! menux_woo_cart_enabled( $s ) ) return '';
	$pos = in_array( $s['woo_cart_position'] ?? 'right', array( 'left', 'right' ), true ) ? $s['woo_cart_position'] : 'right';
	return '<div class="menux-woo-cart-wrap menux-woo-pos-' . esc_attr( $pos ) . '">' . menux_woo_cart_inner_html( $s ) . '</div>';
}

/**
 * Live updates: replace the `.menux-woo-cart` element(s) on add-to-cart AJAX.
 * Registered unconditionally (cheap) but only emits a fragment when the feature
 * is enabled — multiple nav instances share the same class selector, so
 * WooCommerce's jQuery `replaceWith` updates every cart icon on the page.
 */
add_filter( 'woocommerce_add_to_cart_fragments', 'menux_woo_cart_fragments' );
function menux_woo_cart_fragments( $fragments ) {
	$s = wp_parse_args( get_option( 'menux_style', array() ), menux_style_defaults() );
	if ( ! menux_woo_cart_enabled( $s ) ) {
		return $fragments;
	}
	$fragments['div.menux-woo-cart'] = menux_woo_cart_inner_html( $s );
	return $fragments;
}
