<?php

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

class AIEO_DMM_Sticky_ATC extends AIEO_DMM_Module_Base {

    public function get_id()       { return 'sticky_atc'; }
    public function get_label()    { return __('Sticky Add to Cart', 'ai-eshop-optimizer'); }
    public function get_priority() { return 56; } 
    public function get_group()    { return 'visuals'; }

    
    private $hooked = false;

    
    private $settings_cache = null;

    public function register_hooks() {
        
        add_action('wp_ajax_aieo_dmm_sticky_atc_save_settings', array($this, 'ajax_save_settings'));

        
        if (!$this->is_enabled()) {
            return;
        }
        if ($this->hooked) {
            return;
        }
        $this->hooked = true;

        add_action('wp_enqueue_scripts', array($this, 'frontend_scripts'));
        add_action('wp_footer',          array($this, 'render_sticky_bar'), 50);
        add_filter('body_class',         array($this, 'add_body_classes'));

        if ($this->get('override_merchant') === 'yes') {
            add_action('init', array($this, 'disable_merchant_sticky'), 999);
        }

        
        
        add_action('wp_ajax_om_sticky_atc_get_product',        array($this, 'ajax_get_product_data'));
        add_action('wp_ajax_nopriv_om_sticky_atc_get_product', array($this, 'ajax_get_product_data'));
        add_action('wp_ajax_om_sticky_atc_check_cart',         array($this, 'ajax_check_product_in_cart'));
        add_action('wp_ajax_nopriv_om_sticky_atc_check_cart',  array($this, 'ajax_check_product_in_cart'));

        
        
        
        add_action('woocommerce_add_to_cart', array($this, 'log_attribution_for_satc_add'), 30, 6);
        
        
        
        add_filter('wc_add_to_cart_message_html',     array($this, 'maybe_suppress_satc_cart_message'),     10, 3);
        add_filter('woocommerce_add_success',         array($this, 'maybe_suppress_satc_cart_message'),     10, 1);
    }

    public function enqueue_admin_assets() {
        
        
        
        wp_enqueue_style('wp-color-picker');
        wp_enqueue_script('wp-color-picker');
        wp_add_inline_script('wp-color-picker',
            'jQuery(function($){$(".aieo-dmm-satc-color").wpColorPicker();});'
        );
    }

    public function render_subtab() {
        $this->render_template('sticky-add-to-cart.php', array(
            'settings' => $this->get_settings(),
            'module'   => $this,
        ));
    }

    
    
    

    
    public static function defaults() {
        return array(
            'satc_enabled' => 'no',
            'satc_position' => 'bottom',
            'satc_display_after_scroll' => 100,
            'satc_scroll_hide' => 'no',
            'satc_visibility' => 'all',
            'satc_persistent_enabled' => 'no',
            'satc_persistent_dismiss_text' => 'Dismiss',
            'satc_persistent_expire_hours' => 24,
            'satc_desktop_show_image' => 'yes',
            'satc_desktop_show_title' => 'yes',
            'satc_desktop_show_price' => 'yes',
            'satc_desktop_show_quantity' => 'yes',
            'satc_desktop_show_variations' => 'yes',
            'satc_desktop_layout' => 'inline',
            'satc_mobile_show_image' => 'yes',
            'satc_mobile_show_title' => 'yes',
            'satc_mobile_show_price' => 'yes',
            
            
            
            'satc_mobile_show_quantity' => 'no',
            'satc_mobile_show_variations' => 'yes',
            'satc_mobile_layout' => 'stacked',
            'satc_smart_variation_enabled' => 'yes',
            'satc_variation_threshold' => 6,
            
            
            
            
            
            'satc_many_vars_mode'      => 'dropdown',
            
            
            
            'satc_dropdown_placeholder' => '',
            'satc_swatch_limit_desktop' => 6,
            'satc_swatch_limit_mobile' => 3,
            'satc_show_selected_attrs' => 'yes',
            'satc_bar_padding' => 12,
            'satc_elements_spacing' => 15,
            'satc_border_width' => 1,
            'satc_border_color' => '#e0e0e0',
            'satc_background_color' => '#ffffff',
            'satc_text_color' => '#333333',
            'satc_title_color' => '#333333',
            'satc_price_color' => '#333333',
            
            
            'satc_button_bg_color' => '',
            'satc_button_bg_color_hover' => '',
            'satc_button_text_color' => '',
            'satc_button_text_color_hover' => '',
            'satc_button_border_radius' => 4,
            'satc_button_text' => '',
            'satc_use_theme_button' => 'yes',
            'satc_mobile_bar_padding' => 8,
            'satc_mobile_font_size' => 13,
            'satc_override_merchant' => 'yes',
            'satc_allow_third_party' => 'no',
        );
    }

    
    public function get_settings() {
        if ($this->settings_cache !== null) {
            return $this->settings_cache;
        }

        $defaults = self::defaults();

        
        $all = AIEO_DMM_Settings::get_all();
        $stored = array();
        foreach ($all as $k => $v) {
            if (strpos($k, 'satc_') === 0) {
                $stored[$k] = $v;
            }
        }

        
        
        
        if (empty($stored)) {
            $legacy = get_option('om_side_cart_settings', array());
            if (is_array($legacy)) {
                foreach ($legacy as $k => $v) {
                    if (strpos($k, 'satc_') === 0) {
                        $stored[$k] = $v;
                    }
                }
            }
        }

        $this->settings_cache = wp_parse_args($stored, $defaults);
        return $this->settings_cache;
    }

    
    public function get($key, $default = null) {
        if (strpos($key, 'satc_') !== 0) {
            $key = 'satc_' . $key;
        }
        $s = $this->get_settings();
        return array_key_exists($key, $s) ? $s[$key] : $default;
    }

    
    public function is_enabled() {
        if (!AIEO_DMM_Settings::is_module_enabled('sticky_atc')) {
            
            
            
        }
        return $this->get('enabled') === 'yes';
    }

    
    public function ajax_save_settings() {
        AIEO_DMM::verify_ajax_request();

        $defaults = self::defaults();
        $patch    = array();

        $bool_keys = array(
            'satc_enabled', 'satc_scroll_hide', 'satc_persistent_enabled',
            'satc_desktop_show_image', 'satc_desktop_show_title', 'satc_desktop_show_price',
            'satc_desktop_show_quantity', 'satc_desktop_show_variations',
            'satc_mobile_show_image', 'satc_mobile_show_title', 'satc_mobile_show_price',
            'satc_mobile_show_quantity', 'satc_mobile_show_variations',
            'satc_smart_variation_enabled', 'satc_show_selected_attrs',
            'satc_use_theme_button', 'satc_override_merchant', 'satc_allow_third_party',
        );
        foreach ($bool_keys as $k) {
            $patch[$k] = !empty($_POST[$k]) ? 'yes' : 'no';
        }

        $text_keys = array(
            'satc_position'                 => array('bottom', 'top'),
            'satc_visibility'               => array('all', 'desktop', 'mobile'),
            'satc_desktop_layout'           => array('inline', 'stacked'),
            'satc_mobile_layout'            => array('inline', 'stacked'),
            'satc_many_vars_mode'           => array('dropdown', 'hide', 'swatches'),
        );
        foreach ($text_keys as $k => $allowed) {
            $val = isset($_POST[$k]) ? sanitize_key(wp_unslash($_POST[$k])) : '';
            $patch[$k] = in_array($val, $allowed, true) ? $val : $defaults[$k];
        }

        $int_keys = array(
            'satc_display_after_scroll', 'satc_persistent_expire_hours',
            'satc_variation_threshold', 'satc_swatch_limit_desktop', 'satc_swatch_limit_mobile',
            'satc_bar_padding', 'satc_elements_spacing', 'satc_border_width',
            'satc_button_border_radius', 'satc_mobile_bar_padding', 'satc_mobile_font_size',
        );
        foreach ($int_keys as $k) {
            $patch[$k] = isset($_POST[$k]) ? max(0, absint($_POST[$k])) : $defaults[$k];
        }

        $color_keys = array(
            'satc_border_color', 'satc_background_color', 'satc_text_color', 'satc_title_color',
            'satc_price_color', 'satc_button_bg_color', 'satc_button_bg_color_hover',
            'satc_button_text_color', 'satc_button_text_color_hover',
        );
        foreach ($color_keys as $k) {
            $hex = isset($_POST[$k]) ? sanitize_hex_color(wp_unslash($_POST[$k])) : '';
            $patch[$k] = $hex ? $hex : $defaults[$k];
        }

        $string_keys = array('satc_persistent_dismiss_text', 'satc_button_text', 'satc_dropdown_placeholder');
        foreach ($string_keys as $k) {
            $patch[$k] = isset($_POST[$k]) ? sanitize_text_field(wp_unslash($_POST[$k])) : '';
        }

        AIEO_DMM_Settings::update($patch);

        
        
        $this->settings_cache = null;

        wp_send_json_success(array('message' => __('Sticky Add to Cart settings saved.', 'ai-eshop-optimizer')));
    }

    
    
    

