<?php
/**
 * Abstract Automations Base Class
 *
 * Provides a reusable template for modules to register automation triggers,
 * conditions, and event handlers in a consistent way.
 *
 * @package AmbassadorHub\Automations
 */

namespace AmbassadorHub\Automations;

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

use function add_filter;

/**
 * Abstract base class for module automation registration.
 *
 * Modules should extend this class and implement the abstract methods to register
 * their triggers, conditions, and event handlers.
 *
 * Example usage:
 *
 * ```php
 * final class MyModuleAutomations extends AbstractAutomations {
 *     public static function register_trigger_groups( array $groups ): array {
 *         $groups['my_module'] = [
 *             'label' => 'My Module Events',
 *         ];
 *         return $groups;
 *     }
 *
 *     public static function register_triggers( array $triggers ): array {
 *         $triggers['my_event'] = [...];
 *         return $triggers;
 *     }
 *
 *     public static function register_conditions( array $conditions, array $context ): array {
 *         $conditions['my_condition'] = [...];
 *         return $conditions;
 *     }
 *
 *     public static function register_event_handlers(): void {
 *         add_action( 'my_module_event', [self::class, 'on_my_event'] );
 *     }
 * }
 *
 * // In Module::init()
 * MyModuleAutomations::init();
 * ```
 */
abstract class AbstractAutomations {
	/**
	 * Initialize automation registration for this module.
	 *
	 * Hooks all filter and action callbacks. Call this from your Module::init().
	 *
	 * @return void
	 */
	final public static function init(): void {
		// Register filters for triggers and conditions
		add_filter( 'ambh_automation_trigger_groups', array( static::class, 'register_trigger_groups' ) );
		add_filter( 'ambh_automation_triggers', array( static::class, 'register_triggers' ) );
		add_filter( 'ambh_automation_conditions', array( static::class, 'register_conditions' ), 10, 2 );
		add_filter( 'ambh_get_metric_value', array( static::class, 'get_metric_value' ), 10, 4 );

		// Register module-specific event handlers
		static::register_event_handlers();
	}

	/**
	 * Register trigger groups for this module.
	 *
	 * Override to add your module's trigger groups.
	 *
	 * @param array $groups Existing trigger groups.
	 *
	 * @return array Modified groups.
	 */
	public static function register_trigger_groups( array $groups ): array {
		return $groups;
	}

	/**
	 * Register triggers for this module.
	 *
	 * Override to add your module's automation triggers.
	 *
	 * @param array $triggers Existing triggers.
	 *
	 * @return array Modified triggers.
	 */
	public static function register_triggers( array $triggers ): array {
		return $triggers;
	}

	/**
	 * Register conditions for this module.
	 *
	 * Override to add your module's automation conditions.
	 *
	 * @param array $conditions Existing conditions.
	 * @param array $context    Context data (entity_type, etc).
	 *
	 * @return array Modified conditions.
	 */
	public static function register_conditions( array $conditions, array $context ): array { // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundAfterLastUsed -- $context is part of the register_conditions filter signature; base implementation doesn't need it, but subclass overrides may.
		return $conditions;
	}

	/**
	 * Provide metric values for condition evaluation.
	 *
	 * Override to provide metrics that conditions can compare against.
	 *
	 * @param mixed  $value              The metric value (default null).
	 * @param string $metric_key         Metric identifier.
	 * @param int    $target_id          Target ID.
	 * @param string $target_entity_type Target entity type.
	 *
	 * @return mixed Metric value or null if not handled.
	 */
	public static function get_metric_value( mixed $value, string $metric_key, int $target_id, string $target_entity_type ): mixed { // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundAfterLastUsed -- $metric_key, $target_id, $target_entity_type are part of the get_metric_value filter signature; base implementation doesn't need them, but subclass overrides use them to identify which metric/target to compute.
		return $value;
	}

	/**
	 * Register event handlers for this module.
	 *
	 * Override to add_action/add_filter for your module's lifecycle events.
	 *
	 * @return void
	 */
	protected static function register_event_handlers(): void {
		// Override in subclasses to register module-specific event handlers
	}
}
