<?php
/**
 * WooCommerce Category Quantity in Cart condition
 *
 * @link       https://personalizewp.com/
 * @since      3.2.0 Merged into PWP
 * @since      3.0.0
 *
 * @package    PersonalizeWP
 * @subpackage PersonalizeWP/Rule_Conditions/WooCommerce
 */

namespace PersonalizeWP\Rule_Conditions\WooCommerce;

use PersonalizeWP\Rule_Conditions\RuleCondition;
use PersonalizeWP\Rule_Conditions\Dependency\Woocommerce;

defined( 'ABSPATH' ) || exit; // Exit if accessed directly.

/**
 * Checks if the total quantity of products from a specific category in the cart meets the specified condition
 */
class Category_Quantity_In_Cart extends RuleCondition {

	/**
	 * Container of WC dependency and helper functions
	 *
	 * @var Woocommerce
	 */
	private object $woocommerce;

	/**
	 * Condition identifier
	 *
	 * @var string
	 */
	public string $identifier = 'woocommerce_category_quantity_in_cart';

	/**
	 * Constructor
	 */
	public function __construct() {
		parent::__construct();

		$this->category    = __( 'WooCommerce', 'personalizewp' );
		$this->description = __( 'Quantity of Category items in Cart', 'personalizewp' );

		$this->measure_key = 'category_id';

		$this->comparators = [
			'more_than' => _x( 'More Than', 'Comparator', 'personalizewp' ),
			'less_than' => _x( 'Less Than', 'Comparator', 'personalizewp' ),
			'equals'    => _x( 'Is Equal To', 'Comparator', 'personalizewp' ),
		];

		$this->comparison_values = [];
		$this->comparison_type   = 'text';
	}

	/**
	 * Test category quantity in cart against condition
	 *
	 * @param string $comparator Comparator test to run
	 * @param string $value      Quantity value to compare against
	 * @param string $action     Action to take, unused
	 * @param mixed  $meta       Additional meta data containing category_id(s)
	 *
	 * @return bool
	 */
	public function matchesCriteria( $comparator, $value, $action, $meta = [] ): bool {
		// Get category IDs from meta
		$category_ids = [];

		$meta = (array) $meta;
		if ( isset( $meta[ $this->measure_key ] ) ) {
			$category_ids = explode( ',', $meta[ $this->measure_key ] );
			// Sanitise the category IDs.
			$category_ids = array_filter( array_unique( array_map( 'intval', $category_ids ) ) );
		}

		if ( empty( $category_ids ) ) {
			return false;
		}

		$cart_products = $this->woocommerce->get_product_information_from_cart();

		// Calculate total quantity of products in any of the specified categories
		$total_quantity = 0;

		foreach ( $cart_products as $product ) {
			// Check if product belongs to any of the specified categories
			if ( isset( $product['categories'] ) ) {
				foreach ( $category_ids as $category_id ) {
					if ( in_array( $category_id, $product['categories'], true ) ) {
						$total_quantity += (int) $product['quantity'];
						break; // Don't double-count if product is in multiple specified categories
					}
				}
			}
		}

		// Convert comparison value to integer
		$comparison_value = (int) $value;

		// Perform comparison based on the comparator
		switch ( $comparator ) {
			case 'more_than':
				return $total_quantity > $comparison_value;

			case 'less_than':
				return $total_quantity < $comparison_value;

			case 'equals':
				return $total_quantity === $comparison_value;
		}

		return false;
	}

	/**
	 * Array of dependencies for the condition to be used
	 *
	 * @return array
	 */
	public function dependencies(): array {
		$this->woocommerce = Woocommerce::instance();

		return [
			$this->woocommerce,
		];
	}
}
