<?php
/**
 * Performance Optimized Render Engine for WordPress with Conditional Rendering
 *
 * This file contains the RenderEngine class which processes scheme arrays into
 * HTML output with comprehensive charting capabilities. It implements a singleton
 * pattern with caching, security validation, and extensible renderer architecture
 * for the Ultraguard Pro plugin.
 *
 * The engine supports multiple component types including layouts, widgets,
 * forms, actions, displays, data components, and grids with advanced
 * conditional rendering and performance optimization features.
 *
 * @package    UltraguardPro\view
 * @author     Vikas Bhardwaj <support@ultraguard.net>
 * @copyright  2024 Ultraguard Pro
 * @license    GPL v2 or later
 * @version    1.2.0
 * @link       https://ultraguardpro.com/docs/render-engine
 */

namespace UltraguardPro\view;

defined( 'ABSPATH' ) || exit;

use UltraguardPro\core\CacheManager;

/**
 * Performance Optimized Render Engine with Enhanced Chart Support and Conditional Rendering
 *
 * Processes scheme arrays into HTML output with comprehensive charting capabilities
 * and advanced conditional rendering. Implements a singleton pattern with extensive
 * caching, security validation, and a modular renderer architecture. Supports over 80
 * component types with conditional rendering, dependent fields, permission-based states,
 * and performance optimization features.
 *
 * The engine routes rendering requests to specialized renderer classes based on
 * component type, applies security filters, manages caching, handles errors gracefully,
 * and implements comprehensive conditional rendering for fields, widgets, and layouts.
 *
 * @package    UltraguardPro\view
 * @author     Vikas Bhardwaj
 * @version    1.2.0
 * @since      1.0.0
 * @see        LayoutRenderer
 * @see        WidgetRenderer
 * @see        ChartRenderer
 * @see        FormRenderer
 * @see        ActionRenderer
 * @see        DisplayRenderer
 * @see        DataRenderer
 * @see        GridRenderer
 * @see        ConditionalRenderer
 *
 * @example
 * $engine = RenderEngine::get_instance();
 * $html = $engine->render([
 *     'type' => 'container',
 *     'children' => [
 *         [
 *             'type' => 'heading',
 *             'text' => 'Hello World',
 *             'conditions' => [
 *                 'field' => 'user_role',
 *                 'operator' => 'in',
 *                 'value' => ['admin', 'editor']
 *             ]
 *         ],
 *         [
 *             'type' => 'text',
 *             'name' => 'pro_feature',
 *             'label' => 'Pro Feature',
 *             'depends_on' => ['field' => 'basic_mode', 'operator' => '=', 'value' => 'enabled'],
 *             'permission_condition' => ['field' => 'user_meta:is_pro', 'operator' => '=', 'value' => 'yes'],
 *             'disabled_message' => 'Upgrade to Pro to use this feature'
 *         ]
 *     ]
 * ]);
 */
class RenderEngine {

    /**
     * Registered renderers - static for single initialization
     *
     * Associative array mapping scheme types to renderer class names.
     * Contains all registered renderers for layout, widget, form, action,
     * display, data, and grid components.
     *
     * @var array<string, string>
     * @access private
     * @static
     */
    private static $renderers = [];

    /**
     * Engine configuration - static for single initialization
     *
     * Configuration array containing debug settings, cache parameters,
     * security options, performance tuning, and conditional rendering settings.
     *
     * @var array{
     *     debug: bool,
     *     cache_enabled: bool,
     *     cache_ttl: int,
     *     auto_enqueue_assets: bool,
     *     default_wrapper_class: string,
     *     error_handling: string,
     *     max_recursion_depth: int,
     *     timeout: int,
     *     safe_mode: bool,
     *     allowed_html: array<string, array<string, bool>>,
     *     conditional_rendering: array{
     *         enabled: bool,
     *         validate_dependencies: bool,
     *         cache_conditional_results: bool,
     *         dependent_field_updates: bool,
     *         default_disabled_class: string,
     *         show_field_messages: bool
     *     }
     * }
     * @access private
     * @static
     */
    private static $config = [];

    /**
     * Current rendering context
     *
     * Array containing current rendering context including user information,
     * environment details, recursion depth tracking, and field values.
     *
     * @var array{
     *     user_id: int,
     *     is_admin: bool,
     *     is_ajax: bool,
     *     nonce: string,
     *     timestamp: int,
     *     recursion_depth: int,
     *     field_values: array,
     *     permissions: array,
     *     user_roles: array
     * }
     * @access private
     */
    private $context = [];

    /**
     * Instance for singleton pattern
     *
     * Stores the singleton instance of RenderEngine class.
     *
     * @var RenderEngine|null
     * @access private
     * @static
     */
    private static $instance = null;

    /**
     * Cache for renderer method lookups
     *
     * Cache array storing resolved render method names for renderer classes
     * to avoid repeated method_exists checks and reflection operations.
     *
     * @var array<string, string>
     * @access private
     * @static
     */
    private static $renderer_cache = [];

    /**
     * Cache for validated schemes
     *
     * Cache array storing sanitized scheme data to improve performance
     * when the same scheme is rendered multiple times.
     *
     * @var array<string, array>
     * @access private
     * @static
     */
    private static $scheme_cache = [];

    /**
     * Cache for type category mappings
     *
     * Cache array storing category determinations for scheme types
     * (layout, widget, form, display) to optimize classification.
     *
     * @var array<string, string>
     * @access private
     * @static
     */
    private static $type_category_cache = [];

    /**
     * Cache for conditional rendering results
     *
     * Cache array storing conditional rendering evaluation results
     * to improve performance for repeated conditional checks.
     *
     * @var array<string, bool>
     * @access private
     * @static
     */
    private static $conditional_cache = [];

    /**
     * Cache for field states
     *
     * Cache array storing field state evaluations (enabled/disabled)
     * with messages for performance optimization.
     *
     * @var array<string, array>
     * @access private
     * @static
     */
    private static $field_state_cache = [];

    /**
     * Track field dependencies for dynamic updates
     *
     * Array storing field dependency relationships for JavaScript
     * updates when fields change.
     *
     * @var array<string, array>
     * @access private
     */
    private $field_dependencies = [];

    /**
     * Whether renderers and config have been initialized
     *
     * Flag indicating if the static renderers and configuration arrays
     * have been initialized to prevent redundant initialization.
     *
     * @var bool
     * @access private
     * @static
     */
    private static $initialized = false;

    /**
     * Conditional Renderer instance
     *
     * Instance of ConditionalRenderer for evaluating complex conditions,
     * dependencies, and permission-based states.
     *
     * @var ConditionalRenderer|null
     * @access private
     */
    private $conditional_renderer = null;

    /**
    * Collected modals to render in footer
    *
    * @var array<string, array>
    * @access private
    * @static
    */
   private static $footer_modals = [];

   /**
    * Flag to track if footer modals have been rendered
    *
    * @var bool
    * @access private
    * @static
    */
   private static $footer_modals_rendered = false;

   /**
    * Mapping of inline modals to generated IDs
    *
    * Tracks inline modal definitions to avoid duplicates
    *
    * @var array<string, string>
    * @access private
    * @static
    */
   private static $inline_modal_ids = [];
    /**
     * Get singleton instance
     *
     * Returns the singleton instance of RenderEngine, creating it if it
     * doesn't exist. Ensures only one instance exists throughout the
     * application lifecycle.
     *
     * @return RenderEngine The singleton instance
     * @access public
     * @static
     * @since  1.0.0
     *
     * @example
     * $engine = RenderEngine::get_instance();
     * $html = $engine->render($scheme);
     */
    public static function get_instance() {
        if ( null === static::$instance ) {
            static::$instance = new static();
        }
        return static::$instance;
    }

    /**
     * Private constructor
     *
     * Initializes the render engine by setting up renderers, configuration,
     * and conditional rendering system. Prevents direct instantiation (singleton pattern).
     *
     * @return void
     * @access private
     */
    private function __construct() {
        $this->init_renderers();
        $this->init_config();
        $this->init_conditional_renderer();
    }

    /**
     * Initialize conditional renderer
     *
     * Sets up the ConditionalRenderer instance and prepares it for
     * evaluating conditions, dependencies, and field states.
     *
     * @return void
     * @access private
     * @since  1.2.0
     */
    private function init_conditional_renderer() {
        $this->conditional_renderer = ConditionalRenderer::get_instance();
    }

