<?php
/**
 * Shared Cart Condition evaluator.
 *
 * @package PRECO
 */

namespace PRECO\Includes\Frontend\Core;

defined( 'ABSPATH' ) || exit;

/**
 * Evaluates "Cart Condition" rows (Cart Quantity, Cart Value, Total Spend,
 * Number of Orders, Logged in User). Shared between Popup Upsell and the
 * General recommended lists' Cart/Checkout locations.
 */
class CartConditions {

	/**
	 * Evaluate a set of Cart Condition rows (all AND'd).
	 *
	 * @param array $conditions Cart condition rows: [{ type, operator, value }].
	 * @return bool
	 */
	public static function passes( $conditions ) {
		$conditions = is_array( $conditions ) ? $conditions : array();
		if ( empty( $conditions ) ) {
			return true;
		}

		foreach ( $conditions as $condition ) {
			if ( ! is_array( $condition ) || ! self::condition_passes( $condition ) ) {
				return false;
			}
		}
		return true;
	}

	/**
	 * Evaluate a single Cart Condition row.
	 *
	 * @param array $condition Condition row: { type, operator, value }.
	 * @return bool
	 */
	private static function condition_passes( $condition ) {
		$type     = isset( $condition['type'] ) ? (string) $condition['type'] : '';
		$operator = isset( $condition['operator'] ) ? (string) $condition['operator'] : 'gte';
		$value    = isset( $condition['value'] ) ? $condition['value'] : null;

		if ( 'logged_in' === $type ) {
			$expected = ( true === $value || 'yes' === $value || '1' === $value || 1 === $value );
			return is_user_logged_in() === $expected;
		}

		$actual = null;
		switch ( $type ) {
			case 'cart_quantity':
				$actual = (float) WC()->cart->get_cart_contents_count();
				break;
			case 'cart_value':
				$actual = (float) WC()->cart->get_cart_contents_total();
				break;
			case 'total_spend':
				$actual = function_exists( 'wc_get_customer_total_spent' ) ? (float) wc_get_customer_total_spent( get_current_user_id() ) : 0.0;
				break;
			case 'order_count':
				$actual = function_exists( 'wc_get_customer_order_count' ) ? (float) wc_get_customer_order_count( get_current_user_id() ) : 0.0;
				break;
			default:
				return true; // Unknown condition type — don't block on it.
		}

		$expected = (float) $value;
		return 'lt' === $operator ? $actual < $expected : $actual >= $expected;
	}
}
