"
function get_similarity_score($product_id_1, $product_id_2) {
	$cats_1 = wp_get_post_terms($product_id_1, 'product_cat', ['fields' => 'ids']);
	$tags_1 = wp_get_post_terms($product_id_1, 'product_tag', ['fields' => 'ids']);

	$cats_2 = wp_get_post_terms($product_id_2, 'product_cat', ['fields' => 'ids']);
	$tags_2 = wp_get_post_terms($product_id_2, 'product_tag', ['fields' => 'ids']);

	$cat_match = count(array_intersect($cats_1, $cats_2));
	$tag_match = count(array_intersect($tags_1, $tags_2));

	return ($cat_match * 2) + $tag_match;
}

// AJAX handler for product search
add_action('wp_ajax_search_products_for_comparison', 'search_products_for_comparison');
add_action('wp_ajax_nopriv_search_products_for_comparison', 'search_products_for_comparison');

function search_products_for_comparison() {
	check_ajax_referer('product_comparison_search', 'security');

	$query = sanitize_text_field($_POST['query']);
	$exclude_ids = isset($_POST['exclude']) ? array_map('absint', $_POST['exclude']) : [];

	// Get undefined category ID to exclude
	$undefined_cat = get_term_by('slug', 'undefined', 'product_cat');
	$undefined_cat_id = $undefined_cat ? $undefined_cat->term_id : 0;

	$args = [
		'post_type'      => 'product',
		'post_status'    => 'publish',
		'posts_per_page' => 10,
		's'              => $query,
		'post__not_in'   => $exclude_ids,
		'tax_query'      => [
			[
				'taxonomy' => 'product_cat',
				'field'    => 'id',
				'terms'    => $undefined_cat_id,
				'operator' => 'NOT IN',
			]
		]
	];

	$products = new WP_Query($args);
	$output = '';

	if ($products->have_posts()) {
		while ($products->have_posts()) {
			$products->the_post();
			$product = wc_get_product(get_the_ID());

			$output .= '<div class="search-result" style="padding: 8px; border-bottom: 1px solid #eee;">';

			$image = get_the_post_thumbnail(get_the_ID(), [40, 40]);
			if (!$image) {
				$image = '<img src="' . wc_placeholder_img_src() . '" alt="Placeholder" width="40" height="40">';
			}

			$output .= $image;
			$output .= '<span class="search-result-title">' . get_the_title() . '</span>';
			$output .= '<button class="add-to-comparison" data-product-id="' . get_the_ID() . '" style="margin-left: auto; background: #4CAF50; color: white; border: none; padding: 5px 10px; border-radius: 3px; cursor: pointer;">Tilføj</button>';
			$output .= '</div>';
		}
	} else {
		$output = '<div style="padding: 8px;">Ingen produkter fundet</div>';
	}

	echo $output;
	wp_die();
}