    /**
     * Initialize renderers with simplified chart approach
     *
     * Sets up the default renderer mappings for all component types.
     * Only initializes once per request unless explicitly reset.
     * Applies filters to allow customization of renderer mappings.
     *
     * @return void
     * @access private
     * @since  1.0.0
     *
     * @see    apply_filters()
     */
    private function init_renderers() {
        if ( self::$initialized && ! empty( self::$renderers ) ) {
            return;
        }

        // Only set default renderers if not already set
        if ( empty( self::$renderers ) ) {
            self::$renderers = [
                // Layout renderers
                'page'             => 'UltraguardPro\\view\\LayoutRenderer',
                'container'        => 'UltraguardPro\\view\\LayoutRenderer',
                'large-container'  => 'UltraguardPro\\view\\LayoutRenderer',
                'section'          => 'UltraguardPro\\view\\LayoutRenderer',
                'mini-section'     => 'UltraguardPro\\view\\LayoutRenderer',
                'module'           => 'UltraguardPro\\view\\LayoutRenderer',
                'module-set'       => 'UltraguardPro\\view\\LayoutRenderer',
                'tabs'             => 'UltraguardPro\\view\\LayoutRenderer',
                'vertical_tabs'    => 'UltraguardPro\\view\\LayoutRenderer',
                'vertical-tabs'    => 'UltraguardPro\\view\\LayoutRenderer', // hyphen alias
                'accordion'        => 'UltraguardPro\\view\\LayoutRenderer',
                'split-panel'      => 'UltraguardPro\\view\\LayoutRenderer',
                'masonry-grid'     => 'UltraguardPro\\view\\LayoutRenderer',
                'wizard'           => 'UltraguardPro\\view\\LayoutRenderer',
                'drawer'           => 'UltraguardPro\\view\\LayoutRenderer',
                'card-deck'        => 'UltraguardPro\\view\\LayoutRenderer',
                'sticky-container' => 'UltraguardPro\\view\\LayoutRenderer',
                'panel-group'      => 'UltraguardPro\\view\\LayoutRenderer',
                'carousel'         => 'UltraguardPro\\view\\LayoutRenderer',
                'kanban-board'     => 'UltraguardPro\\view\\LayoutRenderer',

                // Widget Renderers (Updated with new components)
                'stat-card'        => 'UltraguardPro\\view\\WidgetRenderer',
                'chart'            => 'UltraguardPro\\view\\ChartRenderer',
                'data-table'       => 'UltraguardPro\\view\\WidgetRenderer',
                'list'             => 'UltraguardPro\\view\\WidgetRenderer',
                'progress'         => 'UltraguardPro\\view\\WidgetRenderer',
                'timeline'         => 'UltraguardPro\\view\\WidgetRenderer',
                'card-grid'        => 'UltraguardPro\\view\\WidgetRenderer',
                'metric-panel'     => 'UltraguardPro\\view\\WidgetRenderer',
                'alert-box'        => 'UltraguardPro\\view\\WidgetRenderer',
                'info-panel'       => 'UltraguardPro\\view\\WidgetRenderer',
                'bar'              => 'UltraguardPro\\view\\WidgetRenderer',
                'ssl-status'       => 'UltraguardPro\\view\\WidgetRenderer',
                'file-integrity'   => 'UltraguardPro\\view\\WidgetRenderer',
                'backup-status'    => 'UltraguardPro\\view\\WidgetRenderer',
                'performance-impact'=> 'UltraguardPro\\view\\WidgetRenderer',
                'card'             => 'UltraguardPro\\view\\WidgetRenderer',

                // New Components added to WidgetRenderer
                'modal'            => 'UltraguardPro\\view\\WidgetRenderer',
                'dropdown'         => 'UltraguardPro\\view\\WidgetRenderer',
                'terminal'         => 'UltraguardPro\\view\\WidgetRenderer',
                'skeleton'         => 'UltraguardPro\\view\\WidgetRenderer',
                'security-dashboard'    => 'UltraguardPro\\view\\WidgetRenderer',
                'vulnerability-scanner' => 'UltraguardPro\\view\\WidgetRenderer',
                'threat-heatmap'        => 'UltraguardPro\\view\\ChartRenderer',

                // Form Renderers
                'text'             => 'UltraguardPro\\view\\FormRenderer',
                'textarea'         => 'UltraguardPro\\view\\FormRenderer',
                'select'           => 'UltraguardPro\\view\\FormRenderer',
                'radio'            => 'UltraguardPro\\view\\FormRenderer',
                'checkbox'         => 'UltraguardPro\\view\\FormRenderer',
                'toggle'           => 'UltraguardPro\\view\\FormRenderer',
                'slider'           => 'UltraguardPro\\view\\FormRenderer',
                'color'            => 'UltraguardPro\\view\\FormRenderer',
                'gradient'         => 'UltraguardPro\\view\\FormRenderer',
                'upload'           => 'UltraguardPro\\view\\FormRenderer',
                'icon-selector'    => 'UltraguardPro\\view\\FormRenderer',
                'page-selector'    => 'UltraguardPro\\view\\FormRenderer',
                'editor'           => 'UltraguardPro\\view\\FormRenderer',
                'code-editor'      => 'UltraguardPro\\view\\FormRenderer',
                'date-picker'      => 'UltraguardPro\\view\\FormRenderer',
                'time-picker'      => 'UltraguardPro\\view\\FormRenderer',
                'repeater'         => 'UltraguardPro\\view\\FormRenderer',
                'number'           => 'UltraguardPro\\view\\FormRenderer',
                'ip-address'       => 'UltraguardPro\\view\\FormRenderer',
                'severity-selector'=> 'UltraguardPro\\view\\FormRenderer',
                'password-strength'=> 'UltraguardPro\\view\\FormRenderer',
                'tag-input'        => 'UltraguardPro\\view\\FormRenderer',
                'cron-builder'     => 'UltraguardPro\\view\\FormRenderer',
                'multi-step-toggle'=> 'UltraguardPro\\view\\FormRenderer',
                'duration-picker'  => 'UltraguardPro\\view\\FormRenderer',
                'json-editor'      => 'UltraguardPro\\view\\FormRenderer',
                'country-selector' => 'UltraguardPro\\view\\FormRenderer',
                'schedule-picker'  => 'UltraguardPro\\view\\FormRenderer',

                // Action Renderers
                'button'           => 'UltraguardPro\\view\\ActionRenderer',
                'button-group'     => 'UltraguardPro\\view\\ActionRenderer',
                'submit'           => 'UltraguardPro\\view\\ActionRenderer',
                'reset'            => 'UltraguardPro\\view\\ActionRenderer',
                'ajax-action'      => 'UltraguardPro\\view\\ActionRenderer',
                'bulk-action'      => 'UltraguardPro\\view\\ActionRenderer',
                'action-bar'       => 'UltraguardPro\\view\\ActionRenderer',
                'link-button'      => 'UltraguardPro\\view\\ActionRenderer',
                'icon-button'      => 'UltraguardPro\\view\\ActionRenderer',

                // Display Renderers
                'html'             => 'UltraguardPro\\view\\DisplayRenderer',
                'message'          => 'UltraguardPro\\view\\DisplayRenderer',
                'badge'            => 'UltraguardPro\\view\\DisplayRenderer',
                'divider'          => 'UltraguardPro\\view\\DisplayRenderer',
                'spacer'           => 'UltraguardPro\\view\\DisplayRenderer',
                'icon'             => 'UltraguardPro\\view\\DisplayRenderer',
                'image'            => 'UltraguardPro\\view\\DisplayRenderer',
                'video'            => 'UltraguardPro\\view\\DisplayRenderer',
                'heading'          => 'UltraguardPro\\view\\DisplayRenderer',
                'paragraph'        => 'UltraguardPro\\view\\DisplayRenderer',
                'step-indicator'   => 'UltraguardPro\\view\\DisplayRenderer',
                'toast-notification'=> 'UltraguardPro\\view\\DisplayRenderer',
                'empty-state'      => 'UltraguardPro\\view\\DisplayRenderer',
                'animated-counter' => 'UltraguardPro\\view\\DisplayRenderer',
                'comparison-slider'=> 'UltraguardPro\\view\\DisplayRenderer',
                'skeleton-loader'  => 'UltraguardPro\\view\\DisplayRenderer',
                'collapsible'      => 'UltraguardPro\\view\\DisplayRenderer',
                'tooltip'          => 'UltraguardPro\\view\\DisplayRenderer',
                'breadcrumb'       => 'UltraguardPro\\view\\DisplayRenderer',
                'loading'          => 'UltraguardPro\\view\\DisplayRenderer',
                'security-badge'   => 'UltraguardPro\\view\\DisplayRenderer',

                // Data Renderers
                'dynamic'          => 'UltraguardPro\\view\\DataRenderer',
                'ajax-content'     => 'UltraguardPro\\view\\DataRenderer',
                'template'         => 'UltraguardPro\\view\\DataRenderer',
                'shortcode'        => 'UltraguardPro\\view\\DataRenderer',
                'widget-area'      => 'UltraguardPro\\view\\DataRenderer',
                'menu'             => 'UltraguardPro\\view\\DataRenderer',

                // Grid Renderers
                'grid'             => 'UltraguardPro\\view\\GridRenderer',
                'auto-grid'        => 'UltraguardPro\\view\\GridRenderer',
                'grid-container'   => 'UltraguardPro\\view\\GridRenderer',
                'grid-item'        => 'UltraguardPro\\view\\GridRenderer',
            ];
        }

        /**
         * Filter the available renderers
         *
         * @since 1.0.0
         * @param array $renderers The registered renderers
         * @return array Modified renderers array
         */
        if ( has_filter( 'ultraguard_render_engine_renderers' ) ) {
            self::$renderers = apply_filters( 'ultraguard_render_engine_renderers', self::$renderers );
        }

        self::$initialized = true;
    }

