<?php


// archive override
function wcpt_archive_override($sc_args = [])
{
  if (!class_exists('WooCommerce')) {
    return false;
  }

  // shortcode attributes
  $wcpt_table_id = '';
  $wcpt_custom_table = false;
  $category = '';
  $tag = '';
  $attribute = '';
  $taxonomy = '';
  $_taxonomy = '';
  $_term = '';
  $page = '';
  $search = '';
  if (get_query_var('paged') !== 1) {
    $page = " page='" . get_query_var('paged') . "' ";
  }

  // get global settings
  $wcpt_settings = wcpt_get_settings_data();

  if (!empty($wcpt_settings['archive_override'])) {

    // get global default
    if (empty($wcpt_settings['archive_override']['default'])) {
      $wcpt_settings['archive_override']['default'] = '';
    }

    $wcpt_table_id = $wcpt_settings['archive_override']['default'];
    if ($wcpt_table_id == 'custom') {
      $wcpt_custom_table = $wcpt_settings['archive_override']['default_custom'];
    }

    // search
    if (is_search()) {
      // Product search results page
      global $wp_query;
      $search = " _search='" . get_query_var("s") . "' ";
      $archive = ' _archive="search" ';

      // search archive override table
      extract(wcpt_archive_override__get_table_vars('search'));

    }

    // category
    if (is_product_category()) {
      $term = get_query_var('term') ? get_query_var('term') : get_query_var('product_cat');
      $category = " category='" . esc_attr($term) . "' ";

      // category archive override table
      extract(wcpt_archive_override__get_table_vars('category', $term));

      $tag = '';
      $attribute = '';

    }

    // shop
    if (
      is_shop() &&
      !is_search()
    ) {

      // shop archive override table
      extract(wcpt_archive_override__get_table_vars('shop'));

      $category = '';
      $tag = '';
      $attribute = '';
      $archive = ' _archive="shop" ';

      // tag
    } else if (is_product_tag()) {
      $term = get_query_var('term');
      $tag = " taxonomy='product_tag:" . esc_attr($term) . "' ";

      // tag archive override table
      extract(wcpt_archive_override__get_table_vars('tag', $term));

      $category = '';
      $attribute = '';

      // brand
    } else if (
      taxonomy_exists('product_brand') && // Check if brand taxonomy exists
      is_tax('product_brand') // Check if we're on a brand taxonomy archive
    ) {
      $term = get_query_var('term');
      $tag = " taxonomy='product_brand:" . esc_attr($term) . "' ";

      // brand archive override table
      extract(wcpt_archive_override__get_table_vars('brand', $term));

      $category = '';
      $attribute = '';

      // attribute
    } else if (
      taxonomy_is_product_attribute(get_query_var('taxonomy', false))
    ) {
      $_taxonomy = get_query_var('taxonomy', false);
      $_attribute = substr($_taxonomy, 0, 3) === 'pa_' ? substr($_taxonomy, 3) : $_taxonomy;

      // $attr_label = wc_attribute_label($_taxonomy);
      $attr_label = $_taxonomy;

      if (function_exists('icl_object_id')) { // WPML
        $slug = wc_attribute_taxonomy_slug($_taxonomy);
        // $all_labels = wc_get_attribute_taxonomy_labels();
        // $attr_label = isset($all_labels[$slug]) ? $all_labels[$slug] : $slug;
        $attr_label = $slug;
      }

      $attribute = " attribute='" . $attr_label . ":" . get_query_var('term', '') . "' ";

      // attribute archive override table
      extract(wcpt_archive_override__get_table_vars('attribute', null, $_taxonomy));

      $category = '';
      $tag = '';

      // other taxonomy
    } else if (
      is_product_taxonomy() &&
      !is_product_category()
    ) {
      $vars = array(
        'wcpt_table_id' => false,
        'wcpt_custom_table' => false
      );

      // // wcpt archive override for custom taxonomy
      // add_filter('wcpt_archive_override_taxonomy_table_vars', 'wcpt_archive_override_taxonomy_table_vars__location', 3, 100);
      // function wcpt_archive_override_taxonomy_table_vars__location( $vars, $taxonomy, $term ){
      //   if( in_array( $taxonomy, array( 'location' ) ) ){ // replace location with your custom taxonomy slug
      //     $vars['wcpt_table_id'] = 62; // replace 62 with your table ID
      //   }
      //   return $vars;
      // }

      extract(apply_filters('wcpt_archive_override_taxonomy_table_vars', $vars, get_query_var('taxonomy'), get_query_var('term')));

      $taxonomy = ' taxonomy="' . esc_attr(get_query_var('taxonomy')) . ':' . esc_attr(get_query_var('term')) . '" ';
    }

  }

  if ($wcpt_table_id) {

    // handle subcategories grid on shop and category archive pages
    if (
      is_shop() ||
      is_product_category() &&
      !is_search()
    ) {
      if (!defined('WCPT_FLAG_CAT_ARCHIVE')) {
        $display_mode = woocommerce_get_loop_display_mode();

        // form mode should force products
        $table_id = $wcpt_table_id === 'custom' ? wcpt_extract_id_from_shortcode($wcpt_custom_table) : $wcpt_table_id;
        if (!empty($_GET[$table_id . '_filtered'])) {
          if ($display_mode == 'subcategories') {
            $display_mode = 'products';
          }
        }

        switch ($display_mode) {
          case 'subcategories':
            return false;

          case 'both':
            add_action('woocommerce_after_shop_loop', 'wcpt_archive_override', 9); // just before woocommerce_pagination()
            define('WCPT_FLAG_CAT_ARCHIVE', TRUE);
            return false;
        }
      } else {
        wp_reset_query();
        $theme = wp_get_theme();
        if (in_array('Salient', array($theme->name, $theme->parent_theme))) {
          echo '<style> .products .product:not(.product-category) { display: none !important; } </style>';
        } else if (in_array('Unicon', array($theme->name, $theme->parent_theme))) {
          echo '<style> #content .products .product:not(.product-category) { display: none !important; } </style>';
        } else {
          echo '<style> #main .products .product:not(.product-category) { display: none !important; } </style>';
        }
      }

    }

    // hide the table navigation and depend
    // upon external filter to direct query
    // in these cases:
    $only_loop = '';
    if (!function_exists('is_plugin_active')) {
      include_once(ABSPATH . 'wp-admin/includes/plugin.php');
    }
    $theme = wp_get_theme();
    if (wcpt_compatible_filter_plugin_active()) {

      if (false === strpos($wcpt_custom_table, ' _only_loop')) { // respect user entered _only_loop='false'
        $only_loop = " _only_loop='true'  ";
      }

    } else if (false === strpos($wcpt_custom_table, ' _only_loop')) {
      // hide result count, orderby and pagination
      ?>
        <style>
          /* general */
          .woocommerce-result-count,
          .woocommerce-ordering,
          .woocommerce-pagination,
          .woocommerce-select-count,

          /* avada */
          .catalog-ordering,

          /* avada */
          .box-sort-filter,

          /* woodmart */
          .woodmart-shop-tools,
          .wd-products-per-page,
          .wd-products-shop-view,

          /* martfury */
          #mf-catalog-toolbar,
          #mf-catalog-toolbar+.mf-toolbar-empty-space
          /* uncode */
          .post-body+.row-navigation,

          /* oceanwp */
          .oceanwp-toolbar.clr,
          /* unicon */
          #content .wcpt+#pagination
          /* samatext */
          .enovathemes-navigation,

          /* xstore */
          .products-per-page,
          .view-switcher,

          /* riode */
          .toolbox-pagination,

          /* betheme */
          .pager_wrapper,

          /* kadence */
          .kadence-shop-top-row,

          /* dokan */
          .gridlist-toggle {
            display: none !important;
          }

          /* uncode */
          .post-body .isotope-container {
            height: auto !important;
          }
        </style>
      <?php
    }

    if (empty($archive)) {
      $archive = " _archive='true' ";
    }

    $_taxonomy = get_query_var('taxonomy') ? " _taxonomy='" . get_query_var('taxonomy') . "' " : "";
    $_term = get_query_var('term') ? " _term='" . get_query_var('term') . "' " : "";

    if (
      get_query_var('taxonomy') == 'product_cat' &&
      !get_query_var('term') &&
      get_query_var('product_cat')
    ) {
      $_term = " _term='" . esc_attr(get_query_var('product_cat')) . "' ";
    }

    $common = " {$archive} {$category} {$attribute} {$taxonomy} {$tag} {$page} {$search} {$only_loop} {$_taxonomy} {$_term} ";

    if (!empty($sc_args)) {
      foreach ($sc_args as $key => $val) {
        $common .= " " . esc_attr($key) . "='" . esc_attr($val) . "' ";
      }
    }

    if ($wcpt_custom_table) {
      $shortcode = str_replace("]", " {$common} ]", $wcpt_custom_table);
    } else {
      $shortcode = "[product_table id='" . $wcpt_table_id . "' {$common} ]";
    }

    echo do_shortcode(apply_filters('wcpt_archive_override', $shortcode));

    return true;

  }

  return false;
}

