<?php
/**
 * Plain-text dynamic tokens.
 *
 * @package VoidPulse
 */

namespace VoidPulse\Shared;

defined( 'ABSPATH' ) || exit;

final class TokenRenderer {
	const FREE_TOKENS = array( 'customer', 'location', 'product', 'time_ago' );

	/**
	 * Validate a message.
	 *
	 * @param string $message Message.
	 * @return string|\WP_Error
	 */
	public static function validate_message( $message ) {
		$message = sanitize_textarea_field( wp_strip_all_tags( $message, true ) );
		if ( '' === trim( $message ) || strlen( $message ) > 300 ) {
			return new \WP_Error( 'voidpulse_invalid_message', __( 'Enter a message of 300 characters or fewer.', 'voidpulse-social-proof-for-woocommerce' ), array( 'status' => 400 ) );
		}
		preg_match_all( '/\{([a-z0-9_]+)\}/i', $message, $matches );
		$unknown = array_diff( array_unique( $matches[1] ), self::FREE_TOKENS );
		if ( $unknown ) {
			return new \WP_Error( 'voidpulse_unknown_tokens', __( 'The message contains unknown dynamic tokens.', 'voidpulse-social-proof-for-woocommerce' ), array( 'status' => 400, 'tokens' => array_values( $unknown ) ) );
		}
		return $message;
	}

	/**
	 * Render known values and normalize fallback wording.
	 *
	 * @param string              $message Message.
	 * @param array<string,mixed> $values Safe values.
	 * @return string
	 */
	public static function render( $message, $values ) {
		$replace = array();
		foreach ( self::FREE_TOKENS as $token ) {
			$replace[ '{' . $token . '}' ] = sanitize_text_field( isset( $values[ $token ] ) ? $values[ $token ] : '' );
		}
		$output = strtr( $message, $replace );
		$output = preg_replace( '/\s+/', ' ', $output );
		$output = str_replace( ' from purchased ', ' purchased ', $output );
		return trim( (string) $output );
	}
}