    /**
     * Initialize configuration with conditional rendering settings
     *
     * Sets up default configuration values for the render engine including
     * debug settings, caching parameters, security options, performance
     * tuning, and conditional rendering settings. Applies filters to allow
     * configuration customization.
     *
     * @return void
     * @access private
     * @since  1.0.0
     *
     * @see    apply_filters()
     */
    private function init_config() {
        if ( self::$initialized && ! empty( self::$config ) ) {
            return;
        }

        // Only set default config if not already set
        if ( empty( self::$config ) ) {
            self::$config = [
                'debug' => defined( 'WP_DEBUG' ) && WP_DEBUG,
                'cache_enabled' => false, // Render cache disabled — admin pages show live security data; DB-query cache (BaseTable/CacheManager) is the correct and sufficient caching layer.
                'cache_ttl' => 3600,
                'auto_enqueue_assets' => true,
                'default_wrapper_class' => 'ultraguard-component',
                'error_handling' => 'graceful',
                'max_recursion_depth' => 50,
                'timeout' => 30,
                'safe_mode' => false,
                'allowed_html' => [
                    'div' => [
                        'class' => true,
                        'id' => true,
                        'style' => true,
                        'data-*' => true
                    ],
                    'span' => [
                        'class' => true,
                        'id' => true,
                        'style' => true
                    ],
                    'p' => [
                        'class' => true,
                        'id' => true
                    ],
                    'strong' => [],
                    'em' => [],
                    'br' => [],
                    'ul' => [
                        'class' => true
                    ],
                    'ol' => [
                        'class' => true
                    ],
                    'li' => [
                        'class' => true
                    ],
                    'canvas' => [
                        'id'    => true,
                        'class' => true,
                        'style' => true,
                        'width' => true,
                        'height' => true,
                        'data-config' => true,
                    ],
                ],
                'conditional_rendering' => [
                    'enabled' => true,
                    'validate_dependencies' => true,
                    'cache_conditional_results' => true,
                    'dependent_field_updates' => true,
                    'default_disabled_class' => 'ultraguard-field-disabled',
                    'show_field_messages' => true,
                    'validation_strictness' => 'moderate', // strict, moderate, permissive
                    'dependency_resolution' => 'immediate', // immediate, deferred, hybrid
                    'permission_check_depth' => 10
                ]
            ];
        }

        /**
         * Filter the render engine configuration
         *
         * @since 1.0.0
         * @param array $config The engine configuration
         * @return array Modified configuration
         */
        if ( has_filter( 'ultraguard_render_engine_config' ) ) {
            self::$config = apply_filters( 'ultraguard_render_engine_config', self::$config );
        }
    }

    /**
     * Main rendering orchestrator with conditional rendering support
     *
     * Processes any scheme type recursively with validation, caching,
     * security checks, conditional rendering, and error handling.
     * This is the primary entry point for rendering operations.
     *
     * @param  array|mixed $scheme  The scheme array to render
     * @param  array       $context Additional context data
     * @return string               Rendered HTML output
     * @throws RenderException      If scheme is invalid or rendering fails
     * @access public
     * @since  1.0.0
     *
     * @example
     * $html = $engine->render([
     *     'type' => 'card',
     *     'title' => 'Security Status',
     *     'content' => 'All systems operational',
     *     'conditions' => ['field' => 'user_role', 'operator' => 'in', 'value' => ['admin']]
     * ], ['is_admin' => true]);
     */
    public function render( $scheme, $context = [] ) {
        // Fast path: return empty string for empty schemes
        if ( empty( $scheme ) || ! is_array( $scheme ) ) {
            return $this->handle_render_error(
                __( 'Empty or invalid scheme provided', 'ultraguard-security-suite' ),
                [ 'type' => 'unknown' ]
            );
        }

        // Secure context with defaults and sanitization
        $this->context = $this->prepare_context( $context );

        // Check recursion depth early
        if ( $this->context['recursion_depth'] > self::$config['max_recursion_depth'] ) {
            return $this->handle_render_error(
                __( 'Maximum recursion depth exceeded', 'ultraguard-security-suite' ),
                $scheme
            );
        }

        // Secure scheme with basic defaults
        $scheme = $this->prepare_scheme( $scheme );

        // Validate scheme
        if ( ! $this->validate_scheme( $scheme ) ) {
            return $this->handle_render_error(
                __( 'Invalid scheme structure', 'ultraguard-security-suite' ),
                $scheme
            );
        }

        // Render cache is intentionally disabled for admin pages.
        // Admin pages display live security data (scan results, threats, quarantine) that
        // must always reflect the latest database state. Caching rendered HTML for 15 minutes
        // would show stale threat counts and stale action buttons after quarantine/restore/delete.
        // The DB-query layer (BaseTable + CacheManager, 5 min TTL, auto-invalidated on writes)
        // is the correct and sufficient caching layer for this plugin.
        $cache_key = false;

        if ( has_action( 'ultraguard_pre_render' ) ) {
            do_action( 'ultraguard_pre_render', $scheme, $this->context );
        }

        // Apply filters
        $scheme = $this->apply_filters( $scheme, $this->context );

        // Check conditional rendering - NEW: Comprehensive conditional check
        if ( ! $this->should_render_scheme( $scheme ) ) {
            return '';
        }

        // Route to appropriate renderer
        try {
            $output = $this->route_renderer( $scheme['type'], $scheme, $this->context );
        } catch ( RenderException $e ) {
            throw $e;
        } catch ( \Exception $e ) {
            if ( self::$config['error_handling'] === 'strict' ) {
                throw new RenderException(
                    /* translators: %s: string */
                    sprintf( esc_html__( 'Rendering failed: %s', 'ultraguard-security-suite' ), esc_html( $e->getMessage() ) ),
                    (int) $e->getCode(),
                    $e // phpcs:ignore WordPress.Security.EscapeOutput.ExceptionNotEscaped -- Exception is chained for debugging, not rendered as output.
                );
            }

            return $this->handle_render_error(
                /* translators: %s: string */
                sprintf( esc_html__( 'Rendering error: %s', 'ultraguard-security-suite' ), esc_html( $e->getMessage() ) ),
                $scheme
            );
        }

        if ( has_filter( 'ultraguard_post_render' ) ) {
            $output = apply_filters( 'ultraguard_post_render', $output, $scheme, $this->context );
        }

        // Add dependency tracking data if enabled
        if ( self::$config['conditional_rendering']['dependent_field_updates'] && ! empty( $this->field_dependencies ) ) {
            $output = $this->add_dependency_data( $output, $scheme );
        }

        // Render cache write skipped — cache_enabled is false (see above).

        if ( has_action( 'ultraguard_post_render_complete' ) ) {
            do_action( 'ultraguard_post_render_complete', $output, $scheme, $this->context );
        }

        return $output;
    }

    /**
     * Prepare context with enhanced defaults for conditional rendering
     *
     * Initializes and sanitizes the rendering context with default values
     * including user information, environment flags, security tokens,
     * and field values for conditional rendering.
     *
     * @param  array $context Raw context data
     * @return array          Prepared context with defaults
     * @access private
     * @since  1.0.0
     *
     * @see    get_current_user_id()
     * @see    is_admin()
     * @see    wp_doing_ajax()
     * @see    wp_create_nonce()
     */
    private function prepare_context( $context ): array {
        // Get current user roles
        $user = wp_get_current_user();
        $user_roles = $user->exists() ? (array) $user->roles : [];

        return wp_parse_args( $context, [
            'user_id' => absint( get_current_user_id() ),
            'is_admin' => wp_validate_boolean( is_admin() ),
            'is_ajax' => wp_validate_boolean( wp_doing_ajax() ),
            'nonce' => wp_create_nonce( 'ultraguard_admin_nonce' ),
            'timestamp' => time(),
            'recursion_depth' => 0,
            'field_values' => [],
            'permissions' => [],
            'user_roles' => $user_roles,
            'is_pro' => false, // Default for pro user check
            'post_id' => get_the_ID() ?: 0,
            'page' => isset( $_GET['page'] ) ? sanitize_text_field( wp_unslash( $_GET['page'] ) ) : '', // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- read-only render context from current admin URL.
            'tab' => isset( $_GET['tab'] ) ? sanitize_text_field( wp_unslash( $_GET['tab'] ) ) : '', // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- read-only render context from current admin URL.
            'section' => isset( $_GET['section'] ) ? sanitize_text_field( wp_unslash( $_GET['section'] ) ) : '' // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- read-only render context from current admin URL.
        ] );
    }