function wcpt_archive_override__get_table_vars($target = '', $term = '', $taxonomy = '')
{
  $wcpt_table_id = false;
  $wcpt_custom_table = false;

  $wcpt_settings = wcpt_get_settings_data();

  if (empty($wcpt_settings['archive_override']['default_custom'])) {
    $wcpt_settings['archive_override']['default_custom'] = '';
  }

  $default_table_id = $wcpt_settings['archive_override']['default'];
  $default_custom_table = $wcpt_settings['archive_override']['default_custom'];

  switch ($target) {

    case 'shop':
      //-- none
      if (empty($wcpt_settings['archive_override']['shop'])) {
        $wcpt_table_id = '';

        //-- default
      } else if ($wcpt_settings['archive_override']['shop'] == 'default') {
        $wcpt_table_id = $wcpt_settings['archive_override']['default'];
        $wcpt_custom_table = $wcpt_settings['archive_override']['default_custom'];

        //-- custom
      } else if ($wcpt_settings['archive_override']['shop'] == 'custom') {
        $wcpt_table_id = 'custom';
        $wcpt_custom_table = $wcpt_settings['archive_override']['shop_custom'];

        //-- a table is assigned
      } else {
        $wcpt_table_id = $wcpt_settings['archive_override']['shop'];

      }

      break;

    case 'search':
      //-- none
      if (empty($wcpt_settings['archive_override']['search'])) {
        $wcpt_table_id = '';

        //-- default
      } else if ($wcpt_settings['archive_override']['search'] == 'default') {
        $wcpt_table_id = $wcpt_settings['archive_override']['default'];
        $wcpt_custom_table = $wcpt_settings['archive_override']['default_custom'];

        //-- custom
      } else if ($wcpt_settings['archive_override']['search'] == 'custom') {
        $wcpt_table_id = 'custom';
        $wcpt_custom_table = $wcpt_settings['archive_override']['search_custom'];

        //-- a table is assigned
      } else {
        $wcpt_table_id = $wcpt_settings['archive_override']['search'];

      }

      break;

    case 'category':

      switch ($wcpt_settings['archive_override']['category']['default']) {
        case '':
          $wcpt_table_id = '';
          $wcpt_custom_table = '';
          break;

        case 'default':
          $wcpt_table_id = $default_table_id;
          $wcpt_custom_table = $default_custom_table;
          break;

        case 'custom':
          $wcpt_table_id = 'custom';
          $wcpt_custom_table = $wcpt_settings['archive_override']['category']['custom'];
          break;

        default:
          $wcpt_table_id = $wcpt_settings['archive_override']['category']['default'];
          $wcpt_custom_table = '';
          break;
      }

      // look through other category rules
      if (!empty($wcpt_settings['archive_override']['category']['other_rules'])) {
        foreach ($wcpt_settings['archive_override']['category']['other_rules'] as $rule) {

          // maybe apply rule
          if (!empty($rule['category']) && in_array($term, $rule['category'])) {
            if (!isset($rule['table_id']))
              $rule['table_id'] = '';

            switch ($rule['table_id']) {
              case '':
                $wcpt_table_id = '';
                $wcpt_custom_table = '';
                break;
              case 'custom':
                $wcpt_table_id = 'custom';
                $wcpt_custom_table = $rule['custom'];
                break;
              case 'default':
                break;
              default:
                $wcpt_table_id = $rule['table_id'];
                break;
            }
          }

        }
      }

      break;

    case 'tag':
      switch ($wcpt_settings['archive_override']['tag']['default']) {
        case '':
          $wcpt_table_id = '';
          $wcpt_custom_table = '';
          break;

        case 'default':
          $wcpt_table_id = $default_table_id;
          $wcpt_custom_table = $default_custom_table;
          break;

        case 'custom':
          $wcpt_table_id = 'custom';
          $wcpt_custom_table = $wcpt_settings['archive_override']['tag']['custom'];
          break;

        default:
          $wcpt_table_id = $wcpt_settings['archive_override']['tag']['default'];
          $wcpt_custom_table = '';
          break;
      }

      // look through other tag rules
      if (!empty($wcpt_settings['archive_override']['tag']['other_rules'])) {
        foreach ($wcpt_settings['archive_override']['tag']['other_rules'] as $rule) {

          // maybe apply rule
          if (!empty($rule['tag']) && in_array($term, $rule['tag'])) {
            if (!isset($rule['table_id']))
              $rule['table_id'] = '';

            switch ($rule['table_id']) {
              case '':
                $wcpt_table_id = '';
                $wcpt_custom_table = '';
                break;
              case 'custom':
                $wcpt_table_id = 'custom';
                $wcpt_custom_table = $rule['custom'];
                break;
              case 'default':
                break;
              default:
                $wcpt_table_id = $rule['table_id'];
                break;
            }
          }

        }
      }

      break;

    case 'brand':
      switch ($wcpt_settings['archive_override']['brand']['default']) {
        case '':
          $wcpt_table_id = '';
          $wcpt_custom_table = '';
          break;

        case 'default':
          $wcpt_table_id = $default_table_id;
          $wcpt_custom_table = $default_custom_table;
          break;

        case 'custom':
          $wcpt_table_id = 'custom';
          $wcpt_custom_table = $wcpt_settings['archive_override']['brand']['custom'];
          break;

        default:
          $wcpt_table_id = $wcpt_settings['archive_override']['brand']['default'];
          $wcpt_custom_table = '';
          break;
      }

      // look through other brand rules
      if (!empty($wcpt_settings['archive_override']['brand']['other_rules'])) {
        foreach ($wcpt_settings['archive_override']['brand']['other_rules'] as $rule) {

          // maybe apply rule
          if (!empty($rule['brand']) && in_array($term, $rule['brand'])) {
            if (!isset($rule['table_id']))
              $rule['table_id'] = '';

            switch ($rule['table_id']) {
              case '':
                $wcpt_table_id = '';
                $wcpt_custom_table = '';
                break;
              case 'custom':
                $wcpt_table_id = 'custom';
                $wcpt_custom_table = $rule['custom'];
                break;
              case 'default':
                break;
              default:
                $wcpt_table_id = $rule['table_id'];
                break;
            }
          }

        }
      }

      break;

    case 'attribute':

      switch ($wcpt_settings['archive_override']['attribute']['default']) {
        case '':
          $wcpt_table_id = '';
          $wcpt_custom_table = '';
          break;

        case 'default':
          $wcpt_table_id = $default_table_id;
          $wcpt_custom_table = $default_custom_table;
          break;

        case 'custom':
          $wcpt_table_id = 'custom';
          $wcpt_custom_table = $wcpt_settings['archive_override']['attribute']['custom'];
          break;

        default:
          $wcpt_table_id = $wcpt_settings['archive_override']['attribute']['default'];
          $wcpt_custom_table = '';
          break;
      }

      // look through other attribute rules
      if (!empty($wcpt_settings['archive_override']['attribute']['other_rules'])) {
        foreach ($wcpt_settings['archive_override']['attribute']['other_rules'] as $rule) {
          // maybe apply rule
          $found = false;
          if (!empty($rule['attribute']) && in_array(str_replace('pa_', '', $taxonomy), $rule['attribute'])) {
            $found = true;
            if (!isset($rule['table_id']))
              $rule['table_id'] = '';

            switch ($rule['table_id']) {
              case '':
                $wcpt_table_id = '';
                $wcpt_custom_table = '';
                break;
              case 'custom':
                $wcpt_table_id = 'custom';
                $wcpt_custom_table = $rule['custom'];
                break;
              case 'default':
                break;
              default:
                $wcpt_table_id = $rule['table_id'];
                break;
            }
          }
        }
      }

      break;
  }

  if (
    !empty($wcpt_table_id) &&
    $wcpt_table_id !== 'custom'
  ) {
    $wcpt_custom_table = '';
  }

  return array(
    'wcpt_table_id' => $wcpt_table_id,
    'wcpt_custom_table' => $wcpt_custom_table
  );
}