    public function disable_merchant_sticky() {
        if (class_exists('Merchant_Modules')) {
            add_filter('merchant_module_sticky-add-to-cart_active', '__return_false');
        }

        global $wp_filter;
        if (isset($wp_filter['wp_footer'])) {
            foreach ($wp_filter['wp_footer']->callbacks as $priority => $callbacks) {
                foreach ($callbacks as $callback) {
                    if (is_array($callback['function']) && is_object($callback['function'][0])) {
                        $class_name = get_class($callback['function'][0]);
                        if (in_array($class_name, array('Merchant_Pro_Sticky_Add_To_Cart', 'Merchant_Sticky_Add_To_Cart'), true)) {
                            remove_action('wp_footer', $callback['function'], $priority);
                        }
                    }
                    if (is_array($callback['function']) && is_string($callback['function'][0])) {
                        if (in_array($callback['function'][0], array('Merchant_Pro_Sticky_Add_To_Cart', 'Merchant_Sticky_Add_To_Cart'), true)) {
                            remove_action('wp_footer', $callback['function'], $priority);
                        }
                    }
                }
            }
        }
    }

    
    
    

    public function ajax_check_product_in_cart() {
        $product_id = isset($_POST['product_id']) ? absint(wp_unslash($_POST['product_id'])) : 0;
        if (!$product_id) {
            wp_send_json_error(array('message' => __('Invalid product ID', 'ai-eshop-optimizer')));
        }

        $in_cart = false;
        if (function_exists('WC') && WC()->cart) {
            foreach (WC()->cart->get_cart() as $cart_item) {
                if ((int) $cart_item['product_id'] === $product_id
                    || (isset($cart_item['variation_id']) && (int) $cart_item['variation_id'] === $product_id)) {
                    $in_cart = true;
                    break;
                }
            }
        }
        wp_send_json_success(array('in_cart' => $in_cart));
    }

    public function ajax_get_product_data() {
        check_ajax_referer('om_sticky_atc', 'nonce');

        $product_id = absint($_POST['product_id'] ?? 0);
        if (!$product_id) {
            wp_send_json_error(array('message' => __('Invalid product ID', 'ai-eshop-optimizer')));
        }

        $product = wc_get_product($product_id);
        if (!$product) {
            wp_send_json_error(array('message' => __('Product not found', 'ai-eshop-optimizer')));
        }

        ob_start();
        $this->render_product_content($product);
        $html = ob_get_clean();

        wp_send_json_success(array(
            'html'    => $html,
            'product' => $this->get_product_js_data($product),
        ));
    }

    
    
    

