<?php
/**
 * Payload resolver service.
 *
 * Coordinates resolving variable mappings to concrete data at runtime.
 *
 * @package 100Prints
 */

class Hundred_Prints_Payload_Resolver {

	/**
	 * Variable source registry.
	 *
	 * @var Hundred_Prints_Variable_Source_Registry
	 */
	private $registry;

	/**
	 * Class constructor.
	 *
	 * @param Hundred_Prints_Variable_Source_Registry|null $registry Optional registry.
	 */
	public function __construct( $registry = null ) {
		$this->registry = $registry ? $registry : hundred_prints_get_variable_source_registry();
	}

	/**
	 * Resolve variables map to final values.
	 *
	 * @param array $variable_map The variables mapping rule sets.
	 * @param int   $post_id      The current post/page context ID.
	 * @return array Mapped payload keys and resolved values.
	 */
	public function resolve( array $variable_map, $post_id = 0 ) {
		$payload = [];
		$context = [
			'post_id' => absint( $post_id ),
			'user_id' => get_current_user_id(),
		];

		foreach ( $this->normalize_variable_map( $variable_map ) as $mapping ) {
			$var_name = $mapping['key'];
			$resolved_value = $this->registry->resolve_rule( $mapping['rule'], $context );

			/**
			 * Filter the resolved variable value.
			 *
			 * This remains as a compatibility hook for filter-based third-party sources.
			 *
			 * @param mixed $resolved_value The resolved value.
			 * @param array $rule           The mapping configuration for this variable.
			 * @param int   $post_id        The current post ID.
			 */
			$payload[ $var_name ] = apply_filters( '100prints_resolve_variable_value', $resolved_value, $mapping['rule'], $post_id );
		}

		return $payload;
	}

	/**
	 * Normalize list-shaped and associative variable maps into one iterable shape.
	 *
	 * @param array $variable_map Raw or sanitized variable map.
	 * @return array
	 */
	private function normalize_variable_map( array $variable_map ) {
		$normalized = [];
		$is_list_map = array_is_list( $variable_map );

		foreach ( $variable_map as $var_name => $rule ) {
			if ( ! is_array( $rule ) ) {
				continue;
			}

			$key = $is_list_map && isset( $rule['key'] ) ? sanitize_text_field( $rule['key'] ) : sanitize_text_field( $var_name );
			if ( '' === $key ) {
				continue;
			}

			$rule['key'] = $key;

			$normalized[] = [
				'key'  => $key,
				'rule' => $rule,
			];
		}

		return $normalized;
	}
}
