<?php
/**
 * Merge Tags
 *
 * @package RadiusTheme\RadiusBooking\Emails
 */
namespace RadiusTheme\RadiusBooking\Emails;

if ( ! defined( 'ABSPATH' ) ) {
	exit; // Exit if accessed directly
}
/**
 * The MergeTags class handles the registration and replacement of custom merge tags.
 * These tags can be utilized to dynamically replace placeholders within content,
 * such as emails or templates, based on application-specific data.
 *
 * @package RadiusTheme\RadiusBooking\Emails
 */
class MergeTags {

	/**
	 * Registered merge tags.
	 *
	 * @var array
	 */
	private static $tags = array();

	/**
	 * Initializes and registers predefined tags with their corresponding translations.
	 *
	 * @return void
	 */
	public static function init() {
		self::register_tag( 'customer_name', __( 'Customer Name', 'radius-booking' ) );
		self::register_tag( 'customer_email', __( 'Customer Email', 'radius-booking' ) );
		self::register_tag( 'customer_phone', __( 'Customer Phone', 'radius-booking' ) );
		self::register_tag( 'staff_name', __( 'Staff Name', 'radius-booking' ) );
		self::register_tag( 'staff_email', __( 'Staff Email', 'radius-booking' ) );
		self::register_tag( 'service_name', __( 'Service Name', 'radius-booking' ) );
		self::register_tag( 'booking_id', __( 'Booking ID', 'radius-booking' ) );
		self::register_tag( 'booking_date', __( 'Booking Date', 'radius-booking' ) );
		self::register_tag( 'time', __( 'Appointment Time', 'radius-booking' ) );
		self::register_tag( 'duration', __( 'Duration', 'radius-booking' ) );
		self::register_tag( 'location', __( 'Location', 'radius-booking' ) );
		self::register_tag( 'price', __( 'Price', 'radius-booking' ) );
		self::register_tag( 'status', __( 'Status', 'radius-booking' ) );
		self::register_tag( 'notes', __( 'Notes', 'radius-booking' ) );
		self::register_tag( 'rejection_reason', __( 'Rejection Reason', 'radius-booking' ) );
		self::register_tag( 'coupon_code', __( 'Coupon Code', 'radius-booking' ) );
		self::register_tag( 'discount_amount', __( 'Discount Amount', 'radius-booking' ) );
		self::register_tag( 'site_url', __( 'Site URL', 'radius-booking' ) );
		self::register_tag( 'site_name', __( 'Site Name', 'radius-booking' ) );
		self::register_tag( 'current_year', __( 'Current Year', 'radius-booking' ) );
	}

	/**
	 * Registers a new tag with a label and an optional callback.
	 *
	 * @param string $tag The unique identifier for the tag to register.
	 * @param string $label The label associated with the tag.
	 * @param callable|null $callback An optional callback function associated with the tag.
	 *
	 * @return void
	 */
	public static function register_tag( $tag, $label, $callback = null ) {
		self::$tags[ $tag ] = array(
			'label'    => $label,
			'callback' => $callback,
		);
	}

	/**
	 * Retrieves the collection of tags.
	 *
	 * @return array The list of tags.
	 */
	public static function get_tags() {
		return self::$tags;
	}

	/**
	 * Replaces placeholders in the provided content with corresponding data.
	 *
	 * @param string $content The content containing placeholders to be replaced. Placeholders can be in the form of
	 *                        {placeholder}, [placeholder], or {{placeholder}}.
	 * @param array $data An associative array of data used for replacing placeholders. Keys correspond to
	 *                        placeholder names, and values are the replacement values.
	 *
	 * @return string The content with placeholders replaced by corresponding data values. If the input $content is
	 *                not a string or is empty, the original value of $content is returned.
	 */
	public static function replace( $content, $data ) {
		if ( empty( $content ) || ! is_string( $content ) ) {
			return $content;
		}

		$data['site_url']     = get_site_url();
		$data['site_name']    = get_bloginfo( 'name' );
		$data['current_year'] = gmdate( 'Y' );

		$patterns = array(
			'/\{([a-zA-Z0-9_]+)\}/',
			'/\[([a-zA-Z0-9_]+)\]/',
			'/\{\{([a-zA-Z0-9_]+)\}\}/',
		);

		foreach ( $patterns as $pattern ) {
			$content = preg_replace_callback(
				$pattern,
				function ( $matches ) use ( $data ) {
					$tag = $matches[1];

					if ( isset( self::$tags[ $tag ] ) && is_callable( self::$tags[ $tag ]['callback'] ) ) {
						return call_user_func( self::$tags[ $tag ]['callback'], $data );
					}

					return isset( $data[ $tag ] ) ? $data[ $tag ] : '';
				},
				$content
			);
		}

		return $content;
	}
}
