<?php
/**
 * WooCommerce Time Since Last Order 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 time since customer's last WooCommerce order
 *
 * Requires the user to be logged into their WP/WooCommerce user account.
 */
class Time_Since_Last_Order extends RuleCondition {

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

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

		$this->category    = __( 'WooCommerce', 'personalizewp' );
		$this->description = __( 'Time Since Last Order', 'personalizewp' );

		$this->measure_key = '';

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

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

		$user_id = get_current_user_id();
		$days    = $this->getDaysSinceLastOrder( $user_id );

		// If no orders found, return false
		if ( false === $days ) {
			return false;
		}

		$value_days = is_numeric( $value ) ? absint( $value ) : 0;

		switch ( $comparator ) {
			case 'more_than':
				return $days > $value_days;

			case 'less_than':
				return $days < $value_days;

			case 'equals':
				return $days === $value_days;
		}

		return false;
	}

	/**
	 * Get days since the customer's last order
	 *
	 * @param int $user_id The WP user ID
	 *
	 * @return int|bool Number of days since last order or false if no orders
	 */
	private function getDaysSinceLastOrder( $user_id ) {
		if ( ! function_exists( 'wc_get_orders' ) ) {
			return false;
		}

		// Get last order for user
		$orders = wc_get_orders(
			[
				'customer' => $user_id,
				'limit'    => 1,
				'orderby'  => 'date',
				'order'    => 'DESC',
				'status'   => [ 'completed', 'processing', 'on-hold' ],
			]
		);

		// If no orders found
		if ( empty( $orders ) ) {
			return false;
		}

		// Get the most recent order
		$last_order      = $orders[0];
		$last_order_date = $last_order->get_date_completed() ? $last_order->get_date_completed() : $last_order->get_date_created();

		if ( ! $last_order_date ) {
			return false;
		}

		// Calculate days difference
		$current_time = new \DateTime();
		$order_time   = new \DateTime( '@' . $last_order_date->getTimestamp() );
		$interval     = $current_time->diff( $order_time );

		return $interval->days;
	}

	/**
	 * Array of dependencies for the condition to be used
	 *
	 * @return array
	 */
	public function dependencies(): array {
		return [
			Woocommerce::instance(),
		];
	}
}