    /**
     * Prepare scheme with enhanced defaults for conditional rendering
     *
     * Ensures all required scheme fields are present with sensible defaults
     * for consistent rendering behavior, including conditional rendering options.
     *
     * @param  array $scheme Raw scheme data
     * @return array         Prepared scheme with defaults
     * @access private
     * @since  1.0.0
     *
     * @see    wp_parse_args()
     */
    private function prepare_scheme( array $scheme ): array {
        $defaults = [
            'type' => 'container',
            'id' => 'ultraguard-' . uniqid(),
            'class' => '',
            'style' => '',
            'attributes' => [],
            'hidden' => false,
            'conditions' => [],
            'depends_on' => null,
            'permission_condition' => null,
            'disabled_message' => '',
            'disabled_reason' => 'insufficient_permission',
            'validation_rules' => [],
            'tooltip' => '',
            'help_text' => '',
            'required' => false,
            'disabled' => false,
            'readonly' => false,
            'default_value' => null,
            'placeholder' => '',
            'wrapper_class' => '',
            'wrapper_style' => '',
            'data' => [],
            'children' => [],
            'content' => '',
            'text' => '',
            'html' => '',
            'label' => '',
            'name' => '',
            'value' => '',
            'options' => []
        ];

        $prepared = wp_parse_args( $scheme, $defaults );

        // Ensure conditions is always an array
        if ( ! empty( $prepared['conditions'] ) && ! is_array( $prepared['conditions'] ) ) {
            $prepared['conditions'] = [ $prepared['conditions'] ];
        }

        return $prepared;
    }

    /**
     * Generate cache key with conditional rendering considerations
     *
     * Creates a unique cache key based on scheme content, context,
     * and conditional rendering state to enable efficient caching
     * of rendered output.
     *
     * @param  array $scheme Scheme data
     * @return string        Generated cache key
     * @access private
     * @since  1.0.0
     *
     * @see    serialize()
     * @see    md5()
     */
    private function generate_cache_key( array $scheme ): string {
        static $keys = [];

        // Include conditional rendering state in cache key
        $conditional_state = '';
        if ( self::$config['conditional_rendering']['enabled'] ) {
            $conditional_state = $this->get_conditional_state_hash( $scheme );
        }

        $key_data = $scheme['type'] . '|' . $scheme['id'] . '|' .
                    $this->context['user_id'] . '|' . $conditional_state;

        if ( ! isset( $keys[ $key_data ] ) ) {
            $keys[ $key_data ] = 'ultraguard_render_' . md5( wp_json_encode( $scheme ) . wp_json_encode( $this->context ) . $conditional_state );
        }

        return $keys[ $key_data ];
    }

    /**
     * Get hash of conditional state for caching
     *
     * Creates a hash of conditional rendering state to include in cache keys.
     *
     * @param  array $scheme Scheme data
     * @return string        Conditional state hash
     * @access private
     * @since  1.2.0
     */
    private function get_conditional_state_hash( $scheme ): string {
        $conditional_data = [
            'conditions' => $scheme['conditions'] ?? [],
            'depends_on' => $scheme['depends_on'] ?? null,
            'permission_condition' => $scheme['permission_condition'] ?? null,
            'user_roles' => $this->context['user_roles'],
            'is_pro' => $this->context['is_pro']
        ];

        return md5( wp_json_encode( $conditional_data ) );
    }

    /**
     * Sanitize scheme data
     *
     * Recursively sanitizes scheme data with appropriate sanitization
     * functions based on field type. Uses caching for performance.
     *
     * @param  array $scheme Scheme data to sanitize
     * @return array         Sanitized scheme
     * @access protected
     * @since  1.0.0
     *
     * @see    sanitize_key()
     * @see    sanitize_text_field()
     * @see    wp_kses()
     * @see    wp_validate_boolean()
     */
    protected function sanitize_scheme( $scheme ) {
        // Check cache first
        $cache_key = 'sanitize_' . md5( wp_json_encode( $scheme ) );
        if ( isset( self::$scheme_cache[ $cache_key ] ) ) {
            return self::$scheme_cache[ $cache_key ];
        }

        $sanitized = [];

        foreach ( $scheme as $key => $value ) {
            $sanitized_key = sanitize_key( $key );

            if ( is_array( $value ) ) {
                $sanitized[ $sanitized_key ] = $this->sanitize_scheme( $value );
            } else {
                switch ( $sanitized_key ) {
                    case 'type':
                    case 'id':
                    case 'class':
                    case 'name':
                    case 'label':
                    case 'placeholder':
                    case 'disabled_reason':
                        $sanitized[ $sanitized_key ] = sanitize_text_field( $value );
                        break;
                    case 'style':
                    case 'wrapper_style':
                        $sanitized[ $sanitized_key ] = wp_kses( $value, [] );
                        break;
                    case 'content':
                    case 'html':
                    case 'text':
                    case 'tooltip':
                    case 'help_text':
                    case 'disabled_message':
                        $sanitized[ $sanitized_key ] = wp_kses( $value, self::$config['allowed_html'] );
                        break;
                    case 'hidden':
                    case 'required':
                    case 'disabled':
                    case 'readonly':
                        $sanitized[ $sanitized_key ] = wp_validate_boolean( $value );
                        break;
                    default:
                        $sanitized[ $sanitized_key ] = is_string( $value ) ? sanitize_text_field( $value ) : $value;
                        break;
                }
            }
        }

        self::$scheme_cache[ $cache_key ] = $sanitized;
        return $sanitized;
    }

    /**
     * Route to specific renderer based on type - ENHANCED for conditional rendering
     *
     * Routes rendering requests to the appropriate renderer class and method
     * based on scheme type. Includes validation, security checks, caching,
     * and conditional rendering integration.
     *
     * @param  string $type    Scheme type identifier
     * @param  array  $scheme  Scheme data
     * @param  array  $context Context data
     * @return string          Rendered HTML output
     * @throws RenderException If renderer not found or inaccessible
     * @access protected
     * @since  1.0.0
     *
     * @see    class_exists()
     * @see    method_exists()
     * @see    is_callable()
     * @see    call_user_func()
     */
    protected function route_renderer( $type, $scheme, $context ) {
        // Validate type parameter
        if ( ! is_string( $type ) || ! $type ) {
            throw new RenderException(
                esc_html__( 'Invalid renderer type provided', 'ultraguard-security-suite' )
            );
        }

        // Sanitize type
        $type = sanitize_key( $type );

        // Check if renderer exists
        if ( ! isset( self::$renderers[ $type ] ) ) {
            if ( self::$config['safe_mode'] ) {
                $type = 'container';
            } else {
                throw new RenderException(
                    /* translators: %s: string */
                    sprintf( esc_html__( 'Renderer not found for type: %s', 'ultraguard-security-suite' ), esc_html( $type ) )
                );
            }
        }

        $renderer_class = self::$renderers[ $type ];

        // Validate renderer class
        if ( ! is_string( $renderer_class ) || ! $renderer_class ) {
            throw new RenderException(
                /* translators: %s: string */
                sprintf( esc_html__( 'Invalid renderer class for type: %s', 'ultraguard-security-suite' ), esc_html( $type ) )
            );
        }

        // Check cache for renderer method
        $cache_key = $type . '_' . $renderer_class;
        if ( ! isset( self::$renderer_cache[ $cache_key ] ) ) {
            if ( ! class_exists( $renderer_class ) ) {
                throw new RenderException(
                    /* translators: %s: string */
                    sprintf( esc_html__( 'Renderer class not found: %s', 'ultraguard-security-suite' ), esc_html( $renderer_class ) )
                );
            }

            // Determine render method
            $render_method = 'render_' . str_replace( '-', '_', $type );

            if ( ! method_exists( $renderer_class, $render_method ) ) {
                if ( method_exists( $renderer_class, 'render' ) ) {
                    $render_method = 'render';
                } else {
                    throw new RenderException(
                        /* translators: %1$s: string, %2$s: string */
                        sprintf( esc_html__( 'Render method not found: %1$s::%2$s', 'ultraguard-security-suite' ), esc_html( $renderer_class ), esc_html( $render_method ) )
                    );
                }
            }

            self::$renderer_cache[ $cache_key ] = $render_method;
        }

        $render_method = self::$renderer_cache[ $cache_key ];

        try {
            // Secure scheme for renderer with type-specific defaults
            $secured_scheme = $this->secure_scheme_for_renderer( $type, $scheme );

            // Apply conditional rendering modifications
            $secured_scheme = $this->apply_conditional_modifications( $secured_scheme, $context );

            if ( has_filter( 'ultraguard_pre_renderer_scheme' ) ) {
                $secured_scheme = apply_filters( 'ultraguard_pre_renderer_scheme', $secured_scheme, $type, $context );
            }

            // Track dependencies if this is a form field
            if ( in_array( $type, [ 'text', 'textarea', 'select', 'radio', 'checkbox', 'toggle', 'slider', 'number' ] ) ) {
                $this->track_field_dependencies( $secured_scheme );
            }

            if ( is_callable( [ $renderer_class, $render_method ] ) ) {
                $output = call_user_func( [ $renderer_class, $render_method ], $secured_scheme, $context );

                if ( ! is_string( $output ) ) {
                    throw new RenderException(
                        esc_html__( 'Renderer returned non-string output', 'ultraguard-security-suite' )
                    );
                }

                // Apply post-render conditional modifications
                $output = $this->apply_post_render_modifications( $output, $secured_scheme, $context );

                return $output;
            } else {
                throw new RenderException(
                    /* translators: %1$s: string, %2$s: string */
                    sprintf( esc_html__( 'Renderer method not callable: %1$s::%2$s', 'ultraguard-security-suite' ), esc_html( $renderer_class ), esc_html( $render_method ) )
                );
            }
        } catch ( \Exception $e ) {
            if ( self::$config['debug'] ) {
                \UltraguardPro\core\Logger::error(
                    sprintf(
                    'UltraGuard Pro Render Error: %s in %s on line %d',
                    $e->getMessage(),
                    $e->getFile(),
                    $e->getLine()
                )
                );
            }

            throw new RenderException(
                /* translators: %1$s: string, %2$s: string */
                sprintf( esc_html__( 'Rendering failed for %1$s: %2$s', 'ultraguard-security-suite' ), esc_html( $type ), esc_html( $e->getMessage() ) ),
                (int) $e->getCode(),
                $e // phpcs:ignore WordPress.Security.EscapeOutput.ExceptionNotEscaped -- Exception is chained for debugging, not rendered as output.
            );
        }
    }