// check if we are on archive and wcpt override is enabled for the archive
function wcpt_archive__get_table_shortcode($q)
{
  // elementor settings conflict fix
  if (
    !empty($_GET['action']) &&
    $_GET['action'] == 'elementor'
  ) {
    die();
  }

  if (!get_queried_object()) {
    return false;
  }

  // Get taxonomy from queried object if available
  if (
    property_exists($q, 'queried_object') &&
    !empty($q->queried_object) &&
    property_exists($q->queried_object, 'taxonomy')
  ) {
    $taxonomy = $q->queried_object->taxonomy;
  } else {
    $taxonomy = false;
  }

  // Get term from queried object if available 
  if (
    property_exists($q, 'queried_object') &&
    !empty($q->queried_object) &&
    property_exists($q->queried_object, 'slug')
  ) {
    $term = $q->queried_object->slug;
  } else {
    $term = false;
  }

  if (
    defined('SHOP_IS_ON_FRONT') ||
    function_exists('is_shop') &&
    is_shop()
  ) {
    extract(wcpt_archive_override__get_table_vars('shop'));
  }

  if (
    is_search() &&
    get_query_var('post_type') == 'product'
  ) {
    extract(wcpt_archive_override__get_table_vars('search'));
  }

  if (
    function_exists('is_product_category') &&
    is_product_category()
  ) {
    extract(wcpt_archive_override__get_table_vars('category', $term));
  }

  if (
    function_exists('is_product_tag') &&
    is_product_tag()
  ) {
    extract(wcpt_archive_override__get_table_vars('tag', $term));
  }

  if (is_tax('product_brand')) {
    extract(wcpt_archive_override__get_table_vars('brand', $term));
  }

  if (
    function_exists('is_product_taxonomy') &&
    is_product_taxonomy() &&
    !is_product_category() &&
    taxonomy_is_product_attribute($taxonomy)
  ) {
    extract(wcpt_archive_override__get_table_vars('attribute', $term, $taxonomy));
  }

  $wcpt_table_id = empty($wcpt_table_id) ? '' : $wcpt_table_id;
  $wcpt_custom_table = empty($wcpt_custom_table) ? '' : $wcpt_custom_table;

  $wcpt_shortcode = false;

  if (
    $wcpt_table_id == 'custom' &&
    $wcpt_custom_table
  ) {
    $wcpt_shortcode = $wcpt_custom_table;

  } else if (
    $wcpt_table_id !== 'custom' &&
    $wcpt_table_id
  ) {
    $wcpt_shortcode = "[product_table id='" . $wcpt_table_id . "' ]";

  } else {
    return false;

  }

  return $wcpt_shortcode;
}