// Main comparison shortcode
function custom_auto_compare_products_columns_safe($atts) {
	// Basic checks
	if (!function_exists('wc_get_product')) {
		return '<p>WooCommerce is required for the product comparison.</p>';
	}

	if (!is_product()) {
		return '';
	}

	global $post;
	$product_id = $post->ID;
	$current_product = wc_get_product($product_id);

	if (!$current_product) {
		return '<p>Invalid product.</p>';
	}

	// Get fields from options or use defaults
	$fields_to_compare = get_option('product_comparison_fields', [
		'image', 'price', 'sku', 'height', 'width', 'length', 'lifting-capacity', 'max-height'
	]);

	// Get manually selected products from URL
	$selected_products = [];
	if (isset($_GET['compare_products']) && !empty($_GET['compare_products'])) {
		$product_ids = explode(',', sanitize_text_field($_GET['compare_products']));
		foreach ($product_ids as $pid) {
			$pid = absint($pid);
			if ($pid && $pid != $product_id) {
				$prod = wc_get_product($pid);
				if ($prod) {
					$selected_products[] = $pid;
				}
			}
		}
	}

	// If no manually selected products, get similar ones
	if (empty($selected_products)) {
		// Get undefined category ID to exclude
		$undefined_cat = get_term_by('slug', 'undefined', 'product_cat');
		$undefined_cat_id = $undefined_cat ? $undefined_cat->term_id : 0;

		$similar_products = [];
		$args = [
			'post_type'      => 'product',
			'post__not_in'   => [$product_id],
			'posts_per_page' => 100,
			'fields'         => 'ids',
			'tax_query'      => [
				[
					'taxonomy' => 'product_cat',
					'field'    => 'id',
					'terms'    => $undefined_cat_id,
					'operator' => 'NOT IN',
				]
			]
		];

		$products_query = new WP_Query($args);

		if ($products_query->have_posts()) {
			foreach ($products_query->posts as $other_id) {
				$score = get_similarity_score($product_id, $other_id);
				if ($score > 0) {
					$similar_products[$other_id] = $score;
				}
			}
			arsort($similar_products);
			$selected_products = array_slice(array_keys($similar_products), 0, 3);
		}

		// Fallback to random products if no similar ones found
		if (empty($selected_products)) {
			$fallback_query = new WP_Query([
				'post_type'      => 'product',
				'post__not_in'   => [$product_id],
				'posts_per_page' => 3,
				'orderby'        => 'rand',
				'fields'         => 'ids',
				'tax_query'      => [
					[
						'taxonomy' => 'product_cat',
						'field'    => 'id',
						'terms'    => $undefined_cat_id,
						'operator' => 'NOT IN',
					]
				]
			]);
			$selected_products = $fallback_query->posts;
		}

		wp_reset_postdata();
	}

	// Build the products array
	$products = [$current_product];
	foreach ($selected_products as $pid) {
		$prod = wc_get_product($pid);
		if ($prod) {
			$products[] = $prod;
		}
	}

	// Generate table ID
	$table_id = 'product-compare-' . $product_id;

	// CSS styles
	$styles = '
    <style>
        .auto-compare-table {
            width: 100%;
            overflow-x: auto;
            margin-bottom: 20px;
        }
        .auto-compare-table table {
            width: 100%;
            border-collapse: collapse;
            min-width: 600px;
        }
        .auto-compare-table th, 
        .auto-compare-table td {
            padding: 10px;
            border: 1px solid #e0e0e0;
            text-align: center;
        }
        .auto-compare-table th.product-column {
            position: relative;
        }
        .remove-product {
            position: absolute;
            top: 5px;
            right: 5px;
            width: 20px;
            height: 20px;
            background: #f44336;
            color: white;
            border-radius: 50%;
            font-size: 12px;
            line-height: 20px;
            text-align: center;
            cursor: pointer;
        }
        .add-product-column {
            cursor: pointer;
            background: #f5f5f5;
        }
        .product-search-bar .search-results .search-result {
            display: flex;
            align-content: center;
            align-items: center;
            gap: 20px;
        }
        .shadow {
            box-shadow: 0 2px 5px rgba(0,0,0,0.2);
        }
    </style>';

	// Start building table - add a wrapper div for the entire component
	$output = '<div id="product-comparison-wrapper-' . $product_id . '">' . $styles;

	// Add the actual table with its ID
	$output .= '<div class="auto-compare-table" id="' . esc_attr($table_id) . '"><table><thead><tr><th>Feature</th>';

	// Product IDs for JavaScript
	$js_product_ids = [$product_id];

	// Add product columns
	foreach ($products as $index => $product) {
		if ($index > 0) {
			$js_product_ids[] = $product->get_id();
			$output .= '<th class="product-column">';
			$output .= '<span class="remove-product" data-product-id="' . esc_attr($product->get_id()) . '">×</span>';
			$output .= '<a href="' . esc_url(get_permalink($product->get_id())) . '">' . esc_html($product->get_name()) . '</a>';
			$output .= '</th>';
		} else {
			$output .= '<th class="product-column"><a href="' . esc_url(get_permalink($product->get_id())) . '">' . esc_html($product->get_name()) . '</a></th>';
		}
	}

	// Add column for adding new products
	if (count($products) < 4) {
		$output .= '<th class="product-column add-product-column">+ Tilføj produkt</th>';
	}

	$output .= '</tr></thead><tbody>';

	// Add rows for each field
	foreach ($fields_to_compare as $field) {
		$field_name = ucfirst($field);
		$field_display_names = [
			'image' => 'Billede',
			'price' => 'Pris',
			'sku' => 'Varenummer',
			'height' => 'Højde',
			'width' => 'Bredde',
			'length' => 'Længde',
			'lifting-capacity' => 'Løftekapacitet',
			'max-height' => 'Maks højde',
			'weight' => 'Vægt',
		];

		if (isset($field_display_names[$field])) {
			$field_name = $field_display_names[$field];
		}

		$output .= '<tr><td>' . $field_name . '</td>';

		foreach ($products as $product) {
			$output .= '<td>';

			switch ($field) {
				case 'image':
					$image = $product->get_image([80, 80]);
					$output .= !empty($image) ? $image : '—';
					break;

				case 'price':
					$output .= $product->get_price_html();
					break;

				case 'sku':
					$output .= $product->get_sku() ?: '—';
					break;

				case 'height':
					$height = $product->get_height();
					$output .= !empty($height) ? $height . ' ' . get_option('woocommerce_dimension_unit') : '—';
					break;

				case 'width':
					$width = $product->get_width();
					$output .= !empty($width) ? $width . ' ' . get_option('woocommerce_dimension_unit') : '—';
					break;

				case 'length':
					$length = $product->get_length();
					$output .= !empty($length) ? $length . ' ' . get_option('woocommerce_dimension_unit') : '—';
					break;

				case 'weight':
					$weight = $product->get_weight();
					$output .= !empty($weight) ? $weight . ' ' . get_option('woocommerce_weight_unit') : '—';
					break;

				default:
					$meta = get_post_meta($product->get_id(), $field, true);
					$output .= !empty($meta) ? esc_html($meta) : '—';
					break;
			}

			$output .= '</td>';
		}

		// Add empty cell for the "add product" column
		if (count($products) < 4) {
			$output .= '<td>—</td>';
		}

		$output .= '</tr>';
	}

	$output .= '</tbody></table></div>'; // Close the table div

	// JavaScript for interactions - traditional approach with page reloads for reliability
	$output .= "
<script>
function initProductComparison() {
  jQuery(document).ready(function($) {
    var tableId = '" . esc_js($table_id) . "';
    var currentProductId = " . esc_js($product_id) . ";

    function renderComparisonTable(newCompareIds) {
      var wrapper = $('#product-comparison-wrapper-' + currentProductId);
      wrapper.css('position', 'relative');
              var overlay = $('<div class=\"loading-overlay\" style=\"position:absolute; top:0; left:0; right:0; bottom:0; background:rgba(255,255,255,0.7); z-index:1000; display:flex; align-items:center; justify-content:center; font-size:18px; font-weight:bold;\">Loading...</div>');
        wrapper.append(overlay);


      $.ajax({
        url: '" . admin_url('admin-ajax.php') . "',
        type: 'POST',
        data: {
          action: 'render_comparison_table',
          product_id: currentProductId,
          compare_ids: newCompareIds,
          security: '" . wp_create_nonce('product_comparison_render') . "'
        },
        success: function(response) {
          wrapper.replaceWith(response);
          // 👇 Re-run JS on the new HTML
          initProductComparison();
        }
      });
    }

    // Search UI
            var searchBar = $('<div class=\"product-search-bar\" style=\"display:none;\">' +
                         '<input type=\"text\" class=\"product-search\" placeholder=\"Søg efter produkter...\" style=\"width:100%; padding:8px; margin-bottom:10px;\">' +
                         '<div class=\"search-results shadow\" style=\"max-height:300px; overflow-y:auto; position: absolute; background: white; width: 100%; display: flex; flex-direction: column; gap: 5px; z-index: 20;\"></div>' +
                         '</div>');
 
        $('#' + tableId).before(searchBar);
 

    $('.add-product-column').on('click', function(e) {
      e.preventDefault();
      $('.product-search-bar').toggle();
      $('.product-search').focus().val('');
      $('.search-results').html('');
    });

    $('.product-search').on('keyup', function() {
      var query = $(this).val();
      if (query.length < 3) {
        $('.search-results').html('');
        return;
      }

     $('.search-results').html('<div style=\"padding: 8px;\">Søger...</div>');
      var exclude = [currentProductId];
      $('#' + tableId + ' .remove-product').each(function() {
        exclude.push(parseInt($(this).data('product-id')));
      });

      $.ajax({
        url: '" . admin_url('admin-ajax.php') . "',
        type: 'POST',
        data: {
          action: 'search_products_for_comparison',
          query: query,
          exclude: exclude,
          security: '" . wp_create_nonce('product_comparison_search') . "'
        },
        success: function(response) {
          $('.search-results').html(response);
        }
      });
    });

    $(document).on('click', '.add-to-comparison', function(e) {
      e.preventDefault();
      var productId = $(this).data('product-id');
      var compareIds = [];

      $('#' + tableId + ' .remove-product').each(function() {
        compareIds.push(parseInt($(this).data('product-id')));
      });

      compareIds.push(productId);
      renderComparisonTable(compareIds);
    });

    $(document).on('click', '.remove-product', function(e) {
      e.preventDefault();
      var productId = $(this).data('product-id');
      var newCompareIds = [];

      $('#' + tableId + ' .remove-product').each(function() {
        var id = parseInt($(this).data('product-id'));
        if (id !== productId) {
          newCompareIds.push(id);
        }
      });

      renderComparisonTable(newCompareIds);
    });
  });
}

// 👇 Run it the first time
initProductComparison();
</script>";

	$output .= '</div>'; // Close the wrapper div

	return $output;
}

add_shortcode('auto_compare_products', 'custom_auto_compare_products_columns_safe');

add_action('wp_ajax_render_comparison_table', 'ajax_render_comparison_table');

function ajax_render_comparison_table() {
	check_ajax_referer('product_comparison_render', 'security');

	$product_id = absint($_POST['product_id']);
	$compare_ids = isset($_POST['compare_ids']) ? array_map('absint', $_POST['compare_ids']) : [];

	// Regenerate table
	$_GET['compare_products'] = implode(',', $compare_ids);
	echo custom_auto_compare_products_columns_safe([]);
	wp_die();
}
"

This code works but the issue is that when I press "X" (or remove product) the table disappears after the 'loading' overlay, the table isnt being recreated or updated. can you fix it? please make sure your fix doesnt involve refreshing the page, i want it to be smooth.