    public function frontend_scripts() {
        if (!$this->is_enabled()) {
            return;
        }

        $should_load = is_product() || ($this->get('persistent_enabled') === 'yes');
        if (!$should_load) {
            return;
        }

        $css_path = AIEO_DIR . 'assets/css/aieo-sticky-add-to-cart.css';
        $css_ver  = file_exists($css_path) ? (string) filemtime($css_path) : AIEO_VERSION;
        wp_enqueue_style(
            'aieo-sticky-atc',
            AIEO_URI . 'assets/css/aieo-sticky-add-to-cart.css',
            array(),
            $css_ver
        );
        wp_add_inline_style('aieo-sticky-atc', $this->get_css_vars());

        $js_path = AIEO_DIR . 'assets/js/aieo-sticky-add-to-cart.js';
        $js_ver  = file_exists($js_path) ? (string) filemtime($js_path) : AIEO_VERSION;

        
        
        
        
        
        $iapi_on = method_exists('AIEO_DMM', 'is_iapi_enabled') && AIEO_DMM::is_iapi_enabled('sticky_atc');
        if ($iapi_on
            && function_exists('wp_enqueue_script_module')
            && defined('AIEO_RUNTIME_DIR')
            && file_exists(AIEO_RUNTIME_DIR . 'assets/js/aieo-sticky-atc-iapi.js')
        ) {
            wp_register_script_module(
                '@aieo/sticky-atc-iapi',
                AIEO_RUNTIME_URI . 'assets/js/aieo-sticky-atc-iapi.js',
                array('@wordpress/interactivity', '@aieo/iapi-bootstrap'),
                (string) filemtime(AIEO_RUNTIME_DIR . 'assets/js/aieo-sticky-atc-iapi.js')
            );
            wp_enqueue_script_module('@aieo/sticky-atc-iapi');
        } else {
            wp_enqueue_script(
                'aieo-sticky-atc',
                AIEO_URI . 'assets/js/aieo-sticky-add-to-cart.js',
                array('jquery'),
                $js_ver,
                true
            );
        }

        $product_data = array();
        if (is_product()) {
            global $product;
            $product_obj = $product;
            if ($product && !is_a($product, 'WC_Product')) {
                $product_obj = wc_get_product($product);
            }
            if ($product_obj && is_a($product_obj, 'WC_Product')) {
                $product_data = $this->get_product_js_data($product_obj);
            }
        }

        
        
        
        
        $multi_select_enabled = false;
        if (is_product() && function_exists('om_product_swatches')) {
            global $product;
            $is_variable = ($product && is_object($product) && method_exists($product, 'is_type') && $product->is_type('variable'));
            if ($is_variable) {
                $swatches = om_product_swatches();
                if (is_object($swatches) && method_exists($swatches, 'get')) {
                    $multi_select_enabled = (bool) $swatches->get('multi_select_enabled', false);
                }
            }
        }

        $sticky_data = array(
            'ajaxUrl'              => admin_url('admin-ajax.php'),
            'nonce'                => wp_create_nonce('om_sticky_atc'),
            'isProductPage'        => is_product(),
            'displayAfterScroll'   => $this->get('display_after_scroll'),
            'scrollHide'           => $this->get('scroll_hide') === 'yes',
            'position'             => $this->get('position'),
            'visibility'           => $this->get('visibility'),
            'persistentEnabled'    => $this->get('persistent_enabled') === 'yes',
            'persistentExpireHours' => $this->get('persistent_expire_hours'),
            'smartVariationEnabled' => $this->get('smart_variation_enabled') === 'yes',
            'variationThreshold'   => $this->get('variation_threshold'),
            'swatchLimitDesktop'   => absint($this->get('swatch_limit_desktop', 6)),
            'swatchLimitMobile'    => absint($this->get('swatch_limit_mobile', 3)),
            'showSelectedAttrs'    => $this->get('show_selected_attrs') === 'yes',
            'multiSelectEnabled'   => $multi_select_enabled,
            'productData'          => $product_data,
            'i18n' => array(
                'dismiss'           => $this->get('persistent_dismiss_text') ?: __('Dismiss', 'ai-eshop-optimizer'),
                'addToCart'         => $this->get('button_text') ?: __('Add to Cart', 'ai-eshop-optimizer'),
                'addSelectedToCart' => __('Add Selected to Cart', 'ai-eshop-optimizer'),
                'selectOptions'     => __('Select options', 'ai-eshop-optimizer'),
                'viewCart'          => __('View Cart', 'ai-eshop-optimizer'),
                'selected'          => __('selected', 'ai-eshop-optimizer'),
                'subtotal'          => __('Subtotal', 'ai-eshop-optimizer'),
            ),
        );

        if ($iapi_on) {
            
            
            
            
            add_action('wp_print_footer_scripts', static function () use ($sticky_data) {
                echo '<script id="aieo-sticky-atc-data">'
                    . 'window.omStickyATC = ' . wp_json_encode($sticky_data) . ';'
                    . '</script>' . "\n";
            }, 5);
        } else {
            
            wp_localize_script('aieo-sticky-atc', 'omStickyATC', $sticky_data);
        }
    }

    private function get_product_js_data($product) {
        if (!$product) {
            return array();
        }
        $data = array(
            'id'             => $product->get_id(),
            'name'           => $product->get_name(),
            'price'          => $product->get_price_html(),
            'type'           => $product->get_type(),
            'image'          => get_the_post_thumbnail_url($product->get_id(), 'thumbnail'),
            'url'            => $product->get_permalink(),
            'isVariable'     => $product->is_type('variable'),
            'variationCount' => 0,
        );
        if ($product->is_type('variable')) {
            $data['variationCount'] = count($product->get_children());
        }
        return $data;
    }

