<?php
/**
 * Shortcode registration system.
 *
 * @package Rsmspark_Content_Widgets
 */

defined( 'ABSPATH' ) || exit;

/**
 * Rsmspark_Content_Widgets_Shortcodes
 *
 * Refactored in compat branch - Phase 0
 */
class Rsmspark_Content_Widgets_Shortcodes {

	/**
	 * Pending shortcode definitions.
	 *
	 * @var array<string, array{registry_id: string, callback: callable}>
	 */
	private static $registry = array();

	/**
	 * @return void
	 */
	public static function init() {
		add_action( 'init', array( __CLASS__, 'register_all' ), 20 );
	}

	/**
	 * Queue a shortcode for registration on init.
	 *
	 * @param string   $tag         Shortcode tag.
	 * @param callable $callback    Render callback.
	 * @param string   $registry_id Widget registry id.
	 * @return void
	 */
	public static function add( $tag, $callback, $registry_id = '' ) {
		$tag = sanitize_key( (string) $tag );
		if ( '' === $tag || ! is_callable( $callback ) ) {
			return;
		}

		self::$registry[ $tag ] = array(
			'registry_id' => sanitize_key( (string) $registry_id ),
			'callback'    => $callback,
		);
	}

	/**
	 * @return void
	 */
	public static function register_all() {
		if ( ! Rsmspark_Content_Widgets_Settings::shortcodes_enabled() ) {
			return;
		}

		foreach ( self::$registry as $tag => $definition ) {
			$registry_id = $definition['registry_id'];
			$callback    = $definition['callback'];

			add_shortcode(
				$tag,
				static function ( $atts, $content = '', $shortcode_tag = '' ) use ( $callback, $registry_id, $tag ) {
					unset( $shortcode_tag );

					if ( '' !== $registry_id && ! Rsmspark_Content_Widgets_Render::should_render( $registry_id ) ) {
						return '';
					}

					$atts = is_array( $atts ) ? $atts : array();
					$embed_context = array();
					foreach ( array( 'embed_width', 'embed_align', 'rsmEmbedWidth', 'rsmEmbedAlign' ) as $embed_key ) {
						if ( array_key_exists( $embed_key, $atts ) ) {
							$embed_context[ $embed_key ] = $atts[ $embed_key ];
						}
					}

					$html = (string) call_user_func( $callback, $atts, $content );
					$html = wp_kses( $html, Rsmspark_Content_Widgets_Kses::allowed_html() );

					return Rsmspark_Content_Widgets_Render::wrap_embed( $html, $embed_context );
				}
			);
		}

		$settings = Rsmspark_Content_Widgets_Settings::get();
		if ( ! empty( $settings['legacy_shortcode_support'] ) ) {
			foreach ( self::$registry as $tag => $definition ) {
				$registry_id = $definition['registry_id'];
				$legacy_tag  = '' !== $registry_id
					? Rsmspark_Content_Widgets_Registry::siteorigin_folder_id( $registry_id )
					: '';
				if ( '' === $legacy_tag || $legacy_tag === $tag || shortcode_exists( $legacy_tag ) ) {
					continue;
				}

				$callback = $definition['callback'];
				add_shortcode(
					$legacy_tag,
					static function ( $atts, $content = '', $shortcode_tag = '' ) use ( $callback, $registry_id, $legacy_tag ) {
						unset( $shortcode_tag );

						if ( '' !== $registry_id && ! Rsmspark_Content_Widgets_Render::should_render( $registry_id ) ) {
							return '';
						}

						$atts = is_array( $atts ) ? $atts : array();
						$embed_context = array();
						foreach ( array( 'embed_width', 'embed_align', 'rsmEmbedWidth', 'rsmEmbedAlign' ) as $embed_key ) {
							if ( array_key_exists( $embed_key, $atts ) ) {
								$embed_context[ $embed_key ] = $atts[ $embed_key ];
							}
						}

						$html = (string) call_user_func( $callback, $atts, $content );
						$html = wp_kses( $html, Rsmspark_Content_Widgets_Kses::allowed_html() );

						return Rsmspark_Content_Widgets_Render::wrap_embed( $html, $embed_context );
					}
				);
			}
		}

		do_action( 'rsmspark_content_widgets_shortcodes_registered', self::$registry );
	}

	/**
	 * @return array<string, array{registry_id: string, callback: callable}>
	 */
	public static function definitions() {
		return self::$registry;
	}
}
