<?php
/**
 * @package Hafenstudios\Kurato
 */

namespace Hafenstudios\Kurato\Mail;

defined( 'ABSPATH' ) || exit;

/**
 * Plant die wiederkehrende Queue-Verarbeitung (K4-Konzept Abschnitt 6).
 *
 * Bevorzugt Action Scheduler (nebenlaeufigkeitssicher, WooCommerce-erprobt),
 * wenn dessen Funktionen verfuegbar sind; sonst faellt der Scheduler auf einen
 * WP-Cron-Minutentakt zurueck. So laeuft die Queue sofort, und ein spaeter
 * eingebetteter Action Scheduler wird ohne Umbau genutzt. Der eigentliche
 * Verarbeitungs-Callback haengt am Hook `kurato_process_queue`.
 */
final class QueueScheduler {

	public const HOOK     = 'kurato_process_queue';
	public const SCHEDULE = 'kurato_minute';
	public const GROUP    = 'kurato';

	/**
	 * Registriert Schedule und Cron-Intervall (idempotent).
	 *
	 * @return void
	 */
	public function register(): void {
		add_filter( 'cron_schedules', array( $this, 'add_minute_interval' ) );

		if ( $this->has_action_scheduler() ) {
			if ( ! as_has_scheduled_action( self::HOOK, array(), self::GROUP ) ) {
				as_schedule_recurring_action( time() + MINUTE_IN_SECONDS, MINUTE_IN_SECONDS, self::HOOK, array(), self::GROUP );
			}
			return;
		}

		if ( ! wp_next_scheduled( self::HOOK ) ) {
			wp_schedule_event( time() + MINUTE_IN_SECONDS, self::SCHEDULE, self::HOOK );
		}
	}

	/**
	 * Entfernt die geplante Verarbeitung (Deaktivierung).
	 *
	 * @return void
	 */
	public function unschedule(): void {
		if ( $this->has_action_scheduler() && function_exists( 'as_unschedule_all_actions' ) ) {
			as_unschedule_all_actions( self::HOOK, array(), self::GROUP );
		}
		$timestamp = wp_next_scheduled( self::HOOK );
		if ( $timestamp ) {
			wp_unschedule_event( $timestamp, self::HOOK );
		}
	}

	/**
	 * Fuegt das Minuten-Intervall fuer den WP-Cron-Fallback hinzu.
	 *
	 * @param array<string, array<string, mixed>> $schedules Bestehende Intervalle.
	 * @return array<string, array<string, mixed>>
	 */
	public function add_minute_interval( array $schedules ): array {
		if ( ! isset( $schedules[ self::SCHEDULE ] ) ) {
			$schedules[ self::SCHEDULE ] = array(
				'interval' => MINUTE_IN_SECONDS,
				'display'  => __( 'Jede Minute (Kurato-Versand)', 'kurato' ),
			);
		}
		return $schedules;
	}

	/**
	 * Ist Action Scheduler verfuegbar?
	 *
	 * @return bool
	 */
	private function has_action_scheduler(): bool {
		return function_exists( 'as_schedule_recurring_action' ) && function_exists( 'as_has_scheduled_action' );
	}
}
