<?php
/**
 * Maintenance Sweep Event
 *
 * Schedules the daily maintenance sweep to reschedule recovery emails
 * for carts that fell through the cracks.
 *
 * @package EDD\Pro\CartRecovery\Cron\Events
 * @copyright Copyright (c) 2026, Sandhills Development, LLC
 * @license https://opensource.org/licenses/GPL-3.0 GNU General Public License v3.0
 * @since 3.6.5
 */

namespace EDD\Pro\CartRecovery\Cron\Events;

use EDD\Cron\Events\Event;

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

/**
 * Maintenance Sweep Event Class
 *
 * Schedules the daily sweep of abandoned carts to identify and reschedule
 * recovery emails for carts that haven't received emails due to silent failures.
 *
 * @since 3.6.5
 */
class MaintenanceSweep extends Event {

	/**
	 * Hook name.
	 *
	 * @since 3.6.5
	 * @var string
	 */
	protected $hook = 'edd_acr_maintenance_sweep';

	/**
	 * Schedule name.
	 *
	 * @since 3.6.5
	 * @var string
	 */
	protected $schedule = 'daily';

	/**
	 * Constructor.
	 *
	 * Calculates the first run time based on the configured anchor time.
	 *
	 * @since 3.6.5
	 */
	public function __construct() {
		if ( ! edd_get_option( 'acr_enabled', false ) ) {
			return;
		}

		$this->first_run = $this->calculate_anchor_time();
		parent::__construct();
	}

	/**
	 * Calculate the first run timestamp using the configured anchor time.
	 *
	 * Runs at noon (12:00) to spread load away from the cleanup job at 2am.
	 *
	 * @since 3.6.5
	 *
	 * @return int The first run timestamp.
	 */
	private function calculate_anchor_time(): int {
		$anchor = apply_filters( 'edd_acr_maintenance_sweep_anchor_time', '12:00' );

		// Get current time in WordPress site timezone.
		$site_timezone = wp_timezone();
		$now           = new \DateTime( 'now', $site_timezone );

		try {
			$today_at_anchor = new \DateTime( $now->format( 'Y-m-d' ) . ' ' . $anchor, $site_timezone );
		} catch ( \Exception $exception ) {
			return time() + DAY_IN_SECONDS;
		}

		$current_timestamp = $today_at_anchor->getTimestamp();

		// If the anchor time has already passed today, schedule for tomorrow.
		if ( $current_timestamp <= time() ) {
			$tomorrow_at_anchor = clone $today_at_anchor;
			$tomorrow_at_anchor->modify( '+1 day' );
			return $tomorrow_at_anchor->getTimestamp();
		}

		return $current_timestamp;
	}
}
