<?php

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

/**
 * Layered Navigation Widget
 *
 * Filter products by attributes
 */
// Ensure woocommerce is active
if (class_exists("woocommerce")) {
    class Rad_Advanced_WC_Widget_Layered_Nav extends WC_Widget
    {

        /**
         * Constructor
         */
        public function __construct()
        {
            $this->widget_cssclass    = "aventa woocommerce widget_layered_nav";
            $this->widget_description = esc_html__("Shows a custom attribute in a widget which lets you narrow down the list of products when viewing product categories.", "aventa");
            $this->widget_id          = "woocommerce_layered_nav";
            $this->widget_name        = esc_html__("Aventa WC Layered Nav", "aventa");

            // This is where we add the style and script
            add_action("load-widgets.php", array(&$this, "rad_Admin_Scripts"));

            // Change list of attributes by ajax for image & color
            add_action("wp_ajax_change_attribute_display_type", array(&$this, "change_attribute_display_type"));
            add_action("wp_ajax_nopriv_change_attribute_display_type", array(&$this, "change_attribute_display_type"));

            $attribute_array      = array();
            $std_attribute        = "";
            $attribute_taxonomies = wc_get_attribute_taxonomies();

            if (!empty($attribute_taxonomies)) {
                foreach ($attribute_taxonomies as $tax) {
                    if (taxonomy_exists(wc_attribute_taxonomy_name($tax->attribute_name))) {
                        $attribute_array[$tax->attribute_name] = $tax->attribute_name;
                    }
                }
                $std_attribute = current($attribute_array);
            }

            $this->settings = array(
                "title"        => array(
                    "std" => __("Filter by", "aventa"),
                ),
                "attribute"    => array(
                    "std" => $std_attribute,
                ),
                "display_type" => array(
                    "std" => "list",
                ),
                "query_type"   => array(
                    "std" => "and",
                ),
                "hide_text"    => array(
                    "std" => false,
                ),
            );
            parent::__construct();
        }

        public function rad_Admin_Scripts()
        {

            //Include wpcolorpicker + its patch to support alpha chanel
            wp_enqueue_style("wp-color-picker");
            wp_enqueue_script("wp-color-picker");
            wp_register_script("colorpickerAlpha", RAD_THEME_INC_URI . "/admin/assets/js/wp-color-picker-alpha.js", array("wp-color-picker"), "1.2.2");
            $color_picker_strings = array(
                "clear"            => __("Clear", "aventa"),
                "clearAriaLabel"   => __("Clear color", "aventa"),
                "defaultString"    => __("Default", "aventa"),
                "defaultAriaLabel" => __("Select default color", "aventa"),
                "pick"             => __("Select Color", "aventa"),
                "defaultLabel"     => __("Color value", "aventa"),
            );
            wp_localize_script("colorpickerAlpha", "wpColorPickerL10n", $color_picker_strings);
            wp_enqueue_script("colorpickerAlpha");

            wp_enqueue_script("media-upload");
            wp_enqueue_script("thickbox");
            wp_enqueue_style("thickbox");
        }

        /**
         * update function.
         *
         * @see WP_Widget->update
         * @access public
         * @param array $new_instance
         * @param array $old_instance
         * @return array
         */
        public function update($new_instance, $old_instance)
        {

            $instance = $old_instance;

            if (empty($new_instance["title"])) {
                $new_instance["title"] = esc_html__("Filter by", "aventa");
            }

            $instance["title"]        = strip_tags($new_instance["title"]);
            $instance["attribute"]    = strip_tags($new_instance["attribute"]);
            $instance["query_type"]   = stripslashes($new_instance["query_type"]);
            $instance["display_type"] = stripslashes($new_instance["display_type"]);
            $instance["values"]       = $new_instance["values"]; //holds extra data (color/image)
            $instance["hide_text"]    = $new_instance["hide_text"];

            return $instance;
        }

        /**
         * form function.
         *
         * @see WP_Widget->form
         * @access public
         * @param array $instance
         */
        public function form($instance)
        {
            $defaults = array(
                "title"        => "",
                "attribute"    => "",
                "display_type" => "list",
                "query_type"   => "and",
                "values"       => "", // hold values of images/colors
                "hide_text"    => false,
            );

            $instance = wp_parse_args((array) $instance, $defaults);

            ?>
            <p>
                <label>
                    <?php esc_html_e("Title", "aventa");?><br />
                    <input class="widefat" type="text" id="<?php echo esc_attr($this->get_field_id("title")); ?>" name="<?php echo esc_attr($this->get_field_name("title")); ?>" value="<?php echo esc_attr($instance["title"]); ?>" />
                </label>
            </p>
            <p class="attribute_container">
                <label for="<?php echo esc_attr($this->get_field_id("attribute")); ?>"><?php esc_html_e("Attribute", "aventa");?></label>
                <select class="widefat" id="<?php echo esc_attr($this->get_field_id("attribute")); ?>" name="<?php echo esc_attr($this->get_field_name("attribute")); ?>">
                    <?php
$attribute_taxonomies = wc_get_attribute_taxonomies();

            if ($attribute_taxonomies) {
                foreach ($attribute_taxonomies as $tax) {
                    if (taxonomy_exists(wc_attribute_taxonomy_name($tax->attribute_name))) {
                        echo "<option name=\"" . esc_attr($tax->attribute_name) . "\"" . selected($tax->attribute_name, $instance["attribute"], false) . "\>" . esc_html($tax->attribute_name) . "</option>";
                    }
                }
            }
            ?>
                </select>
            </p>
            <p>
                <label for="<?php echo esc_attr($this->get_field_id("query_type")); ?>"><?php esc_html_e("Query Type", "aventa");?></label>
                <select class="widefat" id="<?php echo esc_attr($this->get_field_id("query_type")); ?>" name="<?php echo esc_attr($this->get_field_name("query_type")); ?>">
                    <option value="and" <?php selected($instance["query_type"], "and");?>><?php esc_html_e("AND", "aventa");?></option>
                    <option value="or" <?php selected($instance["query_type"], "or");?>><?php esc_html_e("OR", "aventa");?></option>
                </select>
            </p>
            <p class="display_type_container">
                <label for="<?php echo esc_attr($this->get_field_id("display_type")); ?>"><?php esc_html_e("Display Type", "aventa");?></label>
                <select class="widefat" id="<?php echo esc_attr($this->get_field_id("display_type")); ?>" name="<?php echo esc_attr($this->get_field_name("display_type")); ?>" data-id="<?php echo esc_attr($this->id); ?>">
                    <option value="list" <?php selected($instance["display_type"], "list");?>><?php esc_html_e("List", "aventa");?></option>
                    <option value="dropdown" <?php selected($instance["display_type"], "dropdown");?>><?php esc_html_e("Dropdown", "aventa");?></option>
                    <option value="color" <?php selected($instance["display_type"], "color");?>><?php esc_html_e("Color", "aventa");?></option>
                    <option value="image" <?php selected($instance["display_type"], "image");?>><?php esc_html_e("Image", "aventa");?></option>
                </select>
            </p>
            <p class="hide_text_container" style="<?php echo esc_attr($instance["display_type"] != "image" ? "display:none;" : "") ?>">
                <label for="<?php echo esc_attr($this->get_field_id("hide_text")); ?>"><?php esc_html_e("Show only images", "aventa")?></label>
                <input type="checkbox" id="<?php echo esc_attr($this->get_field_id("hide_text")); ?>" name="<?php echo esc_attr($this->get_field_name("hide_text")); ?>" <?php checked($instance["hide_text"], "on");?> />
            </p>
            <div class="rado-widget-attributes-table">
                <?php
$attribute    = $instance["attribute"];
            $display_type = $instance["display_type"];
            $values       = $instance["values"];
            echo "<span class=\"wc-loading hide\"></span>" . $this->show_terms($attribute, $display_type, $values, $this->id, $this->id_base, $this->number);
            ?>
            </div>

            <input type="hidden" name="w_id" value="<?php echo esc_attr($this->id); ?>"/>
            <input type="hidden" name="w_idbase" value="<?php echo esc_attr($this->id_base); ?>"/>
            <input type="hidden" name="w_number" value="<?php echo esc_attr($this->number); ?>"/>

            <input type="hidden" name="ajax_nonce" value="<?php echo wp_create_nonce("ajax_nonce"); ?>"/>
            <input type="hidden" name="widget_id" value="widget-<?php echo esc_attr($this->id); ?>-" />
            <input type="hidden" name="widget_name" value="widget-<?php echo esc_attr($this->id_base); ?>[<?php echo esc_attr($this->number); ?>]" />
            <?php
}

        public function show_terms($attribute, $display_type, $values, $id, $id_base, $number)
        {

            $terms  = get_terms("pa_" . $attribute, array("hide_empty" => "0"));
            $output = "";
            if (!empty($terms) && !is_wp_error($terms)) {

                if ($display_type == "color" || $display_type == "image") {

                    if (!isset($id) || !isset($id_base) || !isset($number)) {
                        return;
                    }

                    $output = sprintf("<table><tr><th>%s</th><th></th></tr>", esc_html__("Terms", "aventa"));

                    foreach ($terms as $term) {
                        $name = "widget-" . $id_base . "[" . $number . "]";
                        $id   = "widget-" . $id . "-" . $term->term_id;

                        $output .= "<tr>
                            <td><label for=\"" . esc_attr($id) . "\">" . esc_attr($term->name) . " </label></td>";

                        $output .= "<td>";

                        $value = (isset($values[$term->slug]) ? esc_attr($values[$term->slug]) : "");

                        if ($display_type == "color") {
                            //reset value if display_type is changed from image to color
                            if (substr($value, 0, 1) !== "#") {
                                $value = "";
                            }

                            $output .= "<div class=\"field color-field clear-after\">
                                            <div class=\"color-field-wrap clear-after\">
                                                <input id=\"" . esc_attr($id) . "\" name=\"" . esc_attr($name) . "[values][" . esc_attr($term->slug) . "]\" type=\"text\" value=\"" . esc_attr($value) . "\" class=\"colorinput\" />
                                                <div class=\"color-view\"></div>
                                            </div>
                                        </div>";

                        } else {
                            //reset value if display_type is changed from color to image
                            if (substr($value, 0, 1) === "#") {
                                $value = "";
                            }

                            $output .= "<div class=\"field upload-field clear-after\" data-title=\"" . esc_attr__("Upload Image", "aventa") . "\" data-referer=\"rad-attr-image\" >
                                            <input type=\"hidden\" id=\"" . esc_attr($id) . "\" name=\"" . esc_attr($name) . "[values][" . esc_attr($term->slug) . "]\" value=\"" . esc_attr($value) . "\" />
                                            <a href=\"#\" class=\"upload-button\">" . esc_html__("Browse", "aventa") . "</a>
                                            <div class=\"upload-thumb " . ($value != "" ? "show" : "") . "\">
                                                <div class=\"close\"><span class=\"close-icon\"></span></div>
                                                <img class=\"\" src=\"" . esc_url(rad_get_image_url($value, "thumbnail")) . "\" alt=\"" . esc_html__("Browse", "aventa") . "\">
                                            </div>
                                        </div>";

                        }
                        $output .= "</td></tr>";
                    }

                    $output .= "</table>";
                    $output .= "<input type=\"hidden\" name=\"" . esc_attr($name) . "[labels]\" value=\"\" />";

                }

            } else {
                if ($display_type == "color" || $display_type == "image") {
                    $output = "<span class=\"no-term\">" . esc_html__("No terms defined for this attribute", "aventa") . "</span>";
                }
            }

            return $output;
        }

        public function change_attribute_display_type()
        {

            // check to see if the submitted nonce matches with the
            // generated nonce we created earlier

            if (!isset($_POST["ajax_nonce"])) {
                die("Failed!");
            }

            $nonce = $_POST["ajax_nonce"];

            if (!wp_verify_nonce($nonce, "ajax_nonce")) {
                die("Failed!");
            }

            if (!isset($_POST["attribute"]) || !isset($_POST["display_type"]) || !isset($_POST["id"]) || !isset($_POST["id_base"]) || !isset($_POST["number"])) {
                exit;
                return;
            }

            $attribute    = $_POST["attribute"];
            $display_type = $_POST["display_type"];
            $id           = $_POST["id"];
            $id_base      = $_POST["id_base"];
            $number       = $_POST["number"];

            $output = "";

            if ($display_type == "color" || $display_type == "image") {
                $output = $this->show_terms($attribute, $display_type, "", $id, $id_base, $number);
            }

            echo "" . $output; //sanitized

            exit;

        }

        /**
         * widget function.
         *
         * @see WP_Widget
         *
         * @param array $args
         * @param array $instance
         */
        public function widget($args, $instance)
        {

            if (!is_post_type_archive("product") && !is_tax(get_object_taxonomies("product"))) {
                return;
            }

            $_chosen_attributes = WC_Query::get_layered_nav_chosen_attributes();
            $taxonomy           = isset($instance["attribute"]) ? wc_attribute_taxonomy_name($instance["attribute"]) : $this->settings["attribute"]["std"];
            $query_type         = isset($instance["query_type"]) ? $instance["query_type"] : $this->settings["query_type"]["std"];
            $display_type       = isset($instance["display_type"]) ? $instance["display_type"] : $this->settings["display_type"]["std"];

            /* Rado codes */
            $hide_text = (isset($instance["hide_text"]) ? true : $this->settings["hide_text"]["std"]);
            $values    = (isset($instance["values"]) ? $instance["values"] : array());
            /*End of Rado codes */

            if (!taxonomy_exists($taxonomy)) {
                return;
            }

            $get_terms_args = array("hide_empty" => "1");

            $orderby = wc_attribute_orderby($taxonomy);

            switch ($orderby) {
                case "name":
                    $get_terms_args["orderby"]    = "name";
                    $get_terms_args["menu_order"] = false;
                    break;
                case "id":
                    $get_terms_args["orderby"]    = "id";
                    $get_terms_args["order"]      = "ASC";
                    $get_terms_args["menu_order"] = false;
                    break;
                case "menu_order":
                    $get_terms_args["menu_order"] = "ASC";
                    break;
            }

            $terms = get_terms($taxonomy, $get_terms_args);

            if (0 === sizeof($terms)) {
                return;
            }

            switch ($orderby) {
                case "name_num":
                    usort($terms, "_wc_get_product_terms_name_num_usort_callback");
                    break;
                case "parent":
                    usort($terms, "_wc_get_product_terms_parent_usort_callback");
                    break;
            }

            ob_start();

            $this->widget_start($args, $instance);

            if ("dropdown" === $display_type) {
                $found = $this->layered_nav_dropdown($terms, $taxonomy, $query_type);
            }
            /* Rado codes*/
            elseif ("color" == $display_type) {
                $found = $this->layered_nav_color($terms, $taxonomy, $query_type, $values);
            } elseif ("image" == $display_type) {
                $found = $this->layered_nav_image($terms, $taxonomy, $query_type, $values, $hide_text);
            }
            /* End of Rado codes*/
            else {
                $found = $this->layered_nav_list($terms, $taxonomy, $query_type);
            }

            $this->widget_end($args);

            // Force found when option is selected - do not force found on taxonomy attributes
            if (!is_tax() && is_array($_chosen_attributes) && array_key_exists($taxonomy, $_chosen_attributes)) {
                $found = true;
            }

            if (!$found) {
                ob_end_clean();
            } else {
                echo ob_get_clean();
            }

        }

        /**
         * Return the currently viewed taxonomy name.
         * @return string
         */
        protected function get_current_taxonomy()
        {
            return is_tax() ? get_queried_object()->taxonomy : "";
        }

        /**
         * Return the currently viewed term ID.
         * @return int
         */
        protected function get_current_term_id()
        {
            return absint(is_tax() ? get_queried_object()->term_id : 0);
        }

        /**
         * Return the currently viewed term slug.
         * @return int
         */
        protected function get_current_term_slug()
        {
            return absint(is_tax() ? get_queried_object()->slug : 0);
        }

        /**
         * Show dropdown layered nav.
         *
         * @param  array  $terms Terms.
         * @param  string $taxonomy Taxonomy.
         * @param  string $query_type Query Type.
         * @return bool Will nav display?
         */
        protected function layered_nav_dropdown($terms, $taxonomy, $query_type)
        {
            global $wp;
            $found = false;

            if ($taxonomy !== $this->get_current_taxonomy()) {
                $term_counts          = $this->get_filtered_term_product_counts(wp_list_pluck($terms, "term_id"), $taxonomy, $query_type);
                $_chosen_attributes   = WC_Query::get_layered_nav_chosen_attributes();
                $taxonomy_filter_name = wc_attribute_taxonomy_slug($taxonomy);
                $taxonomy_label       = wc_attribute_label($taxonomy);

                /* translators: %s: taxonomy name */
                $any_label      = apply_filters("woocommerce_layered_nav_any_label", sprintf(__("Any %s", "aventa"), $taxonomy_label), $taxonomy_label, $taxonomy);
                $multiple       = "or" === $query_type;
                $current_values = isset($_chosen_attributes[$taxonomy]["terms"]) ? $_chosen_attributes[$taxonomy]["terms"] : array();

                if ("" === get_option("permalink_structure")) {
                    $form_action = remove_query_arg(array("page", "paged"), add_query_arg($wp->query_string, "", home_url($wp->request)));
                } else {
                    $form_action = preg_replace("%\/page/[0-9]+%", "", home_url(trailingslashit($wp->request)));
                }

                echo "<form method=\"get\" action=\"" . esc_url($form_action) . "\" class=\"woocommerce-widget-layered-nav-dropdown\">";
                echo "<select class=\"woocommerce-widget-layered-nav-dropdown dropdown_layered_nav_" . esc_attr($taxonomy_filter_name) . "\"" . ($multiple ? "multiple=\"multiple\"" : "") . ">";
                echo "<option value=\"\">" . esc_html($any_label) . "</option>";

                foreach ($terms as $term) {

                    // If on a term page, skip that term in widget list.
                    if ($term->term_id === $this->get_current_term_id()) {
                        continue;
                    }

                    // Get count based on current view.
                    $option_is_set = in_array($term->slug, $current_values, true);
                    $count         = isset($term_counts[$term->term_id]) ? $term_counts[$term->term_id] : 0;

                    // Only show options with count > 0.
                    if (0 < $count) {
                        $found = true;
                    } elseif (0 === $count && !$option_is_set) {
                        continue;
                    }

                    echo "<option value=\"" . esc_attr(urldecode($term->slug)) . "\" " . selected($option_is_set, true, false) . ">" . esc_html($term->name) . "</option>";
                }

                echo "</select>";

                if ($multiple) {
                    echo "<button class=\"woocommerce-widget-layered-nav-dropdown__submit\" type=\"submit\" value=\"" . esc_attr__("Apply", "aventa") . "\">" . esc_html__("Apply", "aventa") . "</button>";
                }

                if ("or" === $query_type) {
                    echo "<input type=\"hidden\" name=\"query_type_" . esc_attr($taxonomy_filter_name) . "\" value=\"or\" />";
                }

                echo "<input type=\"hidden\" name=\"filter_" . esc_attr( $taxonomy_filter_name ) . "\" value=\"" . esc_attr(implode(",", $current_values)) . "\" />";
                echo wc_query_string_form_fields(null, array("filter_" . $taxonomy_filter_name, "query_type_" . $taxonomy_filter_name), "", true); // @codingStandardsIgnoreLine
                echo "</form>";

                wc_enqueue_js(
                    "
                    // Update value on change.
                    jQuery( '.dropdown_layered_nav_" . esc_js($taxonomy_filter_name) . "' ).change( function() {
                        var slug = jQuery( this ).val();
                        jQuery( ':input[name=\"filter_" . esc_js($taxonomy_filter_name) . "\"]' ).val( slug );

                        // Submit form on change if standard dropdown.
                        if ( ! jQuery( this ).attr( 'multiple' ) ) {
                            jQuery( this ).closest( 'form' ).submit();
                        }
                    });

                    // Use Select2 enhancement if possible
                    if ( jQuery().selectWoo ) {
                        var wc_layered_nav_select = function() {
                            jQuery( '.dropdown_layered_nav_" . esc_js($taxonomy_filter_name) . "' ).selectWoo( {
                                placeholder: decodeURIComponent('" . rawurlencode((string) wp_specialchars_decode($any_label)) . "'),
                                minimumResultsForSearch: 5,
                                width: '100%',
                                allowClear: " . ($multiple ? 'false' : 'true') . ",
                                language: {
                                    noResults: function() {
                                        return '" . esc_js(_x("No matches found", "enhanced select", "aventa")) . "';
                                    }
                                }
                            } );
                        };
                        wc_layered_nav_select();
                    }
                "
                );
            }

            return $found;
        }

        /**
         * Get current page URL for layered nav items.
         * @return string
         */
        protected function get_page_base_url($taxonomy)
        {

            if (defined("SHOP_IS_ON_FRONT")) {
                $link = home_url();
            } elseif (is_post_type_archive("product") || is_page(wc_get_page_id("shop"))) {
                $link = get_post_type_archive_link("product");
            } elseif (is_product_category()) {
                $link = get_term_link(get_query_var("product_cat"), "product_cat");
            } elseif (is_product_tag()) {
                $link = get_term_link(get_query_var("product_tag"), "product_tag");
            } else {
                $queried_object = get_queried_object();
                $link           = get_term_link($queried_object->slug, $queried_object->taxonomy);
            }

            // Min/Max
            if (isset($_GET["min_price"])) {
                $link = add_query_arg("min_price", wc_clean($_GET["min_price"]), $link);
            }

            if (isset($_GET["max_price"])) {
                $link = add_query_arg("max_price", wc_clean($_GET["max_price"]), $link);
            }

            // Orderby
            if (isset($_GET["orderby"])) {
                $link = add_query_arg("orderby", wc_clean($_GET["orderby"]), $link);
            }

            /**
             * Search Arg.
             * To support quote characters, first they are decoded from &quot; entities, then URL encoded.
             */
            if (get_search_query()) {
                $link = add_query_arg("s", rawurlencode(wp_specialchars_decode(get_search_query())), $link);
            }

            // Post Type Arg
            if (isset($_GET["post_type"])) {
                $link = add_query_arg("post_type", wc_clean($_GET["post_type"]), $link);
            }

            // Min Rating Arg
            if (isset($_GET["rating_filter"])) {
                $link = add_query_arg("rating_filter", wc_clean($_GET["rating_filter"]), $link);
            }

            /***** Rado codes *****/
            // On Sale Arg
            if (isset($_GET["status"]) && $_GET["status"] == "sale") {
                $link = add_query_arg("status", wc_clean($_GET["status"]), $link);
            }
            //In stock Arg
            if (isset($_GET["availability"]) && $_GET["availability"] == "in_stock") {
                $link = add_query_arg("availability", wc_clean($_GET["availability"]), $link);
            }
            /***** End of Rado codes *****/

            // All current filters
            if ($_chosen_attributes = WC_Query::get_layered_nav_chosen_attributes()) {

                foreach ($_chosen_attributes as $name => $data) {
                    if ($name === $taxonomy) {
                        continue;
                    }
                    $filter_name = sanitize_title(str_replace("pa_", "", $name));
                    if (!empty($data["terms"])) {
                        $link = add_query_arg("filter_" . $filter_name, implode(",", $data["terms"]), $link);
                    }
                    if ("or" == $data["query_type"]) {
                        $link = add_query_arg("query_type_" . $filter_name, "or", $link);
                    }
                }
            }

            return $link;
        }

        /**
         * Count products within certain terms, taking the main WP query into consideration.
         *
         * This query allows counts to be generated based on the viewed products, not all products.
         *
         * @param  array  $term_ids Term IDs.
         * @param  string $taxonomy Taxonomy.
         * @param  string $query_type Query Type.
         * @return array
         */
        protected function get_filtered_term_product_counts($term_ids, $taxonomy, $query_type)
        {
            global $wpdb;

            $tax_query  = WC_Query::get_main_tax_query();
            $meta_query = WC_Query::get_main_meta_query();

            if ("or" === $query_type) {
                foreach ($tax_query as $key => $query) {
                    if (is_array($query) && $taxonomy === $query["taxonomy"]) {
                        unset($tax_query[$key]);
                    }
                }
            }

            $meta_query     = new WP_Meta_Query($meta_query);
            $tax_query      = new WP_Tax_Query($tax_query);
            $meta_query_sql = $meta_query->get_sql("post", $wpdb->posts, "ID");
            $tax_query_sql  = $tax_query->get_sql($wpdb->posts, "ID");

            // Generate query.
            $query           = array();
            $query["select"] = "SELECT COUNT( DISTINCT {$wpdb->posts}.ID ) as term_count, terms.term_id as term_count_id";
            $query["from"]   = "FROM {$wpdb->posts}";
            $query["join"]   = "
                INNER JOIN {$wpdb->term_relationships} AS term_relationships ON {$wpdb->posts}.ID = term_relationships.object_id
                INNER JOIN {$wpdb->term_taxonomy} AS term_taxonomy USING( term_taxonomy_id )
                INNER JOIN {$wpdb->terms} AS terms USING( term_id )
                " . $tax_query_sql["join"] . $meta_query_sql["join"];

            $query["where"] = "
                WHERE {$wpdb->posts}.post_type IN ( 'product' )
                AND {$wpdb->posts}.post_status = 'publish'"
            . $tax_query_sql["where"] . $meta_query_sql["where"] .
            "AND terms.term_id IN (" . implode(",", array_map("absint", $term_ids)) . ")";

            $search = WC_Query::get_main_search_query_sql();
            if ($search) {
                $query["where"] .= " AND " . $search;
            }

            $query["group_by"] = "GROUP BY terms.term_id";
            $query             = apply_filters("woocommerce_get_filtered_term_product_counts_query", $query);
            $query             = implode(" ", $query);

            // We have a query - let's see if cached results of this query already exist.
            $query_hash = md5($query);

            // Maybe store a transient of the count values.
            $cache = apply_filters("woocommerce_layered_nav_count_maybe_cache", true);
            if (true === $cache) {
                $cached_counts = (array) get_transient("wc_layered_nav_counts_" . sanitize_title($taxonomy));
            } else {
                $cached_counts = array();
            }

            if (!isset($cached_counts[$query_hash])) {
                $results                    = $wpdb->get_results($query, ARRAY_A); // @codingStandardsIgnoreLine
                $counts                     = array_map("absint", wp_list_pluck($results, "term_count", "term_count_id"));
                $cached_counts[$query_hash] = $counts;
                if (true === $cache) {
                    set_transient("wc_layered_nav_counts_" . sanitize_title($taxonomy), $cached_counts, DAY_IN_SECONDS);
                }
            }

            return array_map("absint", (array) $cached_counts[$query_hash]);
        }

        /**
         * Show list based layered nav.
         *
         * @param  array  $terms Terms.
         * @param  string $taxonomy Taxonomy.
         * @param  string $query_type Query Type.
         * @return bool   Will nav display?
         */
        protected function layered_nav_list($terms, $taxonomy, $query_type)
        {
            // List display.
            echo "<ul class=\"woocommerce-widget-layered-nav-list\">";

            $term_counts        = $this->get_filtered_term_product_counts(wp_list_pluck($terms, "term_id"), $taxonomy, $query_type);
            $_chosen_attributes = WC_Query::get_layered_nav_chosen_attributes();
            $found              = false;
            $base_link          = $this->get_current_page_url();

            foreach ($terms as $term) {
                $current_values = isset($_chosen_attributes[$taxonomy]["terms"]) ? $_chosen_attributes[$taxonomy]["terms"] : array();
                $option_is_set  = in_array($term->slug, $current_values, true);
                $count          = isset($term_counts[$term->term_id]) ? $term_counts[$term->term_id] : 0;

                // Skip the term for the current archive.
                if ($this->get_current_term_id() === $term->term_id) {
                    continue;
                }

                // Only show options with count > 0.
                if (0 < $count) {
                    $found = true;
                } elseif (0 === $count && !$option_is_set) {
                    continue;
                }

                $filter_name    = "filter_" . wc_attribute_taxonomy_slug($taxonomy);
                $current_filter = isset($_GET[$filter_name]) ? explode(",", wc_clean(wp_unslash($_GET[$filter_name]))) : array(); // WPCS: input var ok, CSRF ok.
                $current_filter = array_map("sanitize_title", $current_filter);

                if (!in_array($term->slug, $current_filter, true)) {
                    $current_filter[] = $term->slug;
                }

                $link = remove_query_arg($filter_name, $base_link);

                // Add current filters to URL.
                foreach ($current_filter as $key => $value) {
                    // Exclude query arg for current term archive term.
                    if ($value === $this->get_current_term_slug()) {
                        unset($current_filter[$key]);
                    }

                    // Exclude self so filter can be unset on click.
                    if ($option_is_set && $value === $term->slug) {
                        unset($current_filter[$key]);
                    }
                }

                if (!empty($current_filter)) {
                    asort($current_filter);
                    $link = add_query_arg($filter_name, implode(",", $current_filter), $link);

                    // Add Query type Arg to URL.
                    if ("or" === $query_type && !(1 === count($current_filter) && $option_is_set)) {
                        $link = add_query_arg("query_type_" . wc_attribute_taxonomy_slug($taxonomy), "or", $link);
                    }
                    $link = str_replace("%2C", ",", $link);
                }

                if ($count > 0 || $option_is_set) {
                    $link      = apply_filters("woocommerce_layered_nav_link", $link, $term, $taxonomy);
                    $term_html = "<a rel=\"nofollow\" href=\"" . esc_url($link) . "\">" . esc_html($term->name) . "</a>";
                } else {
                    $link      = false;
                    $term_html = "<span>" . esc_html($term->name) . "</span>";
                }

                $term_html .= " " . apply_filters("woocommerce_layered_nav_count", "<span class=\"count\">(" . absint($count) . ")</span>", $count, $term);

                echo "<li class=\"woocommerce-widget-layered-nav-list__item wc-layered-nav-term " . ($option_is_set ? "woocommerce-widget-layered-nav-list__item--chosen chosen" : "") . "\">";
                echo apply_filters("woocommerce_layered_nav_term_html", $term_html, $term, $link, $count); // WPCS: XSS ok.
                echo "</li>";
            }

            echo "</ul>";

            return $found;
        }

        /******* Rado codes ********/

        /**
         * Show color list layered nav.
         * @param  array $terms
         * @param  string $taxonomy
         * @param  string $query_type
         * @param  array $values
         * @return bool Will nav display?
         */
        protected function layered_nav_color($terms, $taxonomy, $query_type, $values)
        {

            $term_counts        = $this->get_filtered_term_product_counts(wp_list_pluck($terms, "term_id"), $taxonomy, $query_type);
            $_chosen_attributes = WC_Query::get_layered_nav_chosen_attributes();
            $found              = false;

            echo "<ul class=\"colorlist\">";

            foreach ($terms as $term) {

                $current_values = isset($_chosen_attributes[$taxonomy]["terms"]) ? $_chosen_attributes[$taxonomy]["terms"] : array();
                $option_is_set  = in_array($term->slug, $current_values);
                $count          = isset($term_counts[$term->term_id]) ? $term_counts[$term->term_id] : 0;

                // skip the term for the current archive
                if ($this->get_current_term_id() === $term->term_id) {
                    continue;
                }

                // Only show options with count > 0
                if (0 < $count) {
                    $found = true;
                } elseif ("and" === $query_type && 0 === $count && !$option_is_set) {
                    continue;
                }

                $filter_name    = "filter_" . sanitize_title(str_replace("pa_", "", $taxonomy));
                $current_filter = isset($_GET[$filter_name]) ? explode(",", wc_clean($_GET[$filter_name])) : array();
                $current_filter = array_map("sanitize_title", $current_filter);

                if (!in_array($term->slug, $current_filter)) {
                    $current_filter[] = $term->slug;
                }

                $link = $this->get_page_base_url($taxonomy);

                // Add current filters to URL.
                foreach ($current_filter as $key => $value) {
                    // Exclude query arg for current term archive term
                    if ($value === $this->get_current_term_slug()) {
                        unset($current_filter[$key]);
                    }

                    // Exclude self so filter can be unset on click.
                    if ($option_is_set && $value === $term->slug) {
                        unset($current_filter[$key]);
                    }
                }

                if (!empty($current_filter)) {
                    $link = add_query_arg($filter_name, implode(",", $current_filter), $link);

                    // Add Query type Arg to URL
                    if ($query_type === "or" && !(1 === sizeof($current_filter) && $option_is_set)) {
                        $link = add_query_arg("query_type_" . sanitize_title(str_replace("pa_", "", $taxonomy)), "or", $link);
                    }
                }

                $color = isset($values[$term->slug]) ? $values[$term->slug] : "";

                if ($color) {

                    if ($count > 0 || $option_is_set) {
                        $link      = esc_url(apply_filters("woocommerce_layered_nav_link", $link, $term, $taxonomy));
                        $term_html = "<a href=\"" . esc_url($link) . "\">" . "<span class=\"color\" style=\"background-color:" . esc_attr($color) . ";\" ></span></a>";
                    } else {
                        $link      = false;
                        $term_html = "<span class=\"color\" style=\"background-color:" . esc_attr($color) . ";\" ></span>";
                    }

                    //$term_html .= " " . apply_filters( "woocommerce_layered_nav_count", "<span class=\"count\">(" . absint( $count ) . ")</span>", $count, $term );

                    echo "<li class=\"" . ($option_is_set ? "chosen" : "") . "\">";
                    echo wp_kses_post(apply_filters("woocommerce_layered_nav_term_html", $term_html, $term, $link, $count));
                    echo "</li>";
                }
            }

            echo "</ul>";

            return $found;

        }

        /**
         * Show image list layered nav.
         * @param  array $terms
         * @param  string $taxonomy
         * @param  string $query_type
         * @param  array $values
         * @param  bool $hide_text
         * @return bool Will nav display?
         */
        protected function layered_nav_image($terms, $taxonomy, $query_type, $values, $hide_text)
        {

            $term_counts        = $this->get_filtered_term_product_counts(wp_list_pluck($terms, "term_id"), $taxonomy, $query_type);
            $_chosen_attributes = WC_Query::get_layered_nav_chosen_attributes();
            $found              = false;

            echo "<ul class=\"imagelist\">";

            foreach ($terms as $term) {

                $current_values = isset($_chosen_attributes[$taxonomy]["terms"]) ? $_chosen_attributes[$taxonomy]["terms"] : array();
                $option_is_set  = in_array($term->slug, $current_values);
                $count          = isset($term_counts[$term->term_id]) ? $term_counts[$term->term_id] : 0;

                // skip the term for the current archive
                if ($this->get_current_term_id() === $term->term_id) {
                    continue;
                }

                // Only show options with count > 0
                if (0 < $count) {
                    $found = true;
                } elseif ("and" === $query_type && 0 === $count && !$option_is_set) {
                    continue;
                }

                $filter_name    = "filter_" . sanitize_title(str_replace("pa_", "", $taxonomy));
                $current_filter = isset($_GET[$filter_name]) ? explode(",", wc_clean($_GET[$filter_name])) : array();
                $current_filter = array_map("sanitize_title", $current_filter);

                if (!in_array($term->slug, $current_filter)) {
                    $current_filter[] = $term->slug;
                }

                $link = $this->get_page_base_url($taxonomy);

                // Add current filters to URL.
                foreach ($current_filter as $key => $value) {
                    // Exclude query arg for current term archive term
                    if ($value === $this->get_current_term_slug()) {
                        unset($current_filter[$key]);
                    }

                    // Exclude self so filter can be unset on click.
                    if ($option_is_set && $value === $term->slug) {
                        unset($current_filter[$key]);
                    }
                }

                if (!empty($current_filter)) {
                    $link = add_query_arg($filter_name, implode(",", $current_filter), $link);

                    // Add Query type Arg to URL
                    if ($query_type === "or" && !(1 === sizeof($current_filter) && $option_is_set)) {
                        $link = add_query_arg("query_type_" . sanitize_title(str_replace("pa_", "", $taxonomy)), "or", $link);
                    }
                }

                $image = isset($values[$term->slug]) ? $values[$term->slug] : "";

                if ($image) {

                    if ($count > 0 || $option_is_set) {
                        $link      = esc_url(apply_filters("woocommerce_layered_nav_link", $link, $term, $taxonomy));
                        $term_html = "<a href=\"" . esc_url($link) . "\">" . "<img class=\"image\" title=\"" . esc_attr($term->name) . "\" alt=\"" . esc_attr($term->name) . "\" src=\"" . esc_url(rad_get_image_url($image, "full")) . "\" >" . ($hide_text == false ? esc_html($term->name) : "") . "</a>";
                    } else {
                        $link      = false;
                        $term_html = "<img class=\"image\" title=\"" . esc_attr($term->name) . "\" alt=\"" . esc_attr($term->name) . "\" src=\"" . esc_url(rad_get_image_url($image, "full")) . "\" >" . ($hide_text == false ? esc_html($term->name) : "");
                    }

                    echo "<li class=\"" . ($option_is_set ? "chosen" : "") . "\">";
                    echo wp_kses_post(apply_filters("woocommerce_layered_nav_term_html", $term_html, $term, $link,$count));
                    echo "</li>";

                }

            }

            echo "</ul>";

            return $found;

        }
    }
}