// modify search archive's main query results

// init if conditions are right
add_filter('pre_get_posts', 'wcpt_search_archive_init');
function wcpt_search_archive_init($query)
{
  if (
    // no compatible search plugin active
    empty($_GET['dgwt_wcas']) && // plugin: AJAX search for woocommerce
    empty($_GET['type_aws']) && // plugin: Advanced Woo Search
    // is archive search query
    $query->is_search() &&
    $query->is_main_query() &&
    !empty($query->query_vars['s']) &&
    // product table archive override applied
    wcpt_archive__get_table_shortcode($query)
  ) {
    // -- prevent redirect to single product
    add_filter('woocommerce_redirect_single_search_result', '__return_false');

    // after main qurery is run, we'll collect the entire set of search ids, not just one page
    add_action('wp', 'wcpt_search_archive_modify_product_search_results');
  }
}

// -- store for search ids
$wcpt_archive_product_search_ids_store = false;

// -- modify main query results
function wcpt_search_archive_modify_product_search_results()
{
  global $wp_query, $wcpt_archive_product_search_ids_store;
  if ($wp_query->get('wc_query') === "product_query") {
    $wcpt_archive_product_search_ids_store = wcpt_archive_product_search_ids($wp_query->get('s'));
    if (!empty($wcpt_archive_product_search_ids_store)) {
      $wp_query->found_posts = $wp_query->post_count = count($wcpt_archive_product_search_ids_store);
      $wp_query->no_found_rows = true;
      $wp_query->max_num_pages = 1;
    }
  }
}

