<?php
/**
 * Helper for WooCommerce Product Slider
 *
 * @since ???
 * @since 4.8.9		moved to this file from avia_sc_productslider
 */
if( ! defined( 'ABSPATH' ) ) {  exit;  }    // Exit if accessed directly

if( ! function_exists( 'WC' ) || ! WC() instanceof WooCommerce )
{
	return;
}

if ( ! class_exists( 'avia_product_slider', false ) )
{
	class avia_product_slider extends \aviaBuilder\base\aviaSubItemQueryBase
	{
		use \aviaBuilder\traits\scSlideshowUIControls;

		/**
		 *
		 * @var int
		 */
		static protected $slide = 0;

		/**
		 *
		 * @since 4.7.6.4
		 * @var int
		 */
		protected $current_page;

		/**
		 * Number of queried entires
		 *
		 * @since 5.0
		 * @var int
		 */
		protected $items;

		/**
		 * @since ???
		 * @since 4.8.9					added $sc_context
		 * @param array $atts
		 * @param aviaShortcodeTemplate $sc_context
		 */
		public function __construct( $atts = array(), ?aviaShortcodeTemplate $sc_context = null )
		{
			parent::__construct( $atts, $sc_context, avia_product_slider::default_args() );

			$this->current_page = 1;
			$this->items = 0;

			if( $this->config['items'] < 0 )
			{
				$this->config['paginate'] = 'no';
			}

			if( $this->config['term_rel'] != 'AND' )
			{
				$this->config['term_rel'] = 'IN';
			}
		}

		/**
		 * @since 4.5.7.2
		 */
		public function __destruct()
		{
			unset( $this->config );
		}

		/**
		 * Return defaults array
		 *
		 * @since 4.8
		 * @deprecated 4.8.9
		 * @return array
		 */
		static public function get_defaults()
		{
			_deprecated_function( 'avia_product_slider::get_defaults', '4.8.9', 'Use avia_product_slider::default_args instead. Will be removed in a future version.');

			return avia_product_slider::default_args();
		}

		/**
		 * Returns the defaults array.
		 *
		 * ATTENTION: Backwards compatibilty different behaviour !!!
		 * ==========
		 *
		 * Allows shortcodes using this class to get the default values used before,
		 * merge them into shortcode generated defaults
		 *
		 * @since 4.8.9
		 * @param array $sc_defaults
		 * @return array
		 */
		static public function default_args( array $sc_defaults = array() )
		{
			$default = array(
						'type'					=> 'slider',			// 'slider' | 'grid' | 'list'
						'style'					=> '',					// no_margin
						'columns'				=> '4',
						'image_size'			=> '',
						'items'					=> '16',
						'wc_prod_visible'		=> '',
						'wc_prod_hidden'		=> '',
						'wc_prod_featured'		=> '',
						'wc_prod_sale'			=> '',
						'wc_prod_additional_filter'		=> '',
						'page_element_filter'	=> '',
						'select_type'			=> '',					//	added 5.4.1     '' | 'extended'
						'link'					=> 'product_cat',		//	added 5.4.1		taxonomy,term_id,....
						'post_type'				=> 'product',
						'taxonomy'				=> 'product_cat',
						'categories'			=> array(),
						'term_rel'				=> 'IN',
						'contents'				=> 'excerpt',
						'control_layout'		=> '',
						'slider_navigation'		=> 'av-navigate-arrows av-navigate-dots',
						'nav_visibility_desktop' => '',
						'nav_arrow_color'		=> '',
						'nav_arrow_bg_color'	=> '',
						'nav_dots_color'		=> '',
						'nav_dot_active_color'	=> '',
						'animation'				=> 'fade',
						'transition_speed'		=> '',				//	in ms - empty for default
						'autoplay'				=> 'no',
						'interval'				=> 5,
						'autoplay_stopper'		=> '',
						'manual_stopper'		=> '',
						'bg_slider'				=> 'false',
						'keep_padding'			=> false,			//	needed in js $.AviaSlider
						'hoverpause'			=> true,			//	needed in js $.AviaSlider
						'paginate'				=> 'no',
						'class'					=> '',
						'sort'					=> '',
						'prod_order'			=> '',
						'offset'				=> 0,
						'link_behavior'			=> '',
						'show_images'			=> 'yes',
						'av_display_classes'	=> '',
						'el_id'					=> '',			//	must contain id="...."
						'custom_class'			=> ''
					);

			$default = array_merge( $default, $sc_defaults );

			/**
			 * @since 4.8.9
			 * @param array $default
			 * @return array
			 */
			return apply_filters( 'avf_avia_product_slider_defaults', $default );
		}

		/**
		 * Create custom stylings
		 *
		 * Attention: Due to paging we cannot add any backgrouund images to selectors !!!!
		 * =========
		 *
		 * @since 4.8.9
		 * @param array $result
		 * @return array
		 */
		public function get_element_styles( array $result )
		{
			extract( $result );

			if( 'list' == $this->config['type'] )
			{
				switch( $this->config['columns'] )
				{
					case '1':
						$grid = 'av_fullwidth';
						break;
					case '2':
						$grid = 'av_one_half';
						break;
					case '3':
						$grid = 'av_one_third';
						break;
					case '4':
						$grid = 'av_one_fourth';
						break;
					case '5':
						$grid = 'av_one_fifth';
						break;
					default:
						$grid = 'av_fullwidth';
						break;
				}

				$classes = array(
								'avia-product-slider-container',
								$element_id,
								$grid,
								'flex_column',
								'av-catalogue-column',
								$this->config['custom_class']
							);
			}
			else
			{
				$classes = array(
								'avia-product-slider-container',
								$element_id,
								'template-shop',
								'avia-content-slider',
								"avia-content-{$this->config['type']}-active",
								"shop_columns_{$this->config['columns']}",
								$this->config['class']
							);

				$classes[] = $this->config['columns'] % 2 ? 'avia-content-slider-odd' : 'avia-content-slider-even';
			}

			$element_styling->add_classes( 'container', $classes );
			$element_styling->add_classes( 'container', $this->config['class'] );

			$element_styling->add_responsive_classes( 'container', 'hide_element', $this->config );

			$ui_args = array(
						'element_id'		=> $element_id,
						'element_styling'	=> $element_styling,
						'atts'				=> $this->config,
						'autoplay_option'	=> 'yes',
						'context'			=> __CLASS__,
					);

			$this->addSlideshowAttributes( $ui_args );

			$selectors = array(
						'container'			=> ".avia-product-slider-container.{$element_id}",
						//	override selectors - too weak
						'slide-arrows'		=> "#top .av-slideshow-ui.{$element_id} .avia-slideshow-arrows a",
						'nav-dots'			=> "#top .av-slideshow-ui.{$element_id} .avia-slideshow-dots a:not(.active)",
						'nav-dots-active'	=> "#top .av-slideshow-ui.{$element_id} .avia-slideshow-dots a.active"
					);

			$element_styling->add_selectors( $selectors );

			//	save data for later HTML output
			$this->element_id = $element_id;
			$this->element_styles = $element_styling;

			$result['element_styling'] = $element_styling;

			return $result;
		}

		/**
		 * Create slider HTML
		 *
		 * @since ????
		 * @return string
		 */
		public function html()
		{
			global $woocommerce_loop;

			extract( $this->config );

			avia_product_slider::$slide ++;
			$post_loop_count = 1;
			$loop_counter = 1;
			$autoplay = $autoplay == 'no' ? false : true;
			$woocommerce_loop['columns'] = $columns;

			//	Add filter to change default WC image size
			add_filter( 'avf_wc_before_shop_loop_item_title_img_size', array( $this, 'handler_wc_image_size_slider' ), 1000, 1 );


			$style_tag = $this->element_styles->get_style_tag( $this->element_id );
			$container_class = $this->element_styles->get_class_string( 'container' );
			$av_display_classes = $this->element_styles->responsive_classes_string( 'hide_element', $this->config );
			$data_slideshow_options = $this->element_styles->get_data_attributes_json_string( 'container', 'slideshow-options' );

			ob_start();

			if( have_posts() )
			{
				echo $style_tag;
				echo "<div {$el_id} class='{$container_class} avia-product-slider" . avia_product_slider::$slide . "' {$data_slideshow_options}>";

				if( $sort == 'dropdown' )
				{
					avia_woocommerce_frontend_search_params();
				}

				echo 	"<div class='avia-content-slider-inner'>";

				if( $type == 'grid' )
				{
					echo '<ul class="products">';
				}

				while( have_posts() )
				{
					the_post();

					if( $loop_counter == 1 && $type == 'slider' )
					{
						echo '<ul class="products slide-entry-wrap">';
					}

					if( function_exists( 'wc_get_template_part' ) )
					{
						wc_get_template_part( 'content', 'product'  );
					}
					else
					{
						woocommerce_get_template_part( 'content', 'product' );
					}

					$loop_counter ++;
					$post_loop_count ++;

					if( $loop_counter > $columns )
					{
						$loop_counter = 1;
					}

					if( $loop_counter == 1 && $type == 'slider' )
					{
						echo '</ul>';
					}

				} // end of the loop.

				if( $loop_counter != 1 || $type == 'grid' )
				{
					echo '</ul>';
				}

				echo 	'</div>';

				if( $post_loop_count -1 > $columns && $type == 'slider' )
				{
					echo $this->slide_navigation_arrows();

					if( 'av-control-hidden' != $this->config['control_layout'] && false !== strpos( $this->config['slider_navigation'], 'av-navigate-dots' )  )
					{
						echo $this->slide_navigation_dots();
					}
				}

				echo '</div>';
			}
			else
			{
				if( function_exists( 'woocommerce_product_subcategories' ) )
				{
					if ( ! woocommerce_product_subcategories( array( 'before' => '<ul class="products">', 'after' => '</ul>' ) ) )
					{
						echo '<p>' . __( 'No products found which match your selection.', 'avia_framework' ) . '</p>';
					}
				}
			}

			echo '<div class="clear"></div>';

			$output = ob_get_clean();

			remove_filter( 'avf_wc_before_shop_loop_item_title_img_size', array( $this, 'handler_wc_image_size_slider' ), 1000 );

			if( $paginate == 'yes' && $avia_pagination = avia_pagination( '', 'nav', 'avia-element-paging', $this->current_page ) )
			{
				$output .= "<div class='pagination-wrap pagination-slider {$av_display_classes}'>{$avia_pagination}</div>";
			}

			/**
			 * @since WC 3.3.0 we have to reset WC loop counter otherwise layout might break
			 */
			if( function_exists( 'wc_reset_loop' ) )
			{
				wc_reset_loop();
			}

			wp_reset_query();

			return $output;
		}

		/**
		 * Create List Style HTML
		 *
		 * @since ????
		 * @return string
		 */
		public function html_list()
		{
			global $wp_query;

			extract( $this->config );

			avia_product_slider::$slide ++;
			$extraClass = 'first';
			$post_loop_count = 0;
			$loop_counter = 0;
			$posts_per_col = ceil( $wp_query->post_count / $columns );

			ob_start();

			$style_tag = $this->element_styles->get_style_tag( $this->element_id );
			$container_class = $this->element_styles->get_class_string( 'container' );
			$av_display_classes = $this->element_styles->responsive_classes_string( 'hide_element', $this->config );

			if( have_posts() )
			{
				while( have_posts() )
				{
					the_post();

					$post_loop_count ++;
					$loop_counter ++;
					if( $loop_counter === 1 )
					{
						echo $style_tag;
						echo "<div {$el_id} class='{$container_class} {$extraClass} avia-product-slider" . avia_product_slider::$slide . "'>";
						echo	'<div class="av-catalogue-container av-catalogue-container-woo">';
						echo		'<ul class="av-catalogue-list">';
						$extraClass = '';
					}

					$_pf = new WC_Product_Factory();
					$product = $_pf->get_product( get_the_ID() );

					if( false === $product )
					{
						continue;
					}

					$ajax_class = 'add_to_cart_button product_type_simple';
					$title = get_the_title();
					$content = strip_tags( get_the_excerpt() );
					$price = $product->get_price_html();
					$rel = '';
					$product_id = method_exists( $product , 'get_id' ) ? $product->get_id() : $product->id;
					$product_type = method_exists( $product , 'get_type' ) ? $product->get_type() : $product->product_type;

					/**
					 * Choose product types that link to single product pages when clicked and not ajax add to cart
					 * (currently only class avia_sc_productlist supports this option)
					 *
					 * @since 4.5.4
					 * @return array
					 */
					$force_product_page_array = apply_filters( 'avf_slider_add_to_cart_via_product_page', array( 'variable' ), $this );

					if( empty( $link_behavior ) || in_array( $product_type, $force_product_page_array ) )
					{
						$cart_url = get_the_permalink();
						$ajax_class = '';
					}
					else
					{
						$cart_url = $product->add_to_cart_url();
						$ajax_class = $product->is_purchasable() ? 'add_to_cart_button ajax_add_to_cart' : '';
						$rel = $product->is_purchasable() ? "rel='nofollow'" : '';
					}

					$image = get_the_post_thumbnail( $product_id, 'square', array( 'class' => "av-catalogue-image av-cart-update-image av-catalogue-image-{$show_images}" ) );

					$text  = $image;
					$text .= '<div class="av-catalogue-item-inner">';
					$text .=	'<div class="av-catalogue-title-container">';
					$text .=		"<div class='av-catalogue-title av-cart-update-title'>{$title}</div>";
					$text .=		"<div class='av-catalogue-price av-cart-update-price'>{$price}</div>";
					$text .=	'</div>';
					$text .=	"<div class='av-catalogue-content'>{$content}</div>";
					$text .= '</div>';

					/**
					 * Allows to call e.g.
					 *		do_action( 'woocommerce_product_thumbnails' );
					 *
					 * @since 4.9
					 * @param array $this->config
					 * @param aviaShortcodeTemplate $this->sc_context
					 */
					do_action( 'avf_product_slider_html_list_before_item', $this->config, $this->sc_context );

					echo '<li>';

					//copied from templates/loop/add-to-cart.php - class and rel attr changed, as well as text

					echo apply_filters( 'woocommerce_loop_add_to_cart_link',
								sprintf( '<a %s href="%s" data-product_id="%s" data-product_sku="%s" class="av-catalogue-item %s product_type_%s product-nr-%d">%s</a>',
									$rel,
									esc_url( $cart_url ),
									esc_attr( $product_id ),
									esc_attr( $product->get_sku() ),
									$ajax_class,
									esc_attr( $product_type ),
									$post_loop_count,
									$text
								),
							$product );

					echo '</li>';

					if( $loop_counter == $posts_per_col || $post_loop_count == $wp_query->post_count )
					{
						echo		'</ul>';
						echo	'</div>';
						echo '</div>';

						$loop_counter = 0;
					}

				} // end of the loop.
			}

			$output = ob_get_clean();

			if( $paginate == 'yes' && $avia_pagination = avia_pagination( '', 'nav', 'avia-element-paging', $this->current_page ) )
			{
				$output .= "<div class='pagination-wrap pagination-slider {$av_display_classes} '>{$avia_pagination}</div>";
			}

			/**
			 * @since WC 3.3.0 we have to reset WC loop counter otherwise layout might break
			 */
			if( function_exists( 'wc_reset_loop' ) )
			{
				wc_reset_loop();
			}

			wp_reset_query();

			return $output;
		}

		/**
		 * Create arrows to scroll slides
		 *
		 * @since 4.8.3			reroute to aviaFrontTemplates
		 * @return string
		 */
		protected function slide_navigation_arrows()
		{
			$args = array(
						'context'	=> get_class( $this ),
						'params'	=> $this->config,
						'svg_icon'	=> true
					);

			return aviaFrontTemplates::slide_navigation_arrows( $args );
		}

		/**
		 * Create navigation dots
		 *
		 * @since 5.0
		 * @return string
		 */
		protected function slide_navigation_dots()
		{
			$args = array(
						'total_entries'		=> $this->items,
						'container_entries'	=> $this->config['columns'],
						'context'			=> get_class( $this ),
						'params'			=> $this
					);

			return aviaFrontTemplates::slide_navigation_dots( $args );
		}

		/**
		 * Fetch new entries
		 *
		 * @param array $params
		 */
		public function query_entries( $params = array() )
		{
			global $woocommerce, $avia_config;

			$query = array();
			if( empty( $params ) )
			{
				$params = $this->config;
			}

			/**
			 * Added extended selectbox -> extract categories
			 *
			 * @since 5.4.1
			 */
			if( $params['select_type'] == 'extended' )
			{
				$ext_link = explode( ',', $params['link'] );

				if( empty( $ext_link ) )
				{
					$params['taxonomy'] = 'product_cat';
					$params['categories'] = array();
				}
				else
				{
					$params['taxonomy'] = $ext_link[0];
					unset( $ext_link[0] );
					$params['categories'] = implode( ',', $ext_link );	//	we need to renumber index later
				}
			}

			if( ! empty( $params['categories'] ) )
			{
				//get the product categories
				$terms = ! is_array( $params['categories'] ) ? explode( ',', $params['categories'] ) : $params['categories'];
			}

			$this->current_page = ( $params['paginate'] == 'no' || $params['type'] == 'slider' ) ? 1:  avia_get_current_pagination_number( 'avia-element-paging' );

			//if we find no terms for the taxonomy fetch all taxonomy terms
			if( empty( $terms[0] ) || is_null( $terms[0] ) || $terms[0] === 'null' )
			{
				$term_args = array(
								'taxonomy'		=> $params['taxonomy'],
								'hide_empty'	=> true
							);
				/**
				 * To display private posts you need to set 'hide_empty' to false,
				 * otherwise a category with ONLY private posts will not be returned !!
				 *
				 * You also need to add post_status 'private' to the query params with filter avia_product_slide_query.
				 *
				 * @since 4.4.2
				 * @added_by Günter
				 * @param array $term_args
				 * @param array $params
				 * @return array
				 */
				$term_args = apply_filters( 'avf_av_productslider_term_args', $term_args, $params );

				$allTax = AviaHelper::get_terms( $term_args );

				$terms = array();
				foreach( $allTax as $tax )
				{
					$terms[] = $tax->term_id;
				}
			}

			if( $params['sort'] == 'dropdown' )
			{
				$avia_config['woocommerce']['default_posts_per_page'] = $params['items'];
				$ordering = $woocommerce->query->get_catalog_ordering_args();
				$order = $ordering['order'];
				$orderBY = $ordering['orderby'];

				if( ! empty( $avia_config['shop_overview_products_overwritten'] ) && $params['items'] != -1 )
				{
					$params['items'] = $avia_config['shop_overview_products'];
				}
			}
			else
			{
				$avia_config['woocommerce']['disable_sorting_options'] = true;

				$chk_sort = ( empty( $params['sort'] ) || $params['sort'] == '0' ) ? '' : $params['sort'];
				$ordering = avia_wc_get_product_query_order_args( $chk_sort, $params['prod_order'] );

				$order = $ordering['order'];
				$orderBY = $ordering['orderby'];
			}


            if( $params['offset'] == 'no_duplicates' )
            {
                $params['offset'] = 0;
                $no_duplicates = true;
            }

            if( $params['offset'] == 0 )
			{
				$params['offset'] = false;
			}


			// Meta query - replaced by Tax query in WC 3.0.0
			$meta_query = array();
			$tax_query = array();

			avia_wc_set_out_of_stock_query_params( $meta_query, $tax_query, $params['wc_prod_visible'] );
			avia_wc_set_hidden_prod_query_params( $meta_query, $tax_query, $params['wc_prod_hidden'] );
			avia_wc_set_featured_prod_query_params( $meta_query, $tax_query, $params['wc_prod_featured'] );
			avia_wc_set_on_sale_prod_query_params( $meta_query, $tax_query, $params['wc_prod_sale'] );

			if( 'use_additional_filter' == $params['wc_prod_additional_filter'] )
			{
				avia_wc_set_additional_filter_args( $meta_query, $tax_query );
			}

			$avia_config['woocommerce']['disable_sorting_options'] = true;

			//	sets filter hooks !!
			$ordering_args = avia_wc_get_product_query_order_args( $orderBY, $order );

			if( ! empty( $terms ) )
			{
				$tax_query[] =  array(
									'taxonomy' 	=>	$params['taxonomy'],
									'field' 	=>	'id',
									'terms' 	=>	$terms,
									'operator' 	=>	count( $terms ) == 1 ? 'IN' : $params['term_rel']
							);
			}

			$query = array(
						'post_type'				=> $params['post_type'],
						'post_status'			=> 'publish',
						'ignore_sticky_posts'	=> 1,
						'paged'					=> $this->current_page,
						'offset'            	=> $params['offset'],
						'post__not_in'			=> ( ! empty( $no_duplicates ) ) ? $avia_config['posts_on_current_page'] : array(),
						'posts_per_page'		=> $params['items'],
						'orderby'				=> $ordering_args['orderby'],
						'order'					=> $ordering_args['order'],
						'meta_query'			=> $meta_query,
						'tax_query'				=> $tax_query
					);


			if ( ! empty( $ordering_args['meta_key'] ) )
			{
	 			$query['meta_key'] = $ordering_args['meta_key'];
	 		}

			if( 'skip_current' == $params['page_element_filter'] )
			{
				$query['post__not_in'] = isset( $query['post__not_in'] ) ? $query['post__not_in'] : [];
				$query['post__not_in'][] = get_the_ID();
			}

			/**
			 *
			 * @used_by							Avia_Relevanssi		10
			 * @since < 4.0
			 * @param array $query
			 * @param array $params
			 * @param array $ordering_args
			 * @return array
			 */
			$query = apply_filters( 'avia_product_slide_query', $query, $params, $ordering_args );

			$result = query_posts( $query );
			$this->items = count( $result );

			// store the queried post ids
            if( have_posts() )
            {
                while( have_posts() )
                {
                    the_post();
                    $avia_config['posts_on_current_page'][] = get_the_ID();
                }
            }

				//	remove all filters
			avia_wc_clear_catalog_ordering_args_filters();
			$avia_config['woocommerce']['disable_sorting_options'] = false;
		}

		/**
		 * Returns the selected image size
		 *
		 * @since 4.8
		 * @param string $size
		 * @return string
		 */
		public function handler_wc_image_size_slider( $size )
		{
			return ! empty( $this->config['image_size'] ) ? $this->config['image_size'] : $size;
		}
	}
}