    /**
     * Apply conditional modifications to scheme before rendering
     *
     * Modifies scheme based on conditional rendering rules, including
     * dependency checks, permission conditions, and field states.
     *
     * @param  array $scheme  Original scheme
     * @param  array $context Context data
     * @return array          Modified scheme
     * @access protected
     * @since  1.2.0
     */
    protected function apply_conditional_modifications( $scheme, $context ) {
        if ( ! self::$config['conditional_rendering']['enabled'] ) {
            return $scheme;
        }

        $modified_scheme = $scheme;

        // Check if field should be shown based on dependencies
        if ( ! empty( $scheme['depends_on'] ) ) {
            $cache_key = 'should_show_' . md5( wp_json_encode( $scheme['depends_on'] ) . wp_json_encode( $context ) );

            if ( self::$config['conditional_rendering']['cache_conditional_results'] &&
                 isset( self::$conditional_cache[ $cache_key ] ) ) {
                $should_show = self::$conditional_cache[ $cache_key ];
            } else {
                $should_show = $this->conditional_renderer->should_show_field( $scheme, $context );

                if ( self::$config['conditional_rendering']['cache_conditional_results'] ) {
                    self::$conditional_cache[ $cache_key ] = $should_show;
                }
            }

            if ( ! $should_show ) {
                $modified_scheme['hidden'] = true;
                return $modified_scheme;
            }
        }

        // Apply permission-based field states
        if ( ! empty( $scheme['permission_condition'] ) || ! empty( $scheme['disabled'] ) ) {
            $state_cache_key = 'field_state_' . md5( serialize( $scheme ) . serialize( $context ) );

            if ( self::$config['conditional_rendering']['cache_conditional_results'] &&
                 isset( self::$field_state_cache[ $state_cache_key ] ) ) {
                $field_state = self::$field_state_cache[ $state_cache_key ];
            } else {
                $field_state = $this->conditional_renderer->get_field_state( $scheme, $context );

                if ( self::$config['conditional_rendering']['cache_conditional_results'] ) {
                    self::$field_state_cache[ $state_cache_key ] = $field_state;
                }
            }

            if ( ! $field_state['enabled'] ) {
                $modified_scheme['disabled'] = true;
                $modified_scheme['readonly'] = true;

                // Add disabled class
                if ( ! empty( $modified_scheme['class'] ) ) {
                    $modified_scheme['class'] .= ' ' . self::$config['conditional_rendering']['default_disabled_class'];
                } else {
                    $modified_scheme['class'] = self::$config['conditional_rendering']['default_disabled_class'];
                }

                // Add data attributes for JavaScript
                if ( ! isset( $modified_scheme['attributes'] ) ) {
                    $modified_scheme['attributes'] = [];
                }

                $modified_scheme['attributes']['data-disabled-reason'] = $field_state['reason'];
                if ( ! empty( $field_state['message'] ) ) {
                    $modified_scheme['attributes']['data-disabled-message'] = esc_attr( $field_state['message'] );
                }
            }
        }

        // Apply validation rules if present
        if ( ! empty( $scheme['validation_rules'] ) && is_array( $scheme['validation_rules'] ) ) {
            if ( ! isset( $modified_scheme['attributes'] ) ) {
                $modified_scheme['attributes'] = [];
            }

            $modified_scheme['attributes']['data-validation-rules'] = wp_json_encode( $scheme['validation_rules'] );
        }

        return $modified_scheme;
    }

    /**
     * Apply post-render modifications
     *
     * Applies modifications to rendered output based on conditional
     * rendering rules, such as adding disabled messages.
     *
     * @param  string $output  Rendered HTML output
     * @param  array  $scheme  Scheme data
     * @param  array  $context Context data
     * @return string          Modified output
     * @access protected
     * @since  1.2.0
     */
    protected function apply_post_render_modifications( $output, $scheme, $context ) {
        if ( ! self::$config['conditional_rendering']['enabled'] ) {
            return $output;
        }

        // Add disabled message if field is disabled and message should be shown
        if ( ! empty( $scheme['disabled'] ) && self::$config['conditional_rendering']['show_field_messages'] ) {
            $field_state = $this->conditional_renderer->get_field_state( $scheme, $context );

            if ( ! $field_state['enabled'] && ! empty( $field_state['message'] ) ) {
                $message_id = 'ultraguard-message-' . sanitize_html_class( $scheme['id'] );
                $message_html = sprintf(
                    '<div id="%s" class="ultraguard-field-message ultraguard-field-message-%s">%s</div>',
                    esc_attr( $message_id ),
                    esc_attr( $field_state['reason'] ),
                    wp_kses_post( is_array( $field_state['message'] ) ? esc_html( wp_json_encode( $field_state['message'] ) ) : (string)( $field_state['message'] ) )
                );

                // Append message to output
                $output .= $message_html;

                // Wrap field if needed
                if ( strpos( $output, '<div class="ultraguard-field-wrapper' ) === false ) {
                    $output = sprintf(
                        '<div class="ultraguard-field-wrapper ultraguard-field-disabled" data-field-id="%s">%s</div>',
                        esc_attr( $scheme['id'] ),
                        $output
                    );
                }
            }
        }

        return $output;
    }
    /**
    * Collect modal for footer rendering
    *
    * @param  array  $scheme  Modal scheme data
    * @param  array  $context Rendering context
    * @return string          Empty string (modal will render in footer)
    * @access public
    * @since  1.3.0
    */
   public function collect_modal_for_footer( $scheme, $context ) {
       // Ensure modal has an ID
       $modal_id = $scheme['id'] ?? 'modal-' . uniqid();
       $scheme['id'] = $modal_id;

       // Store modal with unique ID (avoid duplicates)
       if ( ! isset( self::$footer_modals[ $modal_id ] ) ) {
           self::$footer_modals[ $modal_id ] = [
               'scheme' => $scheme,
               'context' => $context
           ];
       }

       return '';
   }

   /**
    * Collect inline modal from button/element
    *
    * Handles inline modal definitions from buttons or other elements.
    * Generates unique ID and collects for footer rendering.
    *
    * @param  array  $modal_scheme Inline modal definition
    * @param  array  $context      Rendering context
    * @return string               Generated modal ID
    * @access public
    * @since  1.3.0
    */
   public function collect_inline_modal( $modal_scheme, $context ) {
       // Generate hash of modal content to avoid duplicates
       $modal_hash = md5( serialize( $modal_scheme ) );

       // Check if we've already collected this exact modal
       if ( isset( self::$inline_modal_ids[ $modal_hash ] ) ) {
           return self::$inline_modal_ids[ $modal_hash ];
       }

       // Generate unique ID if not provided
       $modal_id = $modal_scheme['id'] ?? 'inline-modal-' . substr( $modal_hash, 0, 8 );
       $modal_scheme['id'] = $modal_id;

       // Store the modal
       if ( ! isset( self::$footer_modals[ $modal_id ] ) ) {
           self::$footer_modals[ $modal_id ] = [
               'scheme' => $modal_scheme,
               'context' => $context
           ];
       }

       // Remember this modal hash
       self::$inline_modal_ids[ $modal_hash ] = $modal_id;

       return $modal_id;
   }