    private function get_css_vars() {
        $s = $this->get_settings();
        $d = self::defaults();

        
        
        
        
        $sanitize_size = function ($value, $default, $min = 1) {
            $value = (int) $value;
            return $value < $min ? (int) $default : $value;
        };
        $bar_padding    = $sanitize_size($s['satc_bar_padding'],         $d['satc_bar_padding']);
        $spacing        = $sanitize_size($s['satc_elements_spacing'],    $d['satc_elements_spacing']);
        $border_width   = (int) $s['satc_border_width']; 
        $btn_radius     = (int) $s['satc_button_border_radius']; 
        $mobile_padding = $sanitize_size($s['satc_mobile_bar_padding'],  $d['satc_mobile_bar_padding']);
        $mobile_font    = $sanitize_size($s['satc_mobile_font_size'],    $d['satc_mobile_font_size'], 10);

        
        
        
        
        $add_label = $this->get('button_text') ?: __('Add to cart', 'ai-eshop-optimizer');
        
        $add_label_css = '"' . str_replace(array('\\', '"'), array('\\\\', '\\"'), $add_label) . '"';
        
        
        
        $satc_btn_bg         = trim((string) $s['satc_button_bg_color'])         !== '' ? $s['satc_button_bg_color']         : 'var(--aieo-btn-bg,#212121)';
        $satc_btn_bg_hover   = trim((string) $s['satc_button_bg_color_hover'])   !== '' ? $s['satc_button_bg_color_hover']   : 'var(--aieo-btn-bg-hover,#757575)';
        $satc_btn_text       = trim((string) $s['satc_button_text_color'])       !== '' ? $s['satc_button_text_color']       : 'var(--aieo-btn-fg,#ffffff)';
        $satc_btn_text_hover = trim((string) $s['satc_button_text_color_hover']) !== '' ? $s['satc_button_text_color_hover'] : 'var(--aieo-btn-fg-hover,#ffffff)';
        return ":root{
            --om-satc-padding:{$bar_padding}px;
            --om-satc-spacing:{$spacing}px;
            --om-satc-border-width:{$border_width}px;
            --om-satc-border-color:{$s['satc_border_color']};
            --om-satc-bg-color:{$s['satc_background_color']};
            --om-satc-text-color:{$s['satc_text_color']};
            --om-satc-title-color:{$s['satc_title_color']};
            --om-satc-price-color:{$s['satc_price_color']};
            --om-satc-btn-bg:{$satc_btn_bg};
            --om-satc-btn-bg-hover:{$satc_btn_bg_hover};
            --om-satc-btn-text:{$satc_btn_text};
            --om-satc-btn-text-hover:{$satc_btn_text_hover};
            --om-satc-btn-radius:{$btn_radius}px;
            --om-satc-mobile-padding:{$mobile_padding}px;
            --om-satc-mobile-font:{$mobile_font}px;
            --aieo-satc-add-label:{$add_label_css};
        }";
    }

    public function add_body_classes($classes) {
        if (!$this->is_enabled()) {
            return $classes;
        }

        $visibility = $this->get('visibility');
        if ($visibility === 'desktop') {
            $classes[] = 'om-satc-desktop-only';
        } elseif ($visibility === 'mobile') {
            $classes[] = 'om-satc-mobile-only';
        }

        $classes[] = 'om-satc-position-' . $this->get('position');

        
        
        $is_multi_select_mode = false;
        if (is_product() && function_exists('om_product_swatches')) {
            global $product;
            $is_variable = ($product && is_object($product) && method_exists($product, 'is_type') && $product->is_type('variable'));
            if ($is_variable) {
                $swatches = om_product_swatches();
                if (is_object($swatches) && method_exists($swatches, 'get')) {
                    $is_multi_select_mode = (bool) $swatches->get('multi_select_enabled', false);
                }
            }
        }

        if (!$is_multi_select_mode && is_product() && $this->get('smart_variation_enabled') === 'yes') {
            global $product;
            if ($product && is_object($product) && method_exists($product, 'is_type') && $product->is_type('variable')) {
                $threshold       = (int) $this->get('variation_threshold');
                $variation_count = count($product->get_children());
                if ($variation_count > $threshold) {
                    $classes[] = 'om-satc-many-vars';
                    
                    
                    
                    
                    
                    
                    
                    
                    $many_vars_mode = (string) $this->get('many_vars_mode', 'dropdown');
                    if ($many_vars_mode === 'swatches') {
                        $classes[] = 'om-satc-pending';
                    }
                }
            }
        }

        return $classes;
    }

    
    
    

    public function render_sticky_bar() {
        if (!$this->is_enabled()) {
            return;
        }

        $is_product_page    = is_product();
        $persistent_enabled = $this->get('persistent_enabled') === 'yes';

        if (!$is_product_page && !$persistent_enabled) {
            return;
        }

        $position   = $this->get('position');
        $visibility = $this->get('visibility');

        $product = null;
        if ($is_product_page) {
            global $product;
        }

        
        
        
        if ($is_product_page && $product instanceof WC_Product
            && (!$product->is_purchasable() || !$product->is_in_stock())) {
            if (!$persistent_enabled) { return; }
            $is_product_page = false;
            $product         = null;
        }

        $data_attrs = array(
            'data-position'      => $position,
            'data-visibility'    => $visibility,
            'data-scroll-offset' => $this->get('display_after_scroll'),
            'data-persistent'    => $persistent_enabled ? '1' : '0',
        );
        $data_attrs_str = '';
        foreach ($data_attrs as $key => $value) {
            $data_attrs_str .= ' ' . esc_attr($key) . '="' . esc_attr($value) . '"';
        }

        $use_theme_button = $this->get('use_theme_button') === 'yes';
        $wrapper_classes  = array(
            'om-satc-wrapper',
            'om-satc-' . esc_attr($position),
            'om-satc-visibility-' . esc_attr($visibility),
            
            
            
            'om-satc-desktop-layout-' . sanitize_html_class((string) $this->get('desktop_layout')),
            'om-satc-mobile-layout-'  . sanitize_html_class((string) $this->get('mobile_layout')),
        );
        if (!$use_theme_button) {
            $wrapper_classes[] = 'om-satc-custom-btn';
        }
        ?>
        <!-- AIEO Sticky Add to Cart -->
        <div id="om-sticky-atc-wrapper"
             class="<?php echo esc_attr(implode(' ', $wrapper_classes)); ?>"
             <?php echo $data_attrs_str; ?>>
            <div class="om-satc-inner">
                <?php if ($is_product_page && $product) : ?>
                    <?php $this->render_product_content($product); ?>
                <?php elseif ($persistent_enabled) : ?>
                    <div class="om-satc-persistent-placeholder"></div>
                <?php endif; ?>
            </div>
            <?php if ($persistent_enabled) : ?>
            <button class="om-satc-dismiss" aria-label="<?php echo esc_attr($this->get('persistent_dismiss_text') ?: __('Dismiss', 'ai-eshop-optimizer')); ?>">
                <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                    <line x1="18" y1="6" x2="6" y2="18"></line>
                    <line x1="6" y1="6" x2="18" y2="18"></line>
                </svg>
            </button>
            <?php endif; ?>
        </div>
        <?php
    }

    private function render_product_content($product) {
        if (!$product) {
            return;
        }

        $product_id  = $product->get_id();
        $is_variable = $product->is_type('variable');

        $desktop_show_image    = $this->get('desktop_show_image') === 'yes';
        $desktop_show_title    = $this->get('desktop_show_title') === 'yes';
        $desktop_show_price    = $this->get('desktop_show_price') === 'yes';

        $mobile_show_image  = $this->get('mobile_show_image') === 'yes';
        $mobile_show_title  = $this->get('mobile_show_title') === 'yes';
        $mobile_show_price  = $this->get('mobile_show_price') === 'yes';

        ?>
        <?php
        
        
        
        
        
        $content_classes = 'om-satc-content om-satc-type-' . sanitize_html_class($product->get_type());
        ?>
        <div class="<?php echo esc_attr($content_classes); ?>" data-product-id="<?php echo esc_attr($product_id); ?>">

            <?php if ($desktop_show_image || $mobile_show_image) : ?>
            <div class="om-satc-image <?php echo !$desktop_show_image ? 'om-satc-hide-desktop' : ''; ?> <?php echo !$mobile_show_image ? 'om-satc-hide-mobile' : ''; ?>">
                <a href="<?php echo esc_url($product->get_permalink()); ?>">
                    <?php echo get_the_post_thumbnail($product_id, 'thumbnail'); ?>
                </a>
            </div>
            <?php endif; ?>

            <div class="om-satc-info">
                <?php if ($desktop_show_title || $mobile_show_title) : ?>
                <div class="om-satc-title <?php echo !$desktop_show_title ? 'om-satc-hide-desktop' : ''; ?> <?php echo !$mobile_show_title ? 'om-satc-hide-mobile' : ''; ?>">
                    <a href="<?php echo esc_url($product->get_permalink()); ?>">
                        <?php echo esc_html($product->get_name()); ?>
                    </a>
                </div>
                <?php endif; ?>

                <?php if ($is_variable && $this->get('show_selected_attrs') === 'yes') : ?>
                <div class="om-satc-attrs"></div>
                <?php endif; ?>

                <?php if ($desktop_show_price || $mobile_show_price) : ?>
                <div class="om-satc-price <?php echo !$desktop_show_price ? 'om-satc-hide-desktop' : ''; ?> <?php echo !$mobile_show_price ? 'om-satc-hide-mobile' : ''; ?>">
                    <?php
                    
                    
                    
                    
                    $GLOBALS['aieo_satc_suppress_login_message'] = true;
                    echo wp_kses_post($product->get_price_html());
                    unset($GLOBALS['aieo_satc_suppress_login_message']);
                    ?>
                </div>
                <?php endif; ?>
            </div>

            <div class="om-satc-form">
                <?php echo $this->get_add_to_cart_form($product); ?>
            </div>
        </div>
        <?php
    }

    private function get_add_to_cart_form($product) {
        if (!$product) {
            return '';
        }

        
        
        
        $desktop_qty   = $this->get('desktop_show_quantity') === 'yes';
        $mobile_qty    = $this->get('mobile_show_quantity')  === 'yes';
        $hide_quantity = (!$desktop_qty && !$mobile_qty);
        $qty_hide_cls  = '';
        if (!$desktop_qty) { $qty_hide_cls .= ' om-satc-hide-desktop'; }
        if (!$mobile_qty)  { $qty_hide_cls .= ' om-satc-hide-mobile'; }
        $qty_hide_cls  = trim($qty_hide_cls);

        ob_start();
        switch ($product->get_type()) {
            case 'simple':
                $this->render_simple_add_to_cart($product, $hide_quantity, $qty_hide_cls);
                break;
            case 'variable':
                $this->render_variable_add_to_cart($product, $hide_quantity, $qty_hide_cls);
                break;
            case 'grouped':
                $this->render_grouped_add_to_cart($product);
                break;
            case 'external':
                $this->render_external_add_to_cart($product);
                break;
            default:
                woocommerce_template_single_add_to_cart();
                break;
        }
        return ob_get_clean();
    }

    
    public function maybe_suppress_satc_cart_message($message ) {
        if (isset($_REQUEST['aieo_satc_source']) && $_REQUEST['aieo_satc_source'] === 'sticky_atc') {
            return '';
        }
        return $message;
    }

    
    public function log_attribution_for_satc_add($cart_item_key, $product_id, $quantity, $variation_id, $variation, $cart_item_data) {
        if (!isset($_REQUEST['aieo_satc_source']) || $_REQUEST['aieo_satc_source'] !== 'sticky_atc') {
            return;
        }
        
        
        
        
        if (function_exists('WC') && WC()->cart && $cart_item_key && isset(WC()->cart->cart_contents[$cart_item_key])) {
            WC()->cart->cart_contents[$cart_item_key]['aieo_attribution_source'] = 'sticky_atc';
        }
        if (!class_exists('AIEO_Attribution')) { return; }
        $attribution = AIEO_Attribution::instance();
        if (!is_object($attribution) || !method_exists($attribution, 'log_event')) {
            return;
        }
        $product = wc_get_product((int) $product_id);
        if (!$product) { return; }
        $unit_price = (float) $product->get_price();
        if ($variation_id && ($v = wc_get_product((int) $variation_id))) {
            $unit_price = (float) $v->get_price();
        }
        $attribution->log_event(array(
            'product_id'   => (int) $product_id,
            'variation_id' => (int) $variation_id,
            'quantity'     => max(1, (int) $quantity),
            'unit_price'   => $unit_price,
            'source'       => 'sticky_atc',
            'source_pid'   => (int) $product_id,
        ));
    }

    
    private function render_satc_quantity_input($product, $extra_class = '') {
        
        $max = (int) apply_filters('woocommerce_quantity_input_max', -1, $product);
        $min = 1;
        $val = 1;
        $cls = trim('quantity om-satc-qty ' . $extra_class);
        ?>
        <div class="<?php echo esc_attr($cls); ?>">
            <button type="button" class="om-satc-qty-minus" aria-label="<?php esc_attr_e('Decrease quantity', 'ai-eshop-optimizer'); ?>">&minus;</button>
            <input type="number"
                   class="input-text qty text"
                   name="quantity"
                   value="<?php echo esc_attr($val); ?>"
                   min="<?php echo esc_attr($min); ?>"
                   <?php if ($max > 0) : ?>max="<?php echo esc_attr($max); ?>"<?php endif; ?>
                   step="1"
                   inputmode="numeric"
                   autocomplete="off"
                   aria-label="<?php esc_attr_e('Quantity', 'ai-eshop-optimizer'); ?>">
            <button type="button" class="om-satc-qty-plus" aria-label="<?php esc_attr_e('Increase quantity', 'ai-eshop-optimizer'); ?>">&plus;</button>
        </div>
        <?php
    }

    private function render_simple_add_to_cart($product, $hide_quantity = false, $qty_hide_cls = '') {
        if (!$product->is_purchasable() || !$product->is_in_stock()) {
            echo '<p class="stock out-of-stock">' . esc_html__('Out of stock', 'ai-eshop-optimizer') . '</p>';
            return;
        }

        
        
        
        $button_text = $this->get('button_text') ?: __('Add to cart', 'ai-eshop-optimizer');
        ?>
        <form class="om-satc-simple-form cart" method="post" enctype="multipart/form-data">
            <input type="hidden" name="aieo_satc_source" value="sticky_atc">
            <?php if (!$hide_quantity) : ?>
                <?php $this->render_satc_quantity_input($product, $qty_hide_cls); ?>
            <?php endif; ?>
            <button type="submit" name="add-to-cart" value="<?php echo esc_attr($product->get_id()); ?>"
                    class="single_add_to_cart_button button alt<?php echo function_exists('wc_wp_theme_get_element_class_name') && wc_wp_theme_get_element_class_name('button') ? ' ' . esc_attr(wc_wp_theme_get_element_class_name('button')) : ''; ?>">
                <?php echo esc_html($button_text); ?>
            </button>
            <input type="hidden" name="add-to-cart" value="<?php echo esc_attr($product->get_id()); ?>">
        </form>
        <?php
    }

    private function render_variable_add_to_cart($product, $hide_quantity = false, $qty_hide_cls = '') {
        if (!$product->is_purchasable()) {
            return;
        }

        
        
        $button_text = $this->get('button_text') ?: __('Add to cart', 'ai-eshop-optimizer');

        
        
        
        
        $threshold       = max(1, (int) $this->get('variation_threshold', 6));
        $variation_count = count($product->get_children());
        $is_many_vars    = ($variation_count > $threshold);
        $many_vars_mode  = (string) $this->get('many_vars_mode', 'dropdown'); 

        if ($is_many_vars && $many_vars_mode === 'hide') {
            return; 
        }

        $use_dropdown = ($is_many_vars && $many_vars_mode === 'dropdown');
        ?>
        <form class="om-satc-variable-form variations_form cart <?php echo $use_dropdown ? 'om-satc-dropdown-vars' : 'om-satc-inline-vars'; ?>"
              method="post" enctype="multipart/form-data"
              data-product_id="<?php echo esc_attr($product->get_id()); ?>">

            <input type="hidden" name="aieo_satc_source" value="sticky_atc">

            <?php
            if ($use_dropdown) {
                $this->render_variation_dropdown($product);
            } else {
                $this->render_inline_variation_swatches($product);
            }
            ?>

            <div class="single_variation_wrap">
                <?php if (!$hide_quantity) : ?>
                <?php $this->render_satc_quantity_input($product, $qty_hide_cls); ?>
                <?php endif; ?>

                <button type="submit" class="single_add_to_cart_button button alt disabled wc-variation-selection-needed<?php echo function_exists('wc_wp_theme_get_element_class_name') && wc_wp_theme_get_element_class_name('button') ? ' ' . esc_attr(wc_wp_theme_get_element_class_name('button')) : ''; ?>">
                    <?php echo esc_html($button_text); ?>
                </button>

                <input type="hidden" name="add-to-cart" value="<?php echo esc_attr($product->get_id()); ?>">
                <input type="hidden" name="product_id" value="<?php echo esc_attr($product->get_id()); ?>">
                <input type="hidden" name="variation_id" class="variation_id" value="">
            </div>
        </form>
        <?php
    }

    
    private function render_variation_dropdown($product) {
        $variations  = $product->get_available_variations();
        
        
        $placeholder = (string) $this->get('dropdown_placeholder', '');
        if ($placeholder === '') {
            $placeholder = __('Choose a variation…', 'ai-eshop-optimizer');
        }
        ?>
        <select class="om-satc-variation-select variation_id" data-product-id="<?php echo esc_attr($product->get_id()); ?>" aria-label="<?php echo esc_attr($placeholder); ?>">
            <option value="" data-attributes=""><?php echo esc_html($placeholder); ?></option>
            <?php
            foreach ((array) $variations as $variation) {
                $vid = isset($variation['variation_id']) ? (int) $variation['variation_id'] : 0;
                if ($vid <= 0) { continue; }
                if (empty($variation['is_purchasable']) || empty($variation['is_in_stock'])) { continue; }

                
                $parts = array();
                if (!empty($variation['attributes']) && is_array($variation['attributes'])) {
                    foreach ($variation['attributes'] as $attr_name => $attr_value) {
                        if ($attr_value === '' || $attr_value === null) { continue; }
                        $taxonomy = str_replace('attribute_', '', $attr_name);
                        $label    = $attr_value;
                        if (taxonomy_exists($taxonomy)) {
                            $term = get_term_by('slug', $attr_value, $taxonomy);
                            if ($term && !is_wp_error($term)) {
                                $label = $term->name;
                            }
                        }
                        $parts[] = $label;
                    }
                }
                $text = implode(' / ', $parts);
                if ($text === '') { $text = '#' . $vid; }

                
                
                $attrs_json = isset($variation['attributes']) ? wp_json_encode($variation['attributes']) : '{}';
                ?>
                <option value="<?php echo esc_attr($vid); ?>"
                        data-attributes="<?php echo esc_attr($attrs_json); ?>">
                    <?php echo esc_html($text); ?>
                </option>
                <?php
            }
            ?>
        </select>
        <?php
    }

    
    private function render_inline_variation_swatches($product) {
        $product_id = $product->get_id();
        $attributes = $product->get_variation_attributes();

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

        $desktop_limit = absint($this->get('swatch_limit_desktop', 6));
        $mobile_limit  = absint($this->get('swatch_limit_mobile', 3));

        $attribute_types      = array();
        $attribute_taxonomies = wc_get_attribute_taxonomies();
        foreach ($attribute_taxonomies as $tax) {
            $attribute_types['pa_' . $tax->attribute_name] = $tax->attribute_type;
        }

        $primary_attribute = null;
        $primary_terms     = array();
        $attribute_type    = 'image';

        foreach ($attributes as $attribute_name => $options) {
            $taxonomy = strpos($attribute_name, 'pa_') === 0 ? $attribute_name : 'pa_' . $attribute_name;
            if (taxonomy_exists($taxonomy)) {
                $detected_type = isset($attribute_types[$taxonomy]) ? $attribute_types[$taxonomy] : 'select';
                if ($detected_type === 'color' || $detected_type === 'image') {
                    $attribute_type    = $detected_type;
                    $primary_attribute = $taxonomy;
                    $all_terms = get_terms(array('taxonomy' => $taxonomy, 'hide_empty' => false));
                    if (!is_wp_error($all_terms)) {
                        foreach ($all_terms as $term) {
                            if (in_array($term->slug, $options, true)) {
                                $primary_terms[] = $term;
                            }
                        }
                    }
                    break;
                }
            }
            if ($primary_attribute === null) {
                $primary_attribute = $attribute_name;
            }
        }

        $total_terms       = count($primary_terms);
        $desktop_remaining = max(0, $total_terms - $desktop_limit);
        $mobile_remaining  = max(0, $total_terms - $mobile_limit);

        ?>
        <div class="om-satc-inline-swatches"
             data-product-id="<?php echo esc_attr($product_id); ?>"
             data-desktop-limit="<?php echo esc_attr($desktop_limit); ?>"
             data-mobile-limit="<?php echo esc_attr($mobile_limit); ?>"
             data-total-terms="<?php echo esc_attr($total_terms); ?>">
            <?php
            if (($attribute_type === 'color' || $attribute_type === 'wc-visual') && !empty($primary_terms)) {
                $count = 0;
                foreach ($primary_terms as $term) {
                    $all_meta = get_term_meta($term->term_id);
                    
                    
                    
                    
                    
                    $color_type = isset($all_meta['_aieo_swatch_color_type'][0])
                        ? $all_meta['_aieo_swatch_color_type'][0]
                        : (isset($all_meta['product_attribute_color_type'][0]) ? $all_meta['product_attribute_color_type'][0] : '');
                    $style      = '';

                    if ('gradient' === $color_type) {
                        $payload = isset($all_meta['_aieo_swatch_gradient'][0]) ? maybe_unserialize($all_meta['_aieo_swatch_gradient'][0]) : array();
                        $color_1   = (is_array($payload) && isset($payload['color_1'])) ? $payload['color_1']
                            : (isset($all_meta['product_attribute_color_gradient_color_1'][0]) ? $all_meta['product_attribute_color_gradient_color_1'][0] : '');
                        $color_2   = (is_array($payload) && isset($payload['color_2'])) ? $payload['color_2']
                            : (isset($all_meta['product_attribute_color_gradient_color_2'][0]) ? $all_meta['product_attribute_color_gradient_color_2'][0] : '');
                        $direction = (is_array($payload) && isset($payload['direction'])) ? $payload['direction']
                            : (isset($all_meta['product_attribute_color_gradient_direction'][0]) ? $all_meta['product_attribute_color_gradient_direction'][0] : 'to bottom');
                        $style     = 'background: linear-gradient(' . esc_attr($direction) . ',' . esc_attr($color_1) . ' 0%,' . esc_attr($color_2) . ' 100%);';
                    } elseif ('multiple' === $color_type) {
                        $payload = isset($all_meta['_aieo_swatch_multiple'][0]) ? maybe_unserialize($all_meta['_aieo_swatch_multiple'][0]) : array();
                        if (is_array($payload) && !empty($payload['colors']) && is_array($payload['colors'])) {
                            $colors    = array_values(array_filter(array_map('strval', $payload['colors'])));
                            $direction = isset($payload['direction']) ? $payload['direction'] : 'to bottom';
                        } else {
                            $colors = array_values(array_filter(array(
                                isset($all_meta['product_attribute_color_multiple_color_1'][0]) ? $all_meta['product_attribute_color_multiple_color_1'][0] : '',
                                isset($all_meta['product_attribute_color_multiple_color_2'][0]) ? $all_meta['product_attribute_color_multiple_color_2'][0] : '',
                                isset($all_meta['product_attribute_color_multiple_color_3'][0]) ? $all_meta['product_attribute_color_multiple_color_3'][0] : '',
                                isset($all_meta['product_attribute_color_multiple_color_4'][0]) ? $all_meta['product_attribute_color_multiple_color_4'][0] : '',
                            )));
                            $direction = isset($all_meta['product_attribute_color_multiple_direction'][0]) ? $all_meta['product_attribute_color_multiple_direction'][0] : 'to bottom';
                        }
                        if (count($colors) === 1) {
                            $style = sprintf('background-color: %s;', $colors[0]);
                        } elseif (count($colors) === 2) {
                            $style = sprintf('background: linear-gradient(%s, %s 50%%, %s 50%%);', $direction, $colors[0], $colors[1]);
                        } elseif (count($colors) === 3) {
                            $style = sprintf('background: linear-gradient(%s, %s 33.333%%, %s 33.333%% 66.666%%, %s 66.666%% 100%%);', $direction, $colors[0], $colors[1], $colors[2]);
                        } elseif (count($colors) >= 4) {
                            $style  = sprintf('background: linear-gradient(135deg, %1$s, %1$s), linear-gradient(135deg, %2$s, %2$s), linear-gradient(225deg, %3$s, %3$s), linear-gradient(225deg, %4$s, %4$s);', $colors[0], $colors[1], $colors[2], $colors[3]);
                            $style .= 'background-position: 0% 0%, 0% 100%, 100% 0%, 100% 100%;';
                            $style .= 'background-size: 50% 50%;';
                            $style .= 'background-repeat: no-repeat;';
                        }
                    } else {
                        $color = isset($all_meta['color'][0]) ? $all_meta['color'][0]
                            : (isset($all_meta['product_attribute_color'][0]) ? $all_meta['product_attribute_color'][0] : '');
                        $style = 'background-color: ' . esc_attr($color) . ';';
                    }

                    $variation_id = $this->get_variation_id_for_term($product, $primary_attribute, $term->slug);

                    $item_classes = array('om-satc-swatch-item', 'om-satc-swatch-color');
                    if ($count >= $mobile_limit)  { $item_classes[] = 'om-satc-hide-mobile'; }
                    if ($count >= $desktop_limit) { $item_classes[] = 'om-satc-hide-desktop'; }
                    ?>
                    <div class="<?php echo esc_attr(implode(' ', $item_classes)); ?>"
                         data-attribute="<?php echo esc_attr($primary_attribute); ?>"
                         data-value="<?php echo esc_attr($term->slug); ?>"
                         data-variation-id="<?php echo esc_attr($variation_id); ?>"
                         title="<?php echo esc_attr($term->name); ?>">
                        <span class="om-satc-swatch-color-inner" style="<?php echo esc_attr($style); ?>"></span>
                    </div>
                    <?php
                    $count++;
                }

                if ($desktop_remaining > 0 || $mobile_remaining > 0) :
                ?>
                <span class="om-satc-more-indicator <?php echo $desktop_remaining <= 0 ? 'om-satc-hide-desktop' : ''; ?> <?php echo $mobile_remaining <= 0 ? 'om-satc-hide-mobile' : ''; ?>"
                      data-desktop-remaining="<?php echo esc_attr($desktop_remaining); ?>"
                      data-mobile-remaining="<?php echo esc_attr($mobile_remaining); ?>">
                    <span class="om-satc-more-desktop">+<?php echo esc_html($desktop_remaining); ?></span>
                    <span class="om-satc-more-mobile">+<?php echo esc_html($mobile_remaining); ?></span>
                </span>
                <?php endif;
            } elseif ($attribute_type === 'image' && !empty($primary_terms)) {
                $count = 0;
                foreach ($primary_terms as $term) {
                    
                    
                    $image_id = (int) get_term_meta($term->term_id, '_aieo_swatch_image_id', true);
                    if ($image_id <= 0) {
                        $image_id = (int) get_term_meta($term->term_id, 'product_attribute_image', true);
                    }
                    $image_id     = (int) apply_filters('aieo_swatch_image_id_for_term', $image_id, (int) $term->term_id, (string) $primary_attribute);
                    $variation_id = $this->get_variation_id_for_term($product, $primary_attribute, $term->slug);
                    $img_url      = '';

                    if ($image_id) {
                        $img_url = wp_get_attachment_image_url($image_id, 'thumbnail');
                    }
                    if (empty($img_url) && $variation_id) {
                        $variation_obj = wc_get_product($variation_id);
                        if ($variation_obj) {
                            $var_image_id = $variation_obj->get_image_id();
                            $img_url      = $var_image_id ? wp_get_attachment_image_url($var_image_id, 'thumbnail') : wc_placeholder_img_src('thumbnail');
                        }
                    }
                    if (empty($img_url)) {
                        $img_url = wc_placeholder_img_src('thumbnail');
                    }

                    $item_classes = array('om-satc-swatch-item', 'om-satc-swatch-image');
                    if ($count >= $mobile_limit)  { $item_classes[] = 'om-satc-hide-mobile'; }
                    if ($count >= $desktop_limit) { $item_classes[] = 'om-satc-hide-desktop'; }
                    ?>
                    <div class="<?php echo esc_attr(implode(' ', $item_classes)); ?>"
                         data-attribute="<?php echo esc_attr($primary_attribute); ?>"
                         data-value="<?php echo esc_attr($term->slug); ?>"
                         data-variation-id="<?php echo esc_attr($variation_id); ?>"
                         title="<?php echo esc_attr($term->name); ?>">
                        <img src="<?php echo esc_url($img_url); ?>" alt="<?php echo esc_attr($term->name); ?>">
                    </div>
                    <?php
                    $count++;
                }

                if ($desktop_remaining > 0 || $mobile_remaining > 0) :
                ?>
                <span class="om-satc-more-indicator <?php echo $desktop_remaining <= 0 ? 'om-satc-hide-desktop' : ''; ?> <?php echo $mobile_remaining <= 0 ? 'om-satc-hide-mobile' : ''; ?>"
                      data-desktop-remaining="<?php echo esc_attr($desktop_remaining); ?>"
                      data-mobile-remaining="<?php echo esc_attr($mobile_remaining); ?>">
                    <span class="om-satc-more-desktop">+<?php echo esc_html($desktop_remaining); ?></span>
                    <span class="om-satc-more-mobile">+<?php echo esc_html($mobile_remaining); ?></span>
                </span>
                <?php endif;
            } else {
                $cached_data = $this->get_om_swatch_cache($product_id);
                $variations  = $cached_data ?: $product->get_available_variations();

                $available_variations = array_filter($variations, function ($v) {
                    $is_available = isset($v['available']) ? $v['available'] : (!empty($v['is_purchasable']) && !empty($v['is_in_stock']));
                    return isset($v['variation_id']) && $v['variation_id'] && $is_available;
                });
                $fallback_total            = count($available_variations);
                $fallback_desktop_remaining = max(0, $fallback_total - $desktop_limit);
                $fallback_mobile_remaining  = max(0, $fallback_total - $mobile_limit);

                $count = 0;
                foreach ($variations as $variation) {
                    $variation_id = isset($variation['variation_id']) ? $variation['variation_id'] : 0;
                    $is_available = isset($variation['available']) ? $variation['available'] : (!empty($variation['is_purchasable']) && !empty($variation['is_in_stock']));
                    if (!$variation_id || !$is_available) {
                        continue;
                    }

                    $img_url = '';
                    if (isset($variation['img_url'])) {
                        $img_url = $variation['img_url'];
                    } else {
                        $variation_obj = wc_get_product($variation_id);
                        if ($variation_obj) {
                            $image_id = $variation_obj->get_image_id();
                            $img_url  = $image_id ? wp_get_attachment_image_url($image_id, 'thumbnail') : wc_placeholder_img_src('thumbnail');
                        }
                    }

                    $variation_label = isset($variation['base']) ? $variation['base'] : '';
                    if (empty($variation_label) && isset($variation['attributes'])) {
                        $attr_values = array();
                        foreach ($variation['attributes'] as $attr_name => $attr_value) {
                            if ($attr_value) {
                                $taxonomy = str_replace('attribute_', '', $attr_name);
                                if (taxonomy_exists($taxonomy)) {
                                    $term          = get_term_by('slug', $attr_value, $taxonomy);
                                    $attr_values[] = $term ? $term->name : $attr_value;
                                } else {
                                    $attr_values[] = $attr_value;
                                }
                            }
                        }
                        $variation_label = implode(' / ', $attr_values);
                    }

                    $item_classes = array('om-satc-swatch-item', 'om-satc-swatch-image');
                    if ($count >= $mobile_limit)  { $item_classes[] = 'om-satc-hide-mobile'; }
                    if ($count >= $desktop_limit) { $item_classes[] = 'om-satc-hide-desktop'; }
                    ?>
                    <div class="<?php echo esc_attr(implode(' ', $item_classes)); ?>"
                         data-variation-id="<?php echo esc_attr($variation_id); ?>"
                         data-variation="<?php echo esc_attr(wp_json_encode($variation)); ?>"
                         title="<?php echo esc_attr($variation_label); ?>">
                        <img src="<?php echo esc_url($img_url); ?>" alt="<?php echo esc_attr($variation_label); ?>">
                    </div>
                    <?php
                    $count++;
                }

                if ($fallback_desktop_remaining > 0 || $fallback_mobile_remaining > 0) :
                ?>
                <span class="om-satc-more-indicator <?php echo $fallback_desktop_remaining <= 0 ? 'om-satc-hide-desktop' : ''; ?> <?php echo $fallback_mobile_remaining <= 0 ? 'om-satc-hide-mobile' : ''; ?>"
                      data-desktop-remaining="<?php echo esc_attr($fallback_desktop_remaining); ?>"
                      data-mobile-remaining="<?php echo esc_attr($fallback_mobile_remaining); ?>">
                    <span class="om-satc-more-desktop">+<?php echo esc_html($fallback_desktop_remaining); ?></span>
                    <span class="om-satc-more-mobile">+<?php echo esc_html($fallback_mobile_remaining); ?></span>
                </span>
                <?php endif;
            }
            ?>
        </div>
        <?php
    }

    
    private function get_om_swatch_cache($product_id) {
        if (!class_exists('OM_Product_Swatches_Cache')) {
            return false;
        }

        $cache_key = "om_swatch_archive_{$product_id}";
        $cached    = OM_Product_Swatches_Cache::get($cache_key);
        if ($cached !== false) {
            return $cached;
        }

        $index_key  = "om_swatch_archive_{$product_id}_index";
        $index_data = OM_Product_Swatches_Cache::get($index_key);
        if ($index_data === false || empty($index_data['ids'])) {
            return false;
        }

        $variation_data = array();
        foreach ($index_data['ids'] as $variation_id) {
            $var_key  = "om_swatch_archive_{$product_id}_var_{$variation_id}";
            $var_data = OM_Product_Swatches_Cache::get($var_key);
            if ($var_data !== false) {
                $variation_data[] = $var_data;
            }
        }
        return !empty($variation_data) ? $variation_data : false;
    }

    private function get_variation_id_for_term($product, $attribute, $term_slug) {
        $variation_ids = $product->get_children();
        $attribute_key = 'attribute_' . sanitize_title($attribute);

        foreach ($variation_ids as $variation_id) {
            $variation = wc_get_product($variation_id);
            if (!$variation) {
                continue;
            }
            $attributes = $variation->get_attributes();
            if (isset($attributes[sanitize_title($attribute)]) && $attributes[sanitize_title($attribute)] === $term_slug) {
                return $variation_id;
            }
            $meta_value = get_post_meta($variation_id, $attribute_key, true);
            if ($meta_value === $term_slug) {
                return $variation_id;
            }
        }
        return 0;
    }

    private function render_grouped_add_to_cart($product) {
        ?>
        <a href="<?php echo esc_url($product->get_permalink()); ?>" class="button alt">
            <?php echo esc_html__('View products', 'ai-eshop-optimizer'); ?>
        </a>
        <?php
    }

    private function render_external_add_to_cart($product) {
        $button_text = $product->single_add_to_cart_text();
        ?>
        <a href="<?php echo esc_url($product->get_product_url()); ?>"
           class="single_add_to_cart_button button alt"
           target="_blank" rel="noopener">
            <?php echo esc_html($button_text); ?>
        </a>
        <?php
    }
}