// -- get the search ids from wcpt archive search
function wcpt_archive_product_search_ids($keyphrase, $archive_shortcode = "")
{
  if (
    !$settings = wcpt_get_settings_data() ||
    empty($settings['search']) ||
    empty($settings['search']['override_settings'])
  ) {
    return false;
  }

  $global_settings = wcpt_get_settings_data()['search']['override_settings'];
  $target = empty($global_settings['target']) ? array() : $global_settings['target'];
  $custom_fields = empty($global_settings['custom_fields']) ? array() : $global_settings['custom_fields'];
  if (!empty($global_settings['custom_fields_textarea'])) {
    $custom_fields = array_merge($custom_fields, preg_split("/\r\n|\n|\r/", $global_settings['custom_fields_textarea']));
  }
  $attributes = empty($global_settings['attributes']) ? array() : $global_settings['attributes'];
  $keyword_separator = ' ';
  $include_variation_skus = !empty($global_settings['include_variation_skus']);
  $include_variation_gtins = !empty($global_settings['include_variation_gtins']);
  $keyword_match_type = !empty($global_settings['keyword_match_type']) ? $global_settings['keyword_match_type'] : 'any';
  $use_default_search = !empty($global_settings['use_default_search']) ? 'yes' : false;

  $filter_info = array(
    'keyword' => $keyphrase,
    'target' => $target,
    'custom_fields' => $custom_fields,
    'attributes' => $attributes,
    'keyword_separator' => $keyword_separator,
    'include_variation_skus' => $include_variation_skus,
    'include_variation_gtins' => $include_variation_gtins,
    'keyword_match_type' => $keyword_match_type,
    'use_default_search' => $use_default_search,
  );

  if (FALSE !== strpos($archive_shortcode, 'use_default_search')) {
    add_filter('wcpt_search_args', 'wcpt_search_args__use_default_search');
  } else {
    remove_filter('wcpt_search_args', 'wcpt_search_args__use_default_search');
  }

  return wcpt_search($filter_info);
}

