<?php
/**
 * Current Products Renderer
 *
 * @package Woostify Pro
 */

namespace Elementor;

// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

/**
 * Main class
 */
class Woostify_Current_Query_Renderer extends Woostify_Base_Products_Renderer {
	/**
	 * Settings
	 *
	 * @var $settings
	 */
	private $settings = array();

	/**
	 * Constructs a new instance.
	 *
	 * @param      array  $settings The settings.
	 * @param      string $type     The type.
	 */
	public function __construct( $settings = array(), $type = 'products' ) {
		$this->settings   = $settings;
		$this->type       = $type;
		$this->attributes = $this->parse_attributes(
			array(
				'columns'  => $settings['col'],
				'paginate' => true,
				'cache'    => false,
			)
		);
		$this->query_args = $this->parse_query_args();
	}

	/**
	 * Override the original `get_query_results`
	 * with modifications that:
	 * 1. Remove `pre_get_posts` action if `is_added_product_filter`.
	 *
	 * @return bool|mixed|object
	 */
	protected function get_query_results() {
		$args = $this->query_args;
		$args['post_type' ] = 'product';
		$args['post_status' ] = 'publish';
		$args['fields' ] = "ids";
		$query = new \WP_Query( $args );
		$paginated = ! $query->get( 'no_found_rows' );

		// Check is_object to indicate it's called the first time.
		if ( ! empty( $query->posts ) && is_object( $query->posts[0] ) ) {
			$query->posts = array_map(
				function ( $post ) {
					return $post->ID;
				},
				$query->posts
			);
		}

		$results = (object) array(
			'ids'          => wp_parse_id_list( $query->posts ),
			'total'        => $paginated ? (int) $query->found_posts : count( $query->posts ),
			'total_pages'  => $paginated ? (int) $query->max_num_pages : 1,
			'per_page'     => (int) $query->get( 'posts_per_page' ),
			'current_page' => $paginated ? (int) max( 1, $query->get( 'paged', 1 ) ) : 1,
		);

		return $results;
	}

	/**
	 * Product columns
	 *
	 * @param string $class The product class.
	 */
	public function set_product_columns( $class ) {
		$settings = &$this->settings;
		$classs[] = 'products';
		$classs[] = 'columns-' . $settings['col'];
		$classs[] = 'tablet-columns-' . $settings['col_tablet'];
		$classs[] = 'mobile-columns-' . $settings['col_mobile'];

		return esc_attr( implode( ' ', $classs ) );
	}

