<?php

use WPML\Collect\Support\Collection;

/**
 * @since 4.2.2
 */
class WCML_WC_Shortcode_Product_Category {

	/**
	 * @var SitePress
	 */
	private $sitepress;

	/**
	 * @param SitePress $sitepress
	 */
	public function __construct( \WPML\Core\ISitePress $sitepress ) {
		$this->sitepress = $sitepress;
	}

	public function add_hooks() {
		add_filter( 'shortcode_atts_product_categories', [ $this, 'shortcode_product_categories_convert_attributes' ] );
		add_filter( 'woocommerce_shortcode_products_query', [ $this, 'translate_category' ], 10, 2 );
	}

	/**
	 * @param array|mixed $attributes
	 *
	 * @return array|mixed
	 */
	public function shortcode_product_categories_convert_attributes( $attributes ) {
		if ( ! is_array( $attributes ) ) {
			return $attributes;
		}

		if ( ! empty( $attributes['parent'] ) ) {
			$attributes['parent'] = (int) apply_filters( 'wpml_object_id', $attributes['parent'], \WCML\Utilities\WCTaxonomies::TAXONOMY_PRODUCT_CATEGORY, true );
		}

		return $attributes;
	}

	/**
	 * @param array $args
	 * @param array $atts
	 *
	 * @return array
	 */
	public function translate_category( $args, $atts = null ) {

		if ( $this->sitepress->get_default_language() !== $this->sitepress->get_current_language() ) {

			if ( isset( $args['product_cat'] ) ) {
				$args = $this->translate_categories_using_simple_tax_query( $args );
			} elseif ( ! empty( $atts['category'] ) && isset( $args['tax_query'] ) ) {
				$getProductCategoryObject = function ( $slugOrId ) {
					if ( is_numeric( $slugOrId ) ) {
						return get_term( $slugOrId, 'product_cat' );
					}

					return get_term_by( 'slug', $slugOrId, 'product_cat' );
				};

				$categories = wpml_collect( explode( ',', $atts['category'] ) )
					->map(
						function( $slugOrId ) {
								return trim( $slugOrId ); }
					)
					->filter()
					->map( $getProductCategoryObject );

				$args = $this->replace_category_in_query_arguments( $args, $categories );
			}
		}

		return $args;
	}

	/**
	 * @param array      $args
	 * @param Collection $terms
	 *
	 * @return array
	 */
	private function replace_category_in_query_arguments( array $args, Collection $terms ) {

		foreach ( $args['tax_query'] as $i => $tax_query ) {
			if ( ! is_array( $tax_query ) ) {
				continue;
			}
			$args['tax_query'][ $i ] = [];
			if ( ! is_int( key( $tax_query ) ) ) {
				$tax_query = [ $tax_query ];
			}
			foreach ( $tax_query as $condition ) {
				if ( 'product_cat' === $condition['taxonomy'] ) {
					$condition['terms'] = $terms->pluck( $condition['field'] )->toArray();
				}
				$args['tax_query'][ $i ][] = $condition;
			}
		}

		return $args;
	}

	/**
	 * @param array $args
	 *
	 * @return array
	 */
	public function translate_categories_using_simple_tax_query( $args ) {

		$category_slugs = array_map( 'trim', explode( ',', $args['product_cat'] ) );

		$filter_exists         = remove_filter( 'terms_clauses', [ $this->sitepress, 'terms_clauses' ] );
		$categories_translated = get_terms(
			[
				'slug'     => $category_slugs,
				'taxonomy' => 'product_cat',
			]
		);
		if ( $filter_exists ) {
			add_filter( 'terms_clauses', [ $this->sitepress, 'terms_clauses' ], 10, 3 );
		}

		$category_slugs_translated = [];
		foreach ( $categories_translated as $category_translated ) {
			$category_slugs_translated[] = $category_translated->slug;
		}
		$args['product_cat'] = implode( ',', $category_slugs_translated );

		return $args;
	}


}