// -- add the search ids to the container as html attribute
add_filter('wcpt_container_html_attributes', 'wcpt_archive_product_search_encrypted_attrs');
function wcpt_archive_product_search_encrypted_attrs($attrs)
{
  $search_ids = wcpt_archive_product_search_results_provider();
  if (!empty($search_ids)) {
    $attrs .= ' data-wcpt-encrypted-archive-search-ids="' . wcpt_encrypt(json_encode(wcpt_archive_product_search_results_provider())) . '" ';
  }
  return $attrs;
}

// -- search results provider (over regular page load or ajax)
function wcpt_archive_product_search_results_provider()
{
  if (wp_doing_ajax()) {
    if (
      empty($_REQUEST['wcpt_encrypted_attrs']) ||
      empty($_REQUEST['wcpt_encrypted_attrs']['data-wcpt-encrypted-archive-search-ids'])
    ) {
      return false;
    }

    return json_decode(wcpt_decrypt($_REQUEST['wcpt_encrypted_attrs']['data-wcpt-encrypted-archive-search-ids']), true);

  } else {
    global $wcpt_archive_product_search_ids_store;
    if (empty($wcpt_archive_product_search_ids_store)) {
      return false;
    }

    return $wcpt_archive_product_search_ids_store;

  }
}

// -- modify table query
add_filter('wcpt_query_args', 'wcpt_archive_product_search_table_query_args');
function wcpt_archive_product_search_table_query_args($query_args)
{
  $search_ids = wcpt_archive_product_search_results_provider();
  if (!empty($search_ids)) {
    $query_args['post__in'] = empty($query_args['post__in']) ? wcpt_archive_product_search_results_provider() : array_intersect($query_args['post__in'], wcpt_archive_product_search_results_provider());
  }
  return $query_args;
}

// override category results

// -- ensure main category is applied when no other is applied
add_filter('wcpt_query_args', 'wcpt_category_archive__ensure_term');
function wcpt_category_archive__ensure_term($query_args)
{
  $data = wcpt_get_table_data();
  $table_id = $data['id'];
  $sc_attrs = $data['query']['sc_attrs'];

  if (
    !empty($sc_attrs['_archive']) &&
    !empty($sc_attrs['_taxonomy']) &&
    $sc_attrs['_taxonomy'] == 'product_cat' &&
    !empty($sc_attrs['_term'])
  ) {
    if (empty($_GET[$table_id . '_product_cat'])) {
      $term = get_term_by('slug', $sc_attrs['_term'], 'product_cat');

      foreach ($query_args['tax_query'] as &$tax_query) {
        if ($tax_query['taxonomy'] == 'product_cat') {
          $tax_query['terms'][] = $term->term_taxonomy_id;
        }
      }
    }

  }

  return $query_args;
}

