<?php

namespace Brandy\Core\Services;

/**
 * Service for replacing string variables in content.
 * Supports lazy evaluation and caching for performance optimization.
 */
class StringVariablesService {

	/**
	 * Cached variable values within request lifecycle.
	 * Prevents redundant callback executions.
	 *
	 * @var array<string, string>
	 */
	private static $cached_values = array();

	/**
	 * Returns current year
	 *
	 * @return string current year
	 */
	public static function get_current_year() {
		return gmdate( 'Y' );
	}

	/**
	 * Returns Site Title
	 *
	 * @return string Site Title
	 */
	public static function get_site_title() {
		return get_bloginfo( 'name' );
	}

	/**
	 * Returns theme author
	 *
	 * @return string Theme author
	 */
	public static function get_theme_author() {
		$theme = wp_get_theme();
		return $theme->get( 'Author' );
	}

	public static function get_heart_icon() {
		return '&hearts;';
	}

	/**
	 * Get all data (computes all values, use sparingly)
	 */
	public static function get_data() {
		$data   = self::map_with_functions();
		$result = array();
		foreach ( $data as $key => $function_data ) {
			$result[ $key ] = self::get_cached_value( $key, $function_data );
		}
		return $result;
	}

	/**
	 * Get cached value for a variable key.
	 * Computes and caches value if not already cached.
	 *
	 * @param string $key Variable key
	 * @param array  $function_data Function config with 'function' and optional 'args'
	 * @return string Computed or cached value
	 */
	private static function get_cached_value( $key, $function_data ) {
		if ( ! isset( self::$cached_values[ $key ] ) ) {
			self::$cached_values[ $key ] = call_user_func(
				$function_data['function'],
				...( $function_data['args'] ?? array() )
			);
		}
		return self::$cached_values[ $key ];
	}

	public static function map_with_functions() {
		return array(
			'current_year'            => array(
				'function' => array( self::class, 'get_current_year' ),
			),
			'site_title'              => array(
				'function' => array( self::class, 'get_site_title' ),
			),
			'theme_author'            => array(
				'function' => array( self::class, 'get_theme_author' ),
			),
			'heart_icon'              => array(
				'function' => array( self::class, 'get_heart_icon' ),
			),
			'shop_page_url'           => array(
				'function' => 'brandy_get_shop_page_url',
			),
			'cart_page_url'           => array(
				'function' => 'brandy_get_cart_page_url',
			),
			'checkout_page_url'       => array(
				'function' => 'brandy_get_checkout_page_url',
			),
			'blog_page_url'           => array(
				'function' => 'brandy_get_blog_page_url',
			),
			'home_page_url'           => array(
				'function' => 'home_url',
			),
			'login_url'               => array(
				'function' => 'brandy_get_login_url',
			),
			'contact_us_page_url'     => array(
				'function' => 'brandy_get_contact_us_page_url',
			),
			'about_us_page_url'       => array(
				'function' => 'brandy_get_about_us_page_url',
			),
			'terms_page_url'          => array(
				'function' => 'brandy_get_terms_and_conditions_page_url',
			),
			'privacy_page_url'        => array(
				'function' => 'brandy_get_privacy_policy_page_url',
			),
			'my_account_page_url'     => array(
				'function' => 'brandy_get_my_account_page_url',
			),
			'refund_returns_page_url' => array(
				'function' => 'brandy_get_refund_returns_page_url',
			),
			'my_orders_page_url'      => array(
				'function' => 'brandy_get_my_account_page_url',
				'args'     => array( 'orders' ),
			),
			'my_wishlist_page_url'    => array(
				'function' => 'brandy_get_my_account_page_url',
				'args'     => array( 'wishlist' ),
			),
		);
	}

	/**
	 * Check if content might contain variables (fast pre-check).
	 *
	 * @param string $content Content to check
	 * @return bool True if content might have variables
	 */
	public static function might_have_variables( $content ) {
		return strpos( $content, '[' ) !== false;
	}

	/**
	 * Replace variables in content with lazy evaluation and caching.
	 * Only computes values for variables that exist in content.
	 *
	 * @param string $content Content with variable placeholders like [variable_name]
	 * @return string Content with variables replaced
	 */
	public static function replace_variables( $content ) {
		// Early bail-out: no bracket means no variables
		if ( ! self::might_have_variables( $content ) ) {
			return $content;
		}

		$variables = self::map_with_functions();
		foreach ( $variables as $key => $function_data ) {
			$placeholder = "[$key]";

			// Lazy evaluation: only compute if placeholder exists
			if ( strpos( $content, $placeholder ) !== false ) {
				$value   = self::get_cached_value( $key, $function_data );
				$content = str_replace( $placeholder, $value, $content );
			}
		}

		return $content;
	}

	public static function get_string_list_variables() {
		return implode(
			', ',
			array_map(
				function( $variable_name ) {
					return "[$variable_name]";
				},
				array_keys( self::map_with_functions() )
			)
		);
	}
}