    public static function render_footer_modals() {
        if ( self::$footer_modals_rendered || empty( self::$footer_modals ) ) {
            return '';
        }

        $output = '' . "\n";

        foreach ( self::$footer_modals as $modal_id => $modal_data ) {
            $scheme = $modal_data['scheme'];
            $context = $modal_data['context'];

            $scheme['id'] = $modal_id;

            try {
                // ✓ CALL render_modal_html DIRECTLY - Don't route through 'modal' type
                if ( class_exists( 'UltraguardPro\\view\\WidgetRenderer' ) ) {
                    $modal_html = \UltraguardPro\view\WidgetRenderer::render_modal_html( $scheme, $context );
                    $output .= $modal_html . "\n";
                } else {
                    throw new \Exception( esc_html( 'WidgetRenderer class not found' ) );
                }

            } catch ( \Exception $e ) {
                if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
                    $output .= sprintf(
                        '<!-- Modal rendering error (ID: %s): %s -->' . "\n",
                        esc_attr( $modal_id ),
                        esc_html( $e->getMessage() )
                    );
                }
            }
        }

        $output .= '' . "\n";

        self::$footer_modals_rendered = true;

        if ( has_filter( 'ultraguard_footer_modals_output' ) ) {
            $output = apply_filters( 'ultraguard_footer_modals_output', $output, self::$footer_modals );
        }

