<?php
/**
 * WooCommerce Cart Total condition Rules
 *
 * @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 the current WooCommerce cart total value against specified conditions
 *
 * Uses the WC Cart functionality which uses sessions and cookies.
 */
class Cart_Total extends RuleCondition {

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

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

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

		$this->category = __( 'WooCommerce', 'personalizewp' );

		$this->description = __( 'Total Cart Value', 'personalizewp' );

		$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 data against condition
	 *
	 * @param string $comparator  Comparator test to run
	 * @param mixed  $value       Comparison to check
	 * @param string $action      Action to take
	 * @param mixed  $meta        Additional meta data, unused
	 *
	 * @return bool
	 */
	public function matchesCriteria( $comparator, $value, $action, $meta = [] ): bool {

		if ( ! is_user_logged_in() ) {
			return false;
		}

		if ( ! $this->woocommerce->initialise_session_cart() ) {
			return false;
		}

		// Get cart total from WooCommerce
		$cart_total = $this->get_cart_total();

		// Note: Dealing with floats is always problematic due to PHP internal representation.
		// So multiply by 100 removing any decimal (pence), i.e. convert everything to an int.
		$value_condition = is_numeric( $value ) ? absint( 100 * $value ) : 0;
		$cart_total      = absint( 100 * $cart_total );

		// Ensure we have values to use, not zero numbers.
		if ( empty( $value_condition ) || empty( $cart_total ) ) {
			return false;
		}

		switch ( $comparator ) {
			case 'more_than':
				return $cart_total >= $value_condition;
			case 'less_than':
				return $cart_total <= $value_condition;
			case 'equals':
				return $cart_total === $value_condition;
		}

		return false;
	}

	/**
	 * Get the current cart total
	 *
	 * @return float
	 */
	private function get_cart_total(): float {
		if ( ! isset( \WC()->cart ) ) {
			return 0;
		}

		return (float) \WC()->cart->get_cart_contents_total();
	}

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

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