function wcpt_archive__get_table_query_args($sc)
{
  $sc = rtrim($sc, ']') . ' _return_query_args="true"]';
  $args = json_decode(do_shortcode($sc, true), true);

  return $args;
}

add_filter('wcpt_parse_attributes', 'wcpt_archive__blank_query');
function wcpt_archive__blank_query($attrs)
{
  $data = wcpt_get_table_data();

  if (!empty($data['query']['sc_attrs']['_return_query_args'])) {
    $attrs['terms'] = $attrs['attribute'] = $attrs['nav_category'] = $attrs['nav_category_id'] = $attrs['category'] = $attrs['ids'] = $attrs['skus'] = '';
  }

  return $attrs;
}

// replace product grid with table

// -- theme template override
add_filter('template_include', 'wcpt_automatic_archive_override__template_include', 100);
function wcpt_automatic_archive_override__template_include($template)
{
  $override_settings = wcpt_get_settings_data()['archive_override'];

  if (
      // fse
    (function_exists('wp_is_block_theme') && wp_is_block_theme()) ||
    // manual override
    empty($override_settings['override_method']) ||
    $override_settings['override_method'] === "manual" ||
    // archive override not enabled here
    !wcpt_archive_override_required_here()
  ) {
    return $template;
  }

  // if custom template override is available for theme then apply it
  if ($override_template = wcpt_get_theme_template_override($template)) {
    return $override_template;
  }

  // theme might override template later at 'wc_get_template'
  if (
    wcpt_custom_theme_override_available() &&
    in_array($template, [
      WC()->plugin_path() . '/templates/taxonomy-product-attribute.php',
      WC()->plugin_path() . '/templates/taxonomy-product-cat.php',
      WC()->plugin_path() . '/templates/taxonomy-product-tag.php',
    ])
  ) {
    add_filter('wc_get_template', 'wcpt_automatic_archive_override__wc_get_template', 1000);
    return $template;
  }

  // otherwise return default override template
  return WCPT_PLUGIN_PATH . 'pro/templates/archive_override/archive-product.php';
}

// -- catch theme override done via wc_get_template
function wcpt_automatic_archive_override__wc_get_template($template)
{
  remove_filter('wc_get_template', 'wcpt_automatic_archive_override__wc_get_template', 1000);

  // if custom template override is available for theme then apply it  
  if ($override_template = wcpt_get_theme_template_override($template)) {
    return $override_template;
  }

  // otherwise return default override template
  return WCPT_PLUGIN_PATH . '/pro/templates/archive_override/archive-product.php';
}

// -- full site editor (FSE) - switch product block with product table
add_filter('render_block_woocommerce/product-collection', 'wcpt_fse_override_new_block', 200, 2);
function wcpt_fse_override_new_block($block_content, $block)
{
  if (
    $block['blockName'] === 'woocommerce/product-collection' &&
    !empty($block['attrs']) &&
    !empty($block['attrs']['query']) &&
    !empty($block['attrs']['query']['inherit']) &&
    !empty($block['innerBlocks']) &&
    array_filter($block['innerBlocks'], function ($inner_block) {
      return $inner_block['blockName'] === 'woocommerce/product-template';
    })
  ) {
    if (wcpt_archive_override_required_here()) {
      return wcpt_fse_product_collection_get_override_markup($block_content);
    }
  }

  return $block_content;
}

add_filter('render_block', 'wcpt_fse_override_legacy_block', 200, 2);
function wcpt_fse_override_legacy_block($block_content, $block)
{
  if (
    $block['blockName'] === 'woocommerce/legacy-template' &&
    !empty($block['attrs']['template']) &&
    (
      $block['attrs']['template'] === 'archive-product' ||
      strpos($block['attrs']['template'], 'taxonomy-') === 0
    )

  ) {
    if (wcpt_archive_override_required_here()) {
      return wcpt_fse_product_collection_get_override_markup($block_content);
    }
  }

  return $block_content;
}

function wcpt_fse_product_collection_get_override_markup($block)
{
  ob_start();
  do_action('woocommerce_before_shop_loop');
  ?>
  <div class="wcpt-fse-wrapper alignwide">
    <?php wcpt_archive_override(); ?>
  </div>
  <?php
  do_action('woocommerce_after_shop_loop');
  return ob_get_clean();
}