        return $output;
    }
   /**
    * Get modal count
    *
    * @return int Number of collected modals
    * @access public
    * @static
    */
   public static function get_modal_count() {
       return count( self::$footer_modals );
   }

   /**
    * Check if a modal ID exists
    *
    * @param  string $modal_id Modal ID to check
    * @return bool             True if modal exists
    * @access public
    * @static
    */
   public static function has_modal( $modal_id ) {
       return isset( self::$footer_modals[ $modal_id ] );
   }

   /**
    * Reset footer modals collection
    *
    * @return void
    * @access public
    * @static
    */
   public static function reset_footer_modals() {
       self::$footer_modals = [];
       self::$footer_modals_rendered = false;
       self::$inline_modal_ids = [];
   }
    /**
     * Track field dependencies for dynamic updates
     *
     * Records field dependency relationships for JavaScript updates
     * when dependent fields change.
     *
     * @param  array $scheme Field scheme
     * @return void
     * @access protected
     * @since  1.2.0
     */
    protected function track_field_dependencies( $scheme ) {
        if ( ! self::$config['conditional_rendering']['dependent_field_updates'] ) {
            return;
        }

        if ( ! empty( $scheme['depends_on'] ) ) {
            $field_id = $scheme['id'] ?? '';
            if ( ! $field_id ) {
                return;
            }

            // Extract dependencies from depends_on
            $dependencies = $this->extract_dependency_fields( $scheme['depends_on'] );

            if ( ! empty( $dependencies ) ) {
                $this->field_dependencies[ $field_id ] = [
                    'dependencies' => $dependencies,
                    'conditions' => $scheme['depends_on'],
                    'field_type' => $scheme['type']
                ];
            }
        }
    }

    /**
     * Extract dependency fields from condition
     *
     * Recursively extracts field names from dependency conditions.
     *
     * @param  mixed  $condition Dependency condition
     * @param  array  $fields    Accumulated field names
     * @return array             Extracted field names
     * @access protected
     * @since  1.2.0
     */
    protected function extract_dependency_fields( $condition, $fields = [] ) {
        if ( is_array( $condition ) ) {
            if ( isset( $condition['field'] ) ) {
                $field = $condition['field'];
                // Only add non-special fields (not WordPress conditionals or meta fields)
                if ( ! preg_match( '/^(is_|option:|user_meta:|post_meta:)/', $field ) ) {
                    $fields[] = $field;
                }
            }

            if ( isset( $condition['conditions'] ) && is_array( $condition['conditions'] ) ) {
                foreach ( $condition['conditions'] as $sub_condition ) {
                    $fields = $this->extract_dependency_fields( $sub_condition, $fields );
                }
            }

            // Check array values
            foreach ( $condition as $value ) {
                if ( is_array( $value ) ) {
                    $fields = $this->extract_dependency_fields( $value, $fields );
                }
            }
        }

        return array_unique( $fields );
    }

    /**
     * Add dependency data to output
     *
     * Adds JavaScript data attributes for dynamic dependency updates.
     *
     * @param  string $output Rendered HTML
     * @param  array  $scheme Scheme data
     * @return string         Output with dependency data
     * @access protected
     * @since  1.2.0
     */
    protected function add_dependency_data( $output, $scheme ) {
        if ( empty( $this->field_dependencies ) ) {
            return $output;
        }

        // Add dependency data as a script
        $dependency_json = wp_json_encode( $this->field_dependencies );
        $script = sprintf(
            '<script type="application/json" class="ultraguard-dependency-data">%s</script>',
            $dependency_json
        );

        return $output . $script;
    }

    /**
     * Secure scheme with type-specific defaults
     *
     * Adds type-specific default values to schemes based on category
     * (layout, widget, form, display) to ensure consistent rendering.
     *
     * @param  string $type   Renderer type
     * @param  array  $scheme Original scheme
     * @return array          Secured scheme with defaults
     * @access protected
     * @since  1.0.0
     *
     * @see    wp_parse_args()
     */
    protected function secure_scheme_for_renderer( $type, $scheme ) {
        // Cache category lookups
        if ( ! isset( self::$type_category_cache[ $type ] ) ) {
            $category = 'layout';
            if ( strpos( $type, 'chart' ) !== false || in_array( $type, [ 'stat-card', 'data-table', 'progress', 'modal', 'dropdown', 'terminal', 'skeleton', 'card' ], true ) ) {
                $category = 'widget';
            } elseif ( in_array( $type, [ 'text', 'textarea', 'select', 'radio', 'checkbox' ], true ) ) {
                $category = 'form';
            } elseif ( in_array( $type, [ 'html', 'message', 'badge', 'icon' ], true ) ) {
                $category = 'display';
            }
            self::$type_category_cache[ $type ] = $category;
        } else {
            $category = self::$type_category_cache[ $type ];
        }

        $type_defaults = [
            'layout' => [
                'class' => '',
                'style' => '',
                'id' => 'ultraguard-' . $type . '-' . uniqid(),
                'attributes' => [],
                'children' => [],
                'conditions' => [],
                'depends_on' => null
            ],
            'form' => [
                'name' => '',
                'value' => '',
                'label' => '',
                'description' => '',
                'required' => false,
                'disabled' => false,
                'readonly' => false,
                'options' => [],
                'placeholder' => '',
                'validation_rules' => [],
                'depends_on' => null,
                'permission_condition' => null,
                'disabled_message' => '',
                'tooltip' => '',
                'help_text' => ''
            ],
            'widget' => [
                'title' => '',
                'data' => [],
                'config' => [],
                'conditions' => [],
                'depends_on' => null
            ],
            'display' => [
                'content' => '',
                'html' => '',
                'text' => '',
                'conditions' => [],
                'depends_on' => null
            ]
        ];

        $defaults = $type_defaults[ $category ] ?? $type_defaults['layout'];

        return wp_parse_args( $scheme, $defaults );
    }

    /**
     * Execute rendering filters
     *
     * Applies WordPress filters to the scheme before rendering to allow
     * modification by plugins and themes. Supports type-specific and
     * ID-specific filters.
     *
     * @param  array $scheme  Scheme data
     * @param  array $context Context data
     * @return array          Filtered scheme
     * @access protected
     * @since  1.0.0
     *
     * @see    apply_filters()
     */
    protected function apply_filters( $scheme, $context ) {
        // Secure scheme before applying filters
        $secured_scheme = wp_parse_args( $scheme, [
            'type' => 'unknown',
            'id' => '',
            'class' => '',
            'filters' => [],
            'conditions' => [],
            'depends_on' => null
        ] );

        if ( has_filter( 'ultraguard_pre_render_scheme' ) ) {
            $filtered_scheme = apply_filters( 'ultraguard_pre_render_scheme', $secured_scheme, $context );
        } else {
            $filtered_scheme = $secured_scheme;
        }

        $scheme_type = $filtered_scheme['type'];
        if ( $scheme_type && $scheme_type !== 'unknown' && has_filter( "ultraguard_pre_render_scheme_{$scheme_type}" ) ) {
            $filtered_scheme = apply_filters( "ultraguard_pre_render_scheme_{$scheme_type}", $filtered_scheme, $context );
        }

        $scheme_id = $filtered_scheme['id'] ?? '';
        if ( $scheme_id && has_filter( "ultraguard_pre_render_scheme_{$scheme_id}" ) ) {
            $filtered_scheme = apply_filters( "ultraguard_pre_render_scheme_{$scheme_id}", $filtered_scheme, $context );
        }

        return $filtered_scheme;
    }

    /**
     * Validate scheme structure with conditional rendering support
     *
     * Performs structural validation on scheme data to ensure it contains
     * required fields, references valid renderer types, and has valid
     * conditional rendering configurations.
     *
     * @param  array $scheme Scheme to validate
     * @return bool          True if valid, false otherwise
     * @access protected
     * @since  1.0.0
     */
    protected function validate_scheme( $scheme ) {
        if ( ! is_array( $scheme ) || empty( $scheme ) ) {
            return false;
        }

        if ( ! isset( $scheme['type'] ) || ! is_string( $scheme['type'] ) ) {
            return false;
        }

        // Cache valid types
        static $valid_types = null;
        if ( $valid_types === null ) {
            $valid_types = array_keys( self::$renderers );
        }

        if ( ! in_array( $scheme['type'], $valid_types, true ) ) {
            if ( ! self::$config['safe_mode'] ) {
                return false;
            }
        }

        // Validate conditional rendering configuration if present
        if ( self::$config['conditional_rendering']['enabled'] && self::$config['conditional_rendering']['validate_dependencies'] ) {
            if ( ! $this->validate_conditional_configuration( $scheme ) ) {
                return false;
            }
        }

        return true;
    }

    /**
     * Validate conditional rendering configuration
     *
     * Validates conditional rendering configuration including dependencies,
     * permission conditions, and field states.
     *
     * @param  array $scheme Scheme data
     * @return bool          True if valid, false otherwise
     * @access protected
     * @since  1.2.0
     */
    protected function validate_conditional_configuration( $scheme ) {
        // Validate depends_on configuration
        if ( ! empty( $scheme['depends_on'] ) ) {
            if ( ! $this->conditional_renderer->validate_condition( $scheme['depends_on'] ) ) {
                if ( self::$config['debug'] ) {
                    \UltraguardPro\core\Logger::error(
                        sprintf(
                        'UltraGuard Pro: Invalid depends_on condition for scheme: %s',
                        $scheme['id'] ?? 'unknown'
                    )
                    );
                }
                return false;
            }
        }

        // Validate permission_condition configuration
        if ( ! empty( $scheme['permission_condition'] ) ) {
            if ( ! $this->conditional_renderer->validate_condition( $scheme['permission_condition'] ) ) {
                if ( self::$config['debug'] ) {
                    \UltraguardPro\core\Logger::error(
                        sprintf(
                        'UltraGuard Pro: Invalid permission_condition for scheme: %s',
                        $scheme['id'] ?? 'unknown'
                    )
                    );
                }
                return false;
            }
        }

        // Validate conditions configuration
        if ( ! empty( $scheme['conditions'] ) ) {
            if ( is_array( $scheme['conditions'] ) ) {
                foreach ( $scheme['conditions'] as $condition ) {
                    if ( ! $this->conditional_renderer->validate_condition( $condition ) ) {
                        if ( self::$config['debug'] ) {
                            \UltraguardPro\core\Logger::error(
                                sprintf(
                                'UltraGuard Pro: Invalid condition in scheme: %s',
                                $scheme['id'] ?? 'unknown'
                            )
                            );
                        }
                        return false;
                    }
                }
            } elseif ( ! $this->conditional_renderer->validate_condition( $scheme['conditions'] ) ) {
                if ( self::$config['debug'] ) {
                    \UltraguardPro\core\Logger::error(
                        sprintf(
                        'UltraGuard Pro: Invalid conditions for scheme: %s',
                        $scheme['id'] ?? 'unknown'
                    )
                    );
                }
                return false;
            }
        }

        return true;
    }

    /**
     * Enhanced: Check if scheme should be rendered based on conditions
     *
     * Evaluates rendering conditions including user capabilities, roles,
     * custom conditions, dependencies, and permission-based states to
     * determine if a scheme should be rendered.
     *
     * @param  array $scheme Scheme data
     * @return bool          Whether to render the scheme
     * @access protected
     * @since  1.0.0
     *
     * @see    current_user_can()
     * @see    wp_get_current_user()
     * @see    ConditionalRenderer
     */
    protected function should_render_scheme( $scheme ) {
        $secured_scheme = wp_parse_args( $scheme, [
            'hidden' => false,
            'capability' => '',
            'roles' => [],
            'condition' => null,
            'conditions' => [],
            'depends_on' => null,
            'permission_condition' => null
        ] );

        // Check basic hidden flag
        if ( ! empty( $secured_scheme['hidden'] ) ) {
            return false;
        }

        // Check capability
        if ( ! empty( $secured_scheme['capability'] ) ) {
            if ( ! current_user_can( $secured_scheme['capability'] ) ) {
                return false;
            }
        }

        // Check roles
        if ( ! empty( $secured_scheme['roles'] ) && is_array( $secured_scheme['roles'] ) ) {
            static $current_user_roles = null;
            if ( $current_user_roles === null ) {
                $user = wp_get_current_user();
                $current_user_roles = $user->exists() ? (array) $user->roles : [];
            }

            $has_role = false;
            foreach ( $secured_scheme['roles'] as $role ) {
                if ( in_array( $role, $current_user_roles, true ) ) {
                    $has_role = true;
                    break;
                }
            }

            if ( ! $has_role ) {
                return false;
            }
        }

        // Check conditions (backward compatibility)
        if ( ! empty( $secured_scheme['condition'] ) ) {
            try {
                if ( ! $this->conditional_renderer->evaluate( $secured_scheme['condition'], $this->context ) ) {
                    return false;
                }
            } catch ( \Exception $e ) {
                if ( self::$config['debug'] ) {
                    \UltraguardPro\core\Logger::error( 'UltraGuard Pro Condition Error: ' . $e->getMessage() );
                }

                if ( ! self::$config['safe_mode'] ) {
                    return false;
                }
            }
        }

        // Check conditions array (new method)
        if ( ! empty( $secured_scheme['conditions'] ) && is_array( $secured_scheme['conditions'] ) ) {
            try {
                foreach ( $secured_scheme['conditions'] as $condition ) {
                    if ( ! $this->conditional_renderer->evaluate( $condition, $this->context ) ) {
                        return false;
                    }
                }
            } catch ( \Exception $e ) {
                if ( self::$config['debug'] ) {
                    \UltraguardPro\core\Logger::error( 'UltraGuard Pro Conditions Error: ' . $e->getMessage() );
                }

                if ( ! self::$config['safe_mode'] ) {
                    return false;
                }
            }
        }

        // Check dependencies (using the enhanced ConditionalRenderer)
        if ( self::$config['conditional_rendering']['enabled'] && ! empty( $secured_scheme['depends_on'] ) ) {
            try {
                if ( ! $this->conditional_renderer->should_show_field( $secured_scheme, $this->context ) ) {
                    return false;
                }
            } catch ( \Exception $e ) {
                if ( self::$config['debug'] ) {
                    \UltraguardPro\core\Logger::error( 'UltraGuard Pro Dependency Error: ' . $e->getMessage() );
                }

                if ( ! self::$config['safe_mode'] ) {
                    return false;
                }
            }
        }

        // Check permission condition
        if ( self::$config['conditional_rendering']['enabled'] && ! empty( $secured_scheme['permission_condition'] ) ) {
            try {
                $field_state = $this->conditional_renderer->get_field_state( $secured_scheme, $this->context );
                if ( ! $field_state['enabled'] ) {
                    // Field should still render but will be disabled
                    return true;
                }
            } catch ( \Exception $e ) {
                if ( self::$config['debug'] ) {
                    \UltraguardPro\core\Logger::error( 'UltraGuard Pro Permission Error: ' . $e->getMessage() );
                }

                if ( ! self::$config['safe_mode'] ) {
                    return false;
                }
            }
        }

        return true;
    }

    /**
     * Handle rendering errors gracefully
     *
     * Generates appropriate error output based on configuration settings.
     * Supports debug mode with detailed information or graceful degradation.
     *
     * @param  string $error  Error message
     * @param  array  $scheme Scheme data that caused the error
     * @return string         Error HTML or empty string
     * @access protected
     * @since  1.0.0
     *
     * @see    esc_html()
     * @see    esc_attr()
     */
    protected function handle_render_error( $error, $scheme ) {
        $secured_scheme = wp_parse_args( $scheme, [
            'type' => 'unknown',
            'id' => 'unknown'
        ] );

        if ( self::$config['debug'] ) {
            $scheme_debug = esc_html( (string) wp_json_encode( $secured_scheme, JSON_PRETTY_PRINT ) );

            return sprintf(
                '<div class="ultraguard-render-error" style="border: 2px solid #dc3232; padding: 10px; margin: 10px 0; background: #ffeaea;">' .
                '<strong>%s</strong><br>%s<pre>%s</pre></div>',
                esc_html__( 'Rendering Error', 'ultraguard-security-suite' ),
                esc_html( $error ),
                $scheme_debug
            );
        }

        if ( self::$config['error_handling'] === 'debug' ) {
            return sprintf(
                '<div class="ultraguard-render-error" style="display: none;" data-error="%s"></div>',
                esc_attr( $error )
            );
        }

        return '';
    }

    /**
     * Set configuration
     *
     * Updates the render engine configuration with new values while
     * preserving existing configuration for unspecified keys.
     *
     * @param  array $config Configuration array with new values
     * @return void
     * @access public
     * @since  1.0.0
     *
     * @see    wp_parse_args()
     */
    public function set_config( $config ) {
        self::$config = wp_parse_args( $config, self::$config );
    }

    /**
     * Get configuration
     *
     * Returns the current render engine configuration array.
     *
     * @return array Current configuration
     * @access public
     * @since  1.0.0
     */
    public function get_config() {
        return self::$config;
    }

    /**
     * Get registered renderers
     *
     * Returns the complete array of registered renderer mappings.
     *
     * @return array<string, string> Registered renderers
     * @access public
     * @since  1.0.0
     */
    public function get_renderers() {
        return self::$renderers;
    }

    /**
     * Register custom renderer
     *
     * Registers a new renderer class for a specific scheme type.
     * Validates the renderer class exists and updates internal caches.
     *
     * @param  string $type           Scheme type identifier
     * @param  string $renderer_class Fully qualified renderer class name
     * @return bool                   True if registration successful, false otherwise
     * @access public
     * @since  1.0.0
     *
     * @see    class_exists()
     * @see    sanitize_key()
     */
    public function register_renderer( $type, $renderer_class ) {
        if ( ! is_string( $type ) || ! $type || ! is_string( $renderer_class ) || ! $renderer_class ) {
            return false;
        }

        $type = sanitize_key( $type );
        $renderer_class = sanitize_text_field( $renderer_class );

        if ( ! class_exists( $renderer_class ) ) {
            if ( self::$config['debug'] ) {
                \UltraguardPro\core\Logger::error( sprintf( 'UltraGuard Pro: Renderer class not found: %s', $renderer_class ) );
            }
            return false;
        }

        self::$renderers[ $type ] = $renderer_class;

        // Clear renderer cache for this type
        unset( self::$renderer_cache[ $type . '_' . $renderer_class ] );

        return true;
    }

    /**
     * Unregister renderer
     *
     * Removes a renderer registration for a specific scheme type.
     * Clears related caches to prevent stale data.
     *
     * @param  string $type Scheme type identifier
     * @return bool         True if renderer was unregistered, false if not found
     * @access public
     * @since  1.0.0
     */
    public function unregister_renderer( $type ) {
        if ( isset( self::$renderers[ $type ] ) ) {
            $renderer_class = self::$renderers[ $type ];
            unset( self::$renderers[ $type ] );

            // Clear renderer cache for this type
            unset( self::$renderer_cache[ $type . '_' . $renderer_class ] );

            return true;
        }
        return false;
    }

    /**
     * Check if renderer is registered
     *
     * Verifies if a renderer is registered for a specific scheme type
     * and that the renderer class exists.
     *
     * @param  string $type Scheme type identifier
     * @return bool         Whether renderer is registered and class exists
     * @access public
     * @since  1.0.0
     *
     * @see    class_exists()
     */
    public function has_renderer( $type ) {
        return isset( self::$renderers[ $type ] ) && class_exists( self::$renderers[ $type ] );
    }

    /**
     * Get current context
     *
     * Returns the current rendering context array.
     *
     * @return array Current context data
     * @access public
     * @since  1.0.0
     */
    public function get_context() {
        return $this->context;
    }

    /**
     * Update context with field values for conditional rendering
     *
     * Updates the current rendering context with new values while
     * preserving existing context data. Specifically handles field
     * values for conditional rendering.
     *
     * @param  array $context New context data
     * @return void
     * @access public
     * @since  1.0.0
     *
     * @see    wp_parse_args()
     */
    public function update_context( $context ) {
        $this->context = wp_parse_args( $context, $this->context );

        // Clear conditional caches when context changes significantly
        if ( isset( $context['field_values'] ) || isset( $context['user_roles'] ) || isset( $context['is_pro'] ) ) {
            $this->clear_conditional_caches();
        }
    }

    /**
     * Clear conditional rendering caches
     *
     * Clears conditional rendering caches to ensure fresh evaluations
     * when context changes.
     *
     * @return void
     * @access public
     * @since  1.2.0
     */
    public function clear_conditional_caches() {
        self::$conditional_cache = [];
        self::$field_state_cache = [];
        $this->field_dependencies = [];
    }

    /**
     * Clear render cache
     *
     * Clears all cached render data including object cache, transients,
     * and internal caches. Useful for development or after updates.
     *
     * @return bool True if cache cleared successfully, false otherwise
     * @access public
     * @since  1.0.0
     *
     * @see    CacheManager::invalidate_db()
     */
    public function clear_cache() {
        // Render cache is permanently disabled — only the DB-query cache exists.
        // wp_cache_flush() and render-transient deletes have been removed:
        // they were too broad and are now unnecessary. DB-query cache is
        // auto-invalidated on every write via DatabaseCrud::clear_table_cache().

        // Reset request-scoped in-memory caches only (no persistent side-effects).
        self::$scheme_cache = [];
        self::$renderer_cache = [];
        self::$type_category_cache = [];
        $this->clear_conditional_caches();

        return $result !== false;
    }

    /**
     * Validate field configuration with dependencies
     *
     * Validates field configuration including dependencies and
     * permission conditions.
     *
     * @param  array $field_config Field configuration
     * @return array               Validation results
     * @access public
     * @since  1.2.0
     */
    public function validate_field_config( $field_config ) {
        return $this->conditional_renderer->validate_field_config( $field_config );
    }

    /**
     * Get dependent fields
     *
     * Returns all fields that depend on the specified field.
     *
     * @param  string $field_id     Field ID to check
     * @param  array  $all_fields   All field configurations
     * @return array                Dependent field IDs
     * @access public
     * @since  1.2.0
     */
    public function get_dependent_fields( $field_id, $all_fields ) {
        return $this->conditional_renderer->get_dependent_fields( $field_id, $all_fields );
    }

    /**
     * Render field with conditional logic
     *
     * Complete field rendering with conditional logic applied.
     *
     * @param  array  $field_config Field configuration
     * @param  array  $context      Context data
     * @param  string $field_html   Raw field HTML
     * @return string               Rendered field HTML
     * @access public
     * @since  1.2.0
     */
    public function render_field_with_conditions( $field_config, $context, $field_html ) {
        return $this->conditional_renderer->render_field( $field_config, $context, $field_html );
    }

    /**
     * Get field attributes for conditional rendering
     *
     * Returns HTML attributes for a field based on its state.
     *
     * @param  array $field_config Field configuration
     * @param  array $context      Context data
     * @return string              HTML attributes
     * @access public
     * @since  1.2.0
     */
    public function get_field_attributes( $field_config, $context ) {
        return $this->conditional_renderer->get_field_attributes( $field_config, $context );
    }

    /**
     * Evaluate condition directly
     *
     * Evaluates a condition using the ConditionalRenderer.
     *
     * @param  mixed $condition Condition to evaluate
     * @param  array $context   Context data
     * @return bool             Evaluation result
     * @access public
     * @since  1.2.0
     */
    public function evaluate_condition( $condition, $context ) {
        return $this->conditional_renderer->evaluate( $condition, $context );
    }

    /**
     * Add JavaScript for dynamic conditional updates
     *
     * Enqueues JavaScript for dynamic field updates based on dependencies.
     *
     * @return void
     * @access public
     * @since  1.2.0
     */
    public function enqueue_conditional_assets() {
        if ( ! self::$config['conditional_rendering']['dependent_field_updates'] ) {
            return;
        }

        wp_enqueue_script(
            'ultraguard-conditional-rendering',
            plugins_url( 'assets/js/conditional-rendering.js', ULTRA_GUARD_PRO_FILE ),
            [ 'jquery' ],
            '1.2.0',
            true
        );

        wp_localize_script(
            'ultraguard-conditional-rendering',
            'ultraguardConditionalConfig',
            [
                'ajaxurl' => self_admin_url( 'admin-ajax.php' ),
                'nonce' => wp_create_nonce( 'ultraguard_admin_nonce' ),
                'debug' => self::$config['debug'],
                'validation_strictness' => self::$config['conditional_rendering']['validation_strictness']
            ]
        );
    }
}

/**
 * Render Exception Class
 *
 * Custom exception class for render engine errors. Provides specialized
 * exception handling for rendering failures with context preservation.
 *
 * @package    UltraguardPro\view
 * @since      1.0.0
 * @extends    \Exception
 */
class RenderException extends \Exception {}
