<?php
/**
 * Tax query rules helper.
 *
 * @package PRECO
 */

namespace PRECO\Includes\Frontend\Engine\Filters\Query;

defined( 'ABSPATH' ) || exit;

/**
 * Tax query rules helper.
 */
class TaxRuleHelper {
	/**
	 * Coerce a taxonomy value (string or array) to a clean array of slugs.
	 *
	 * @param mixed $value Stored rule value.
	 * @return string[]
	 */
	private function coerce_terms( $value ) {
		if ( is_string( $value ) && '' !== trim( $value ) ) {
			$value = array_values( array_filter( array_map( 'trim', explode( ',', $value ) ) ) );
		}
		return is_array( $value )
			? array_values( array_filter( array_map( 'sanitize_title', $value ) ) )
			: array();
	}

	/**
	 * Add a taxonomy term tax query clause.
	 *
	 * @param array  $tax_query Tax query array, modified by reference.
	 * @param string $taxonomy  Taxonomy name (e.g. 'product_cat').
	 * @param string $relation  Rule relation (e.g. 'not_in').
	 * @param mixed  $value     Stored term slug(s).
	 * @return void
	 */
	public function add_tax_rule( &$tax_query, $taxonomy, $relation, $value ) {
		$terms = $this->coerce_terms( $value );
		if ( empty( $terms ) ) {
			return;
		}

		$tax_query[] = array(
			'taxonomy' => $taxonomy,
			'field'    => 'slug',
			'terms'    => $terms,
			'operator' => ( 'not_in' === $relation ) ? 'NOT IN' : 'IN',
		);
	}

	/**
	 * Add a product attribute tax query clause.
	 *
	 * @param array  $tax_query Tax query array, modified by reference.
	 * @param string $relation  Rule relation (e.g. 'not_in').
	 * @param mixed  $value     Array with 'attrKey' and 'attrValue'.
	 * @return void
	 */
	public function add_attribute_rule( &$tax_query, $relation, $value ) {
		if ( ! is_array( $value ) || empty( $value['attrKey'] ) ) {
			return;
		}
		$attr_key    = sanitize_title( (string) $value['attrKey'] );
		$attr_values = isset( $value['attrValue'] ) && is_array( $value['attrValue'] ) ? array_values( array_filter( array_map( 'sanitize_title', $value['attrValue'] ) ) ) : array();
		if ( empty( $attr_values ) ) {
			return;
		}

		$taxonomy = 'pa_' . $attr_key;
		if ( ! \taxonomy_exists( $taxonomy ) ) {
			return;
		}

		$tax_query[] = array(
			'taxonomy' => $taxonomy,
			'field'    => 'slug',
			'terms'    => $attr_values,
			'operator' => ( 'not_in' === $relation ) ? 'NOT IN' : 'IN',
		);
	}

	/**
	 * Add a "featured product" tax query clause.
	 *
	 * @param array  $tax_query Tax query array, modified by reference.
	 * @param string $relation  Rule relation (e.g. 'is_not').
	 * @return void
	 */
	public function add_featured_rule( &$tax_query, $relation ) {
		$term        = function_exists( 'wc_get_product_visibility_term_ids' ) ? \wc_get_product_visibility_term_ids() : array();
		$featured_id = isset( $term['featured'] ) ? absint( $term['featured'] ) : 0;
		if ( ! $featured_id ) {
			return;
		}

		$tax_query[] = array(
			'taxonomy' => 'product_visibility',
			'field'    => 'term_id',
			'terms'    => array( $featured_id ),
			'operator' => ( 'is_not' === $relation ) ? 'NOT IN' : 'IN',
		);
	}

	/**
	 * Resolve which installed taxonomy represents "brand" for this store.
	 *
	 * @return string Taxonomy name, or empty string if none found.
	 */
	public function resolve_brand_taxonomy() {
		$preferred = \apply_filters( 'preco_brand_taxonomies', array( 'product_brand', 'pwb-brand', 'yith_product_brand', 'product-brands' ) );
		if ( ! is_array( $preferred ) ) {
			$preferred = array( 'product_brand' );
		}
		foreach ( $preferred as $tax ) {
			$tax = (string) $tax;
			if ( $tax && \taxonomy_exists( $tax ) ) {
				return $tax;
			}
		}
		return '';
	}
}
