<?php
/**
 * Cron for the BNPL gateway.
 *
 * @package flo-checkout
 */

namespace Flo_Checkout\Gateways\BNPL;

use Northmill_Online_Shared_Checkout\Northmill_Online_Shared\Modules\Loggers\Log_Level_Enum;

/**
 * Class BNPL_Cron
 */
class BNPL_Cron {
	const CRON_HOOK = 'northmill_bnpl_cron_check'; // Cron hook name.

	/**
	 * Set up the cron job for checking transaction status for BNPL orders.
	 *
	 * @return void
	 */
	public static function setup(): void {
		add_filter( 'cron_schedules', array( self::class, 'add_cron_schedule' ) );

		// Hook the cron job to the cron hook.
		add_action( self::CRON_HOOK, array( self::class, 'payment_status_cron' ) );

		if ( 'yes' === BNPL_Settings::get( 'enabled' ) ) {
			// Schedule the cron job, will fire every 15 minutes.
			if ( ! wp_next_scheduled( self::CRON_HOOK ) ) {
				wp_schedule_event( time(), '15_minutes', self::CRON_HOOK );
			}
		} else {
			self::clear_cron();
		}
	}

	/**
	 * Clear the scheduled hook for the cron job.
	 *
	 * @return void
	 */
	public static function clear_cron(): void {
		if ( wp_next_scheduled( self::CRON_HOOK ) ) {
			wp_clear_scheduled_hook( self::CRON_HOOK );
		}
	}

	/**
	 * Add 15-minute schedule to WordPress cron schedules
	 *
	 * @param array $schedules Array of cron schedules.
	 *
	 * @return array
	 */
	public static function add_cron_schedule( array $schedules ): array {
		$schedules['15_minutes'] = array(
			'interval' => 15 * MINUTE_IN_SECONDS, // 15 minutes in seconds
			'display'  => __( 'Every 15 minutes', 'flo-checkout-plugin' ),
		);
		return $schedules;
	}

	/**
	 * Check transaction status for BNPL orders that aren't completed.
	 * Runs on a cron job.
	 *
	 * TODO: Include a time limit? If the order is too old, don't check the status?
	 */
	public static function payment_status_cron(): void {
		BNPL_Settings::log( 'Running BNPL cron job.', null, Log_Level_Enum::INFO );

		$per_page = 10;
		$paged    = 1;

		// Get orders with a BNPL transaction ID, and the order status is pending payment.
		// Only orders that are less than 1 day old are checked.
		// Batch processing to avoid memory issues.
		do {
			$args = array(
				'post_type'      => 'shop_order',
				'post_status'    => array( 'wc-pending' ),
				'posts_per_page' => $per_page,
				'paged'          => $paged,
				'meta_query'     => array(
					array(
						'key'     => 'northmill_bnpl_transaction_id',
						'compare' => 'EXISTS',
					),
				),
				'date_query'     => array(
					array(
						'after' => '1 day ago',
					),
				),
			);

			$orders = get_posts( $args );

			if ( ! empty( $orders ) ) {
				foreach ( $orders as $order ) {
					BNPL_Settings::log( 'Checking transaction status for order', array( 'order_id' => $order->ID ), Log_Level_Enum::INFO );
					BNPL_Transactions::check_transaction_status( $order->ID );
				}
			}

			++$paged;
			$still_processing = count( $orders ) === $per_page;

		} while ( $still_processing );

		BNPL_Settings::log( 'Finished running BNPL cron job.', null, Log_Level_Enum::INFO );
	}
}
