<?php
/**
 * Specific Day, before/after type condition Rules
 *
 * @link       https://personalizewp.com/
 * @since      1.0.0
 *
 * @package    PersonalizeWP
 * @subpackage PersonalizeWP/Rule_Conditions
 */

namespace PersonalizeWP\Rule_Conditions;

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

/**
 * Checks the current date against specific date conditions
 */
class Visiting_Date extends RuleCondition {

	public string $identifier = 'core_visiting_date';

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

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

		$this->description = __( 'Date', 'personalizewp' );

		$this->comparators = [
			'before'      => _x( 'Before', 'Comparator', 'personalizewp' ),
			'after'       => _x( 'After', 'Comparator', 'personalizewp' ),
			'equals'      => _x( 'Is Equal To', 'Comparator', 'personalizewp' ),
			'days_after'  => _x( 'Days After', 'Comparator', 'personalizewp' ),
			'days_before' => _x( 'Days Before', 'Comparator', 'personalizewp' ),
		];

		$this->comparison_values = [];

		$this->comparison_type = 'datepicker';
	}

	/**
	 * 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
	 * @return bool
	 */
	public function matchesCriteria( $comparator, $value, $action, $meta = [] ): bool {
		switch ( $comparator ) {
			case 'before':
				return $this->comparatorBefore( $value );
			case 'after':
				return $this->comparatorAfter( $value );
			case 'equals':
				return $this->comparatorEquals( $value );
			case 'days_after':
				return $this->comparatorDaysAfter( $value, $meta );
			case 'days_before':
				return $this->comparatorDaysBefore( $value, $meta );
		}

		return false;
	}

	/**
	 * "Equal" test
	 *
	 * @param string $value Date value to check
	 * @return bool
	 */
	public function comparatorEquals( $value ) {
		$rule_time  = gmdate( 'Y-m-d', strtotime( $value ) );
		$users_time = gmdate( 'Y-m-d', strtotime( $GLOBALS['PERSONALIZEWP_PARAMS']['users_current_timestamp'] ) );

		if ( $rule_time === $users_time ) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * "Before" test
	 *
	 * @param string $value Date value to check
	 * @return bool
	 */
	public function comparatorBefore( $value ) {

		$rule_time  = gmdate( 'Y-m-d', strtotime( $value ) );
		$users_time = gmdate( 'Y-m-d', strtotime( $GLOBALS['PERSONALIZEWP_PARAMS']['users_current_timestamp'] ) );

		if ( $rule_time > $users_time ) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * "After" test
	 *
	 * @param string $value Date value to check
	 * @return bool
	 */
	public function comparatorAfter( $value ) {

		$rule_time  = gmdate( 'Y-m-d', strtotime( $value ) );
		$users_time = gmdate( 'Y-m-d', strtotime( $GLOBALS['PERSONALIZEWP_PARAMS']['users_current_timestamp'] ) );

		if ( $rule_time < $users_time ) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * "Days After" test - checks if current date equals the specified date plus X days
	 *
	 * @param string $value The base date value
	 * @param mixed  $meta  Meta data containing the number of days
	 * @return bool
	 */
	public function comparatorDaysAfter( $value, $meta = [] ): bool {
		if ( empty( $meta ) ) {
			return false;
		}
		// Get the number of days from meta data
		$days_offset = isset( $meta->days_number ) ? (int) $meta->days_number : 0;

		// Calculate the target date (base date + X days)
		$base_date   = gmdate( 'Y-m-d', strtotime( $value ) );
		$target_date = gmdate( 'Y-m-d', strtotime( $base_date . ' +' . $days_offset . ' days' ) );

		// Get current user's date
		$current_date = gmdate( 'Y-m-d', strtotime( $GLOBALS['PERSONALIZEWP_PARAMS']['users_current_timestamp'] ) );

		return $target_date === $current_date;
	}

	/**
	 * "Days Before" test - checks if current date equals the specified date minus X days
	 *
	 * @param string $value The base date value
	 * @param mixed  $meta  Meta data containing the number of days
	 * @return bool
	 */
	public function comparatorDaysBefore( $value, $meta = [] ): bool {
		if ( empty( $meta ) ) {
			return false;
		}
		// Get the number of days from meta data
		$days_offset = isset( $meta->days_number ) ? (int) $meta->days_number : 0;

		// Calculate the target date (base date - X days)
		$base_date   = gmdate( 'Y-m-d', strtotime( $value ) );
		$target_date = gmdate( 'Y-m-d', strtotime( $base_date . ' -' . $days_offset . ' days' ) );

		// Get current user's date
		$current_date = gmdate( 'Y-m-d', strtotime( $GLOBALS['PERSONALIZEWP_PARAMS']['users_current_timestamp'] ) );

		return $target_date === $current_date;
	}
}