// -- helpers
// -- -- check if archive override is required where function is called
function wcpt_archive_override_required_here()
{
  global $wp_query;
  // skip if we are past the main query or archive hasn't been assigned an override
  if (!is_main_query() || !wcpt_archive__get_table_shortcode($wp_query)) {
    return false;
  }

  return true;
}

// -- -- replace theme template path with plugin override path
function wcpt_get_theme_template_override($template)
{
  if (!wcpt_custom_theme_override_available()) {
    return false;
  }

  if (strpos($template, get_template_directory()) === false) {
    return false;
  }

  $theme_override_dir = WCPT_PLUGIN_PATH . 'pro/templates/archive_override/' . get_template();
  $relative_template_path = str_replace(get_template_directory(), '', $template);

  return $theme_override_dir . $relative_template_path;
}
// -- -- get theme slug
function wcpt_archive_override_get_theme_slug()
{
  $parent_theme = wp_get_theme()->parent();
  if ($parent_theme) {
    $parent_theme_slug = $parent_theme->get_stylesheet();
    return $parent_theme_slug;
  } else {
    return wp_get_theme()->get_stylesheet();
  }
}
// -- -- check if custom theme override is available
function wcpt_custom_theme_override_available()
{
  $theme_slug = wcpt_archive_override_get_theme_slug();
  if (is_dir(plugin_dir_path(__FILE__) . 'templates/archive_override/' . $theme_slug)) {
    return true;
  }
  return false;
}

// archive tables need to follow pagination permalink format
add_action('woocommerce_product_query', 'wcpt_parse_url_parameters');
function wcpt_parse_url_parameters($q)
{
  if (
    !is_object($q) ||
    !method_exists($q, 'is_main_query') ||
    !$q->is_main_query()
  ) {
    return;
  }

  // Check if URL contains /page/N pattern
  $shortcode = wcpt_archive__get_table_shortcode($q);

  if ($shortcode) {
    $table_id = null;
    // Extract table ID or name from shortcode
    if (preg_match('/\[product_table\s+id=[\'"](\d+)[\'"]\s*\]/', $shortcode, $matches)) {
      $table_id = $matches[1];

    } else if (preg_match('/\[product_table.*?name=[\'"]([^\'"]+)[\'"].*?\]/', $shortcode, $matches)) {
      $table_name = $matches[1];
      if ($table_name) {
        $table_id = wcpt_get_table_id_from_name($table_name);
      }
    }

    // Check if shortcode has _only_loop="true" or _only_loop='true'
    $has_only_loop = preg_match('/_only_loop=[\'"]true[\'"]/', $shortcode);

    if (
      $table_id &&
      !wp_doing_ajax() &&
      !$has_only_loop &&
      !wcpt_compatible_filter_plugin_active()
    ) {
      $page = isset($q->query_vars['paged']) ? $q->query_vars['paged'] : 1;
      $_REQUEST[$table_id . '_paged'] = $_GET[$table_id . '_paged'] = $page;

      // prevent woocommerce from thinking we have no results for current page 
      $q->set('paged', 0);

      // lazy load
      add_filter('wcpt_lazy_load_query_attr', function ($query) use ($page) {
        $table_data = wcpt_get_table_data();
        $table_id = $table_data['id'];
        $sc_attrs = $table_data['query']['sc_attrs'];
        if (!empty($sc_attrs['_archive'])) {
          $query .= '&' . $table_id . '_paged=' . $page;
        }

        return $query;
      });
    }
  }
}

// check if compatible filter plugin is active
function wcpt_compatible_filter_plugin_active()
{
  if (
    is_plugin_active('prdctfltr/prdctfltr.php') ||
    is_plugin_active('filter-everything/filter-everything.php') ||
    is_plugin_active('xforwoocommerce/xforwoocommerce.php') ||
    is_plugin_active('woocommerce-products-filter/index.php') ||
    is_plugin_active('woo-product-filter/woo-product-filter.php') ||
    is_plugin_active('woocommerce-ajax-layered-nav/ajax_layered_nav-widget.php') ||
    is_plugin_active('woocommerce-ajax-filters/woocommerce-filters.php')
  ) {
    return true;
  }
  return false;
}