	/**
	 * Parse query
	 */
	protected function parse_query_args() {
		global $wp_query;
		$settings = &$this->settings;

		$query_args = array(
			'post_type'   => 'product',
			'post_status' => 'publish',
			'cache'       => false,
			'orderby'     => $settings['order_by'],
			'order'       => $settings['order'],
		);
		
		$options = woostify_options( false );
		// Case widget using in woobuilder and query category products
		
		$query_args['posts_per_page'] = $options['products_per_page'];
		$query_args['paginate'] = true;
		$query_args['meta_query'] = WC()->query->get_meta_query(); // phpcs:ignore
		$query_args['tax_query']  = WC()->query->get_tax_query(); // phpcs:ignore

		if ($wp_query->is_tax && $wp_query->get_queried_object()->slug) {
			$taxonomy = $wp_query->get_queried_object()->taxonomy;
			$term_slug = $wp_query->get_queried_object()->slug;
			$query_args['tax_query'][] =  array(
				'taxonomy' => $taxonomy,
				'terms'    => array( $term_slug ),
				'field'    => 'slug',
			);
		}

		$ordering_args = WC()->query->get_catalog_ordering_args();
		// Fix case get_catalog_ordering_args get wrong data order price_desc
		$catalog_order =  get_option('woocommerce_default_catalog_orderby');
		if (!empty($catalog_order) && $catalog_order == 'price-desc') {
			$ordering_args['orderby'] = 'price-desc';
		}
		// Update orderby for woocommerce default catalog orderby
		if (!empty($catalog_order) && $catalog_order == 'menu_order') {
			$ordering_args['orderby'] = $catalog_order;
		}
		$query_args['orderby'] = $ordering_args['orderby'];
		$query_args['order']   = $ordering_args['order'];
		
		if ( $ordering_args['meta_key'] ) {
			$query_args['meta_key'] = $ordering_args['meta_key']; // phpcs:ignore
		}
		
		// Update orderby.
		if ( isset( $query_args['orderby'] ) && in_array( $query_args['orderby'], array( 'rating', 'popularity', 'date', 'date id', 'price', 'price-desc' ), true ) ) {
			$query_args['order']   = 'DESC';
			switch ( $query_args['orderby'] ) {
				case 'price':
					$query_args['orderby']  = 'meta_value_num';
					$query_args['order']   = 'ASC';
					$query_args['meta_key'] = '_price'; // phpcs:ignore
					break;
				case 'rating':
					$query_args['orderby']  = 'meta_value_num';
					$query_args['meta_key'] = '_wc_average_rating'; // phpcs:ignore
					break;
				case 'popularity':
					$query_args['orderby']  = 'meta_value_num';
					$query_args['meta_key'] = 'total_sales'; // phpcs:ignore
					break;
				case 'price-desc':
					$query_args['orderby']  = 'meta_value_num';
					$query_args['order']   = 'DESC';
					$query_args['meta_key'] = '_price'; // phpcs:ignore
					break;
				case 'date':
				case 'date id':
					$query_args['order']    = 'DESC';
					break;
				default:
					$query_args['orderby'] = $settings['order_by'];
					break;
			}

			$query_args['orderby'] = 'meta_value_num';
		}
		

		add_action(
			"woocommerce_shortcode_before_{$this->type}_loop",
			function () {
				wc_set_loop_prop( 'is_shortcode', false );
			}
		);

		// Products columns.
		add_filter( 'woostify_product_catalog_columns', array( $this, 'set_product_columns' ) );

		$page = get_query_var( 'paged', 1 );

		if ( 1 < $page ) {
			$query_args['paged'] = $page;
		}

		if ( 'yes' === $settings['pro_pagi'] ) {
			$page = isset( $_GET['page'] ) ? intval( wp_unslash( $_GET['page'] ) ) : 1; // phpcs:ignore

			if ( 1 < $page ) {
				$query_args['paged'] = $page;
			}

			// Ordering.
			if ( 'yes' === $settings['ordering'] ) {
				add_action( 'woocommerce_before_shop_loop', 'woocommerce_catalog_ordering', 30 );
			} else {
				remove_action( 'woocommerce_before_shop_loop', 'woocommerce_catalog_ordering', 30 );
			}

			// Result count.
			if ( 'yes' === $settings['result_count'] ) {
				add_action( 'woocommerce_before_shop_loop', 'woocommerce_result_count', 20 );
			} else {
				remove_action( 'woocommerce_before_shop_loop', 'woocommerce_result_count', 20 );
			}

		} else {
			remove_action( 'woocommerce_before_shop_loop', 'woocommerce_catalog_ordering', 30 );
			remove_action( 'woocommerce_before_shop_loop', 'woocommerce_result_count', 20 );
		}

		// Always query only IDs.
		$query_args['fields'] = 'ids';

		// Support 'product-filter' addon.
		if ( class_exists( 'Woostify_Product_Filter' ) ) {
			$params_query = \Woostify_Product_Filter::init()->get_active_data( 'args' );
			// Get tax_query before using wp_parse_args
			// wp_parse_args using the merge array to overide tax_query
			$tax_query = array();
			if (isset($params_query['tax_query'])) {
				$tax_query[] = $params_query['tax_query'];
			}
			if (isset($query_args['tax_query'])) {
				$tax_query = array_merge($query_args['tax_query'], $tax_query);
			}
			$query_args   = wp_parse_args( $params_query, $query_args );
			if (!empty($tax_query)) {
				$query_args['tax_query'] = $tax_query;
			}
		}

		return $query_args;
	}
}
