/**
 * UltraGuard Pro - Managers Module (Enhanced)
 * Version: 2.2.0 - Integrated with UltraGuardModals
 * 
 * Features:
 * - Enhanced with 50+ action types for comprehensive DOM manipulation
 * - Added support for sending container/item IDs with AJAX requests
 * - Integrated with UltraGuardModals for consistent modal handling
 * - Fully backward compatible with version 2.1.0, 2.0.0, and 1.2.0
 * 
 * Modal Integration:
 * - All modal operations now use window.UltraGuardModals API
 * - Supports: open, close, toggle, setContent, showLoading
 * - Automatic fallback to basic DOM manipulation if UltraGuardModals not available
 * - Modal actions pass data and trigger context for better integration
 */

(function($) {
    'use strict';

    // Check if jQuery is available and $ is properly set
    if (typeof $ === 'undefined') {
        console.error('UltraGuard Managers: jQuery not found or $ is not available');
        return;
    }

    window.UltraGuardManagers = window.UltraGuardManagers || {};

    // ==================== AJAX Manager with Container ID Support ====================
    window.UltraGuardManagers.UltraGuardAjaxManager = class UltraGuardAjaxManager {
        constructor(ajaxParams) {
            this.ajaxParams = ajaxParams;
            this.requests = new Map();
            this.cache = new Map();
            
            // Track request IDs for response correlation
            this.requestCounter = 0;
        }

        /**
         * Extract ID from element based on common patterns
         */
        extractIdFromElement($element) {
            if (!$element || !$element.length) return null;
            
            // Check common data attributes
            const id = $element.data('id') ||
                      $element.data('file-id') ||
                      $element.data('folder-id') ||
                      $element.data('item-id') ||
                      $element.data('widget-id') ||
                      $element.data('container-id') ||
                      $element.data('button-id') ||
                      $element.data('list-id') ||
                      $element.attr('data-id') ||
                      $element.attr('data-file-id') ||
                      $element.attr('data-folder-id') ||
                      $element.attr('data-item-id') ||
                      $element.attr('data-widget-id') ||
                      $element.attr('data-container-id') ||
                      $element.attr('data-button-id') ||
                      $element.attr('data-list-id') ||
                      $element.attr('id');
            
            return id || null;
        }

        /**
         * Extract multiple IDs from a collection
         */
        extractIdsFromCollection($elements) {
            if (!$elements || !$elements.length) return [];
            
            const ids = [];
            $elements.each((index, element) => {
                const id = this.extractIdFromElement($(element));
                if (id) ids.push(id);
            });
            
            return ids;
        }

        /**
         * Enhanced request method with ID extraction
         */
        request(method, url, data = {}, options = {}) {
            // Generate unique request ID for tracking
            const requestId = `req_${++this.requestCounter}_${Date.now()}`;
            
            // Extract and add IDs from source element
            if (options.sourceElement) {
                const $source = $(options.sourceElement);
                const elementId = this.extractIdFromElement($source);
                
                if (elementId) {
                    // Add the ID to the request data
                    data.element_id = elementId;
                    data.source_id = elementId;
                    
                    // Also add specific ID type based on context
                    if (options.idType) {
                        data[`${options.idType}_id`] = elementId;
                    }
                    
                    // Add selector info if available
                    if ($source.attr('id')) {
                        data.element_selector = `#${$source.attr('id')}`;
                    } else if ($source.data('id')) {
                        data.element_selector = `[data-id="${$source.data('id')}"]`;
                    }
                }
                
                // Add element type
                if (options.elementType) {
                    data.element_type = options.elementType;
                } else {
                    // Try to detect element type from classes
                    const classList = $source.attr('class') || '';
                    if (classList.includes('file')) data.element_type = 'file';
                    else if (classList.includes('folder')) data.element_type = 'folder';
                    else if (classList.includes('button')) data.element_type = 'button';
                    else if (classList.includes('item')) data.element_type = 'item';
                    else if (classList.includes('list')) data.element_type = 'list';
                    else if (classList.includes('container')) data.element_type = 'container';
                    else if (classList.includes('widget')) data.element_type = 'widget';
                }
            }
            
            // Handle multiple elements (for batch operations)
            if (options.sourceElements && options.sourceElements.length) {
                const ids = this.extractIdsFromCollection($(options.sourceElements));
                if (ids.length) {
                    data.element_ids = ids.join(',');
                    data.batch_operation = true;
                    data.element_count = ids.length;
                }
            }
            
            // Add specific ID type if provided directly
            if (options.id) {
                data.element_id = options.id;
                if (options.idType) {
                    data[`${options.idType}_id`] = options.id;
                }
            }
            
            // Add request tracking
            data.request_id = requestId;

            // Only inject the global nonce when the caller has not already set one.
            // Forms set data.nonce explicitly from their rendered nonce field;
            // overwriting it here would replace a module-specific token with the
            // page-wide 'ultraguard_admin_nonce' token, breaking PHP verification.
            if (!data.nonce || data.nonce === '') {
                if (this.ajaxParams.nonce) {
                    data.nonce = this.ajaxParams.nonce;
                } else {
                    console.warn('UltraGuard AJAX: No nonce for action "' + (data.action||'?') + '". Request may be rejected.');
                }
            }

            if (!data.action) {
                console.error('AJAX request missing action parameter');
                return Promise.reject(new Error('Missing action parameter'));
            }

            const cacheKey = `${method}:${url}:${JSON.stringify(data)}`;
            
            if (method === 'GET' && this.cache.has(cacheKey)) {
                const cachedResponse = this.cache.get(cacheKey);
                // Add request ID to cached response for consistency
                if (cachedResponse && typeof cachedResponse === 'object') {
                    cachedResponse._requestId = requestId;
                    cachedResponse._sourceId = data.element_id;
                }
                return Promise.resolve(cachedResponse);
            }
            
            return new Promise((resolve, reject) => {
                $.ajax({
                    url: url || this.ajaxParams.ajaxurl,
                    type: method,
                    data: data,
                    dataType: 'json',
                    beforeSend: (xhr) => {
                        $(document).trigger('ultraguard:ajax:beforeSend', [url, method, xhr, data]);
                    },
                    success: (response) => {
                        // Enhance response with request metadata
                        if (response && typeof response === 'object') {
                            response._requestId = requestId;
                            response._sourceId = data.element_id;
                            response._sourceType = data.element_type;
                            
                            // If response has actions, enhance them with the source ID
                            if (response.actions && Array.isArray(response.actions)) {
                                response.actions = this.enhanceActionsWithSourceInfo(response.actions, data);
                            }
                        }
                        
                        if (response && response.success !== false) {
//                            if (method === 'GET') {
//                                this.cache.set(cacheKey, response);
//                            }
                            
                            $(document).trigger('ultraguard:ajax:success', [response, data]);
                            resolve(response);
                        } else {
                            const error = this.handleError(response);
                            error._requestId = requestId;
                            error._sourceId = data.element_id;
                            $(document).trigger('ultraguard:ajax:error', [error, data]);
                            reject(error);
                        }
                    },
                    error: (xhr, status, error) => {
                        const ajaxError = this.handleAjaxError(xhr, status, error);
                        ajaxError._requestId = requestId;
                        ajaxError._sourceId = data.element_id;
                        $(document).trigger('ultraguard:ajax:error', [ajaxError, data]);
                        reject(ajaxError);
                    },
                    complete: () => {
                        $(document).trigger('ultraguard:ajax:complete', [url, method, data]);
                    }
                });
            });
        }

        /**
         * Enhance actions with source information for better DOM manipulation
         */
        enhanceActionsWithSourceInfo(actions, requestData) {
            if (!actions || !requestData.element_id) return actions;
            
            return actions.map(action => {
                if (!action) return action;
                
                const enhancedAction = {...action};
                
                // Add source ID to action data if it doesn't have a selector
                if (!enhancedAction.selector && requestData.element_id) {
                    // Try to create a meaningful selector based on element type
                    if (requestData.element_type) {
                        enhancedAction.selector = `[data-${requestData.element_type}-id="${requestData.element_id}"]`;
                    } else {
                        enhancedAction.selector = `[data-id="${requestData.element_id}"], #${requestData.element_id}`;
                    }
                }
                
                // Add source metadata
                enhancedAction._source = {
                    id: requestData.element_id,
                    type: requestData.element_type,
                    selector: requestData.element_selector
                };
                
                return enhancedAction;
            });
        }

        /**
         * Enhanced GET method with ID support
         */
        get(url, data = {}, options = {}) {
            return this.request('GET', url, data, options);
        }

        /**
         * Enhanced POST method with ID support
         */
        post(url, data = {}, options = {}) {
            return this.request('POST', url, data, options);
        }

        /**
         * Enhanced PUT method with ID support
         */
        put(url, data = {}, options = {}) {
            return this.request('PUT', url, data, options);
        }

        /**
         * Enhanced DELETE method with ID support
         */
        delete(url, data = {}, options = {}) {
            return this.request('DELETE', url, data, options);
        }

        /**
         * Helper method for file operations
         */
        fileOperation(action, fileId, options = {}) {
            return this.post(this.ajaxParams.ajaxurl, {
                action: action,
                file_id: fileId
            }, {
                sourceElement: options.sourceElement,
                idType: 'file',
                elementType: 'file',
                ...options
            });
        }

        /**
         * Helper method for folder operations
         */
        folderOperation(action, folderId, options = {}) {
            return this.post(this.ajaxParams.ajaxurl, {
                action: action,
                folder_id: folderId
            }, {
                sourceElement: options.sourceElement,
                idType: 'folder',
                elementType: 'folder',
                ...options
            });
        }

        /**
         * Helper method for widget operations
         */
        widgetOperation(action, widgetId, options = {}) {
            return this.post(this.ajaxParams.ajaxurl, {
                action: action,
                widget_id: widgetId
            }, {
                sourceElement: options.sourceElement,
                idType: 'widget',
                elementType: 'widget',
                ...options
            });
        }

        /**
         * Helper method for batch operations on multiple items
         */
        batchOperation(action, items, options = {}) {
            const itemIds = items.map(item => item.id || item).join(',');
            const itemType = options.itemType || 'item';
            
            return this.post(this.ajaxParams.ajaxurl, {
                action: action,
                [`${itemType}_ids`]: itemIds,
                batch_operation: true,
                item_count: items.length
            }, {
                sourceElements: options.sourceElements,
                elementType: itemType,
                ...options
            });
        }

        handleError(response) {
            if (!response) {
                return {
                    message: 'No response from server',
                    code: 'no_response'
                };
            }

            if (response.data && response.data.code === 'nonce_failure') {
                return {
                    message: 'Security verification failed. Please refresh the page and try again.',
                    code: 'security_failed',
                    data: response.data
                };
            }

            return {
                message: response.data?.message || response.message || 'Request failed',
                code: response.data?.code || 'unknown_error',
                data: response.data || response
            };
        }

        handleAjaxError(xhr, status, error) {
            let message = 'Request failed';
            let code = 'ajax_error';

            if (xhr.responseJSON) {
                if (xhr.responseJSON.data) {
                    message = xhr.responseJSON.data.message || message;
                    code = xhr.responseJSON.data.code || code;
                } else if (xhr.responseJSON.message) {
                    message = xhr.responseJSON.message;
                }
            } else if (xhr.status === 0) {
                message = 'Network error or request blocked';
                code = 'network_error';
            } else if (xhr.status === 403) {
                message = 'Access denied';
                code = 'access_denied';
            } else if (xhr.status === 404) {
                message = 'Requested resource not found';
                code = 'not_found';
            } else if (xhr.status === 500) {
                message = 'Internal server error';
                code = 'server_error';
            }

            return {
                message: message,
                code: code,
                xhr: xhr,
                status: status,
                error: error
            };
        }

        clearCache() {
            this.cache.clear();
            this.requestCounter = 0;
        }
    };

    // ==================== Real-time Manager ====================
    window.UltraGuardManagers.UltraGuardRealtimeManager = class UltraGuardRealtimeManager {
        constructor() {
            this.connections = new Map();
            this.isConnected = false;
        }

        connect(channel) {
            if (this.connections.has(channel)) {
                return this.connections.get(channel);
            }

            
            const connection = {
                channel: channel,
                listeners: new Map(),
                disconnect: () => {
                    this.disconnect(channel);
                }
            };
            
            this.connections.set(channel, connection);
            this.isConnected = true;
            
            return connection;
        }

        disconnect(channel) {
            const connection = this.connections.get(channel);
            if (connection) {
                this.connections.delete(channel);
                
                if (this.connections.size === 0) {
                    this.isConnected = false;
                }
            }
        }

        on(event, callback) {
            $(document).on(`ultraguard:realtime:${event}`, callback);
        }

        emit(event, data) {
            $(document).trigger(`ultraguard:realtime:${event}`, [data]);
        }
    };

    // ==================== Validation Engine ====================
    window.UltraGuardManagers.UltraGuardValidationEngine = class UltraGuardValidationEngine {
        constructor() {
            this.rules = new Map();
            this.messages = new Map();
        }

        addRule(field, rule, message) {
            if (!this.rules.has(field)) {
                this.rules.set(field, []);
            }
            
            this.rules.get(field).push(rule);
            
            if (message) {
                const ruleName = typeof rule === 'string' ? rule : rule.name;
                this.messages.set(`${field}.${ruleName}`, message);
            }
        }

        validateField($field, rules) {
            const fieldName = $field.attr('name');
            const value = $field.val();
            const fieldRules = rules || this.rules.get(fieldName) || [];
            
            for (const rule of fieldRules) {
                const isValid = this.validateRule(rule, value, $field);
                if (!isValid) {
                    const ruleName = typeof rule === 'string' ? rule : rule.name;
                    const message = this.messages.get(`${fieldName}.${ruleName}`) || 'Validation failed';
                    return { isValid: false, message: message };
                }
            }
            
            return { isValid: true };
        }

        validateRule(rule, value, $field) {
            if (typeof rule === 'function') {
                return rule(value, $field);
            }
            
            if (typeof rule === 'string') {
                return this.builtInRule(rule, value, $field);
            }
            
            return true;
        }

        builtInRule(rule, value, $field) {
            switch (rule) {
                case 'required':
                    return value && value.trim().length > 0;
                    
                case 'email':
                    return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value);
                    
                case 'url':
                    return /^https?:\/\/.+/.test(value);
                    
                case 'numeric':
                    return !isNaN(value) && value.trim().length > 0;
                    
                default:
                    return true;
            }
        }

        showFieldError($field, message) {
            $field.addClass('ultraguard-field-error');
            
            let $error = $field.siblings('.ultraguard-field-error-message');
            
            if (!$error.length) {
                $error = $('<span class="ultraguard-field-error-message"></span>');
                $field.after($error);
            }
            
            $error.text(message);
        }

        clearFieldError($field) {
            $field.removeClass('ultraguard-field-error');
            $field.siblings('.ultraguard-field-error-message').remove();
        }
    };

    // ==================== Enhanced Dynamic Response Handler ====================
    window.UltraGuardManagers.UltraGuardResponseHandler = class UltraGuardResponseHandler {
        constructor(ultraGuard) {
            this.ultraGuard = ultraGuard;
            this.actionHandlers = new Map();
            this.registerDefaultHandlers();
        }

        registerDefaultHandlers() {
            // Original handlers - preserved for backward compatibility
            this.register('notification', this.handleNotification.bind(this));
            this.register('reload', this.handleReload.bind(this));
            this.register('redirect', this.handleRedirect.bind(this));
            this.register('update', this.handleUpdate.bind(this));
            this.register('remove', this.handleRemove.bind(this));
            this.register('append', this.handleAppend.bind(this));
            this.register('prepend', this.handlePrepend.bind(this));
            this.register('replace', this.handleReplace.bind(this));
            this.register('addClass', this.handleAddClass.bind(this));
            this.register('removeClass', this.handleRemoveClass.bind(this));
            this.register('toggleClass', this.handleToggleClass.bind(this));
            this.register('updateAttribute', this.handleUpdateAttribute.bind(this));
            this.register('trigger', this.handleTrigger.bind(this));
            this.register('modal', this.handleModal.bind(this));
            this.register('widget', this.handleWidget.bind(this));
            this.register('form', this.handleForm.bind(this));
            this.register('datatable', this.handleDataTable.bind(this));
            this.register('script', this.handleScript.bind(this));
            this.register('style', this.handleStyle.bind(this));
            this.register('animate', this.handleAnimate.bind(this));
            this.register('scroll', this.handleScroll.bind(this));
            this.register('focus', this.handleFocus.bind(this));
            this.register('download', this.handleDownload.bind(this));
            this.register('showMessage', this.handleShowMessage.bind(this));
            
            // NEW ENHANCED HANDLERS
            this.register('empty', this.handleEmpty.bind(this));
            this.register('clone', this.handleClone.bind(this));
            this.register('insertBefore', this.handleInsertBefore.bind(this));
            this.register('insertAfter', this.handleInsertAfter.bind(this));
            this.register('removeAttribute', this.handleRemoveAttribute.bind(this));
            this.register('updateData', this.handleUpdateData.bind(this));
            this.register('show', this.handleShow.bind(this));
            this.register('hide', this.handleHide.bind(this));
            this.register('toggle', this.handleToggle.bind(this));
            this.register('fadeIn', this.handleFadeIn.bind(this));
            this.register('fadeOut', this.handleFadeOut.bind(this));
            this.register('fadeToggle', this.handleFadeToggle.bind(this));
            this.register('slideUp', this.handleSlideUp.bind(this));
            this.register('slideDown', this.handleSlideDown.bind(this));
            this.register('slideToggle', this.handleSlideToggle.bind(this));
            this.register('css', this.handleCss.bind(this));
            this.register('on', this.handleOn.bind(this));
            this.register('off', this.handleOff.bind(this));
            this.register('batch', this.handleBatch.bind(this));
            this.register('conditional', this.handleConditional.bind(this));
            this.register('delay', this.handleDelay.bind(this));
        }

        register(action, handler) {
            this.actionHandlers.set(action, handler);
        }

        handle(response, context = {}) {
            // Check if there's a notification action
            const hasNotificationAction = response.actions && 
                Array.isArray(response.actions) && 
                response.actions.some(action => action.type === 'notification');

            // Handle messages first (skip if notification action exists)
            if (response.success === true && !hasNotificationAction) {
                if (response.message) {
                    this.ultraGuard.showMessage(response.message, 'success');
                } 
                if (response.data && response.data.message) {
                    this.ultraGuard.showMessage(response.data.message, 'success');
                }
            } else if (response.success === false) {
                const errorData = this.parseErrorResponse(response);
                this.ultraGuard.showMessage(errorData.message, 'error');
            }

            // ── saved_values: refresh form fields with what the server actually stored ──
            // PHP handlers return { data: { saved_values: { fieldName: value, ... } } }
            // after a successful settings save. We update every matching field so the UI
            // reflects the persisted state without a full page reload.
            const savedValues = (response.data && response.data.saved_values)
                ? response.data.saved_values
                : null;

            if (savedValues && context.sourceElement) {
                this.applyFormFieldValues(context.sourceElement, savedValues);
            }

            // Process refresh if needed
            if (response.refresh === true) {
                const delay = response.refreshDelay || 1000;
                setTimeout(() => {
                    window.location.reload();
                }, delay);
            }

            // Process actions
            if (response.actions && Array.isArray(response.actions)) {
                this.processActions(response.actions, context);
            }
            if (response.action && typeof response.action === 'object') {
                this.processAction(response.action, context);
            }

            const domSignature = this.extractDomSignature(response);
            if (domSignature) {
                this.dispatchDomSignature(domSignature, response, context);
            }

            // Handle source ID specific event
            if (response._sourceId) {
                $(document).trigger('ultraguard:response:for_element', [response._sourceId, response]);
            }

            $(document).trigger('ultraguard:response:handled', [response, context]);
        }

        /**
         * Apply a map of { fieldName: savedValue } to every matching field in $scope.
         *
         * Handles:
         *   - Checkboxes / toggle inputs  → .prop('checked') + .active CSS class
         *   - Number / text / textarea / select inputs → .val()
         *
         * @param {jQuery} $scope      The form element (or any ancestor) to search within.
         * @param {Object} savedValues Plain object: { fieldName: value }
         */
        applyFormFieldValues($scope, savedValues) {
            if (!$scope || !$scope.length || !savedValues) return;

            // Allow a raw DOM element or jQuery object.
            const $form = $scope instanceof jQuery ? $scope : $($scope);

            Object.entries(savedValues).forEach(([name, value]) => {
                const $field = $form.find(`[name="${CSS.escape(name)}"]`);
                if (!$field.length) return;

                const type = ($field.attr('type') || '').toLowerCase();
                const tag  = ($field.prop('tagName') || '').toLowerCase();

                if (type === 'checkbox') {
                    // The server stores '1'/'0', true/false, or 1/0.
                    const isChecked = value === true || value === 1 || value === '1';
                    $field.prop('checked', isChecked);

                    // Keep the visual .active class on the label wrapper in sync.
                    const $container = $field.closest('.ultraguard-toggle');
                    if ($container.length) {
                        $container.toggleClass('active', isChecked);
                    }

                    $field.trigger('ultraguard:field:updated', [name, isChecked]);

                } else if (type === 'radio') {
                    $form.find(`[name="${CSS.escape(name)}"]`).each((i, el) => {
                        $(el).prop('checked', String($(el).val()) === String(value));
                    });

                } else if (tag === 'select' && $field.prop('multiple')) {
                    // value should be an array from the server
                    $field.val(Array.isArray(value) ? value : [value]);

                } else {
                    // text, number, textarea, select (single)
                    $field.val(value !== null && value !== undefined ? value : '');
                    $field.trigger('ultraguard:field:updated', [name, value]);
                }
            });

            // Fire a single event so other components (e.g. live counters) can react.
            $form.trigger('ultraguard:form:fields:updated', [savedValues]);
        }

        extractDomSignature(response) {
            if (!response || !response.data || !response.data.ui_signature) {
                return null;
            }

            const signature = response.data.ui_signature;
            if (!signature || typeof signature !== 'object') {
                return null;
            }

            return signature;
        }

        dispatchDomSignature(signature, response, context = {}) {
            const status = this.normalizeSignatureToken(signature.status || (response.success ? 'success' : 'error'));
            const moduleName = this.normalizeSignatureToken(signature.module || '');
            const actionName = this.normalizeSignatureToken(signature.action || '');
            const payload = {
                signature,
                response,
                context
            };

            $(document).trigger('ultraguard:dom:signature', [payload]);
            $(document).trigger(`ultraguard:response:${status}`, [payload]);

            if (moduleName) {
                $(document).trigger(`ultraguard:module:${moduleName}:response`, [payload]);
                $(document).trigger(`ultraguard:module:${moduleName}:${status}`, [payload]);
            }

            if (actionName) {
                $(document).trigger(`ultraguard:action:${actionName}:response`, [payload]);
                $(document).trigger(`ultraguard:action:${actionName}:${status}`, [payload]);
            }
        }

        normalizeSignatureToken(value) {
            return String(value || '')
                .trim()
                .toLowerCase()
                .replace(/[^a-z0-9:_-]+/g, '-')
                .replace(/-+/g, '-')
                .replace(/^-|-$/g, '');
        }
        
        processActions(actions, context) {
            actions.forEach((action, index) => {
                const delay = action.delay || 0;
                
                if (delay > 0) {
                    setTimeout(() => {
                        this.processAction(action, context);
                    }, delay);
                } else {
                    this.processAction(action, context);
                }
            });
        }

        processAction(action, context) {
            if (!action || !action.type) {
                console.warn('Invalid action object:', action);
                return;
            }

            const handler = this.actionHandlers.get(action.type);
            
            if (handler) {
                try {
                    handler(action, context);
                } catch (error) {
                    console.error(`Error executing action ${action.type}:`, error);
                }
            } else {
                console.warn(`No handler registered for action: ${action.type}`);
                $(document).trigger('ultraguard:action:unhandled', [action, context]);
            }
        }

        // ==================== Original Action Handlers (Preserved) ====================
        
        handleNotification(action, context) {
            const message = action.message || '';
            const status = action.status || 'info';
            const duration = action.duration !== undefined ? action.duration : 5000;
            
            this.ultraGuard.showMessage(message, status, duration);
        }

        handleShowMessage(action, context) {
            const message = action.message || '';
            const type = action.type || 'info';
            const duration = action.duration !== undefined ? action.duration : 5000;
            
            this.ultraGuard.showMessage(message, type, duration);
        }

        handleReload(action, context) {
            const delay = action.delay || 0;
            
            if (delay > 0) {
                setTimeout(() => {
                    window.location.reload();
                }, delay);
            } else {
                window.location.reload();
            }
        }

        handleRedirect(action, context) {
            if (!action.url) {
                console.warn('Redirect action missing URL');
                return;
            }
            
            const delay = action.delay || 0;
            
            if (delay > 0) {
                setTimeout(() => {
                    window.location.href = action.url;
                }, delay);
            } else {
                window.location.href = action.url;
            }
        }

        handleUpdate(action, context) {
            if (!action.selector) {
                console.warn('Update action missing selector');
                return;
            }
            
            const $element = $(action.selector);
            if ($element.length) {
                const content = action.content || '';
                const method = action.method || 'html';
                
                if (method === 'html') {
                    $element.html(content);
                } else if (method === 'text') {
                    $element.text(content);
                } else if (method === 'val') {
                    $element.val(content);
                }
                
                $(document).trigger('ultraguard:element:updated', [$element, action]);
            }
        }

        handleRemove(action, context) {
            if (!action.selector) {
                console.warn('Remove action missing selector');
                return;
            }
            
            const $element = $(action.selector);
            if ($element.length) {
                const animate = action.animate !== false;
                
                if (animate) {
                    $element.fadeOut(action.duration || 300, function() {
                        $(this).remove();
                    });
                } else {
                    $element.remove();
                }
            }
        }

        handleAppend(action, context) {
            if (!action.selector || !action.content) {
                console.warn('Append action missing selector or content');
                return;
            }
            
            const $element = $(action.selector);
            if ($element.length) {
                const $newContent = $(action.content);
                $element.append($newContent);
                
                if (action.animate !== false) {
                    $newContent.hide().fadeIn(action.duration || 300);
                }
                
                $(document).trigger('ultraguard:element:appended', [$element, $newContent, action]);
            }
        }

        handlePrepend(action, context) {
            if (!action.selector || !action.content) {
                console.warn('Prepend action missing selector or content');
                return;
            }
            
            const $element = $(action.selector);
            if ($element.length) {
                const $newContent = $(action.content);
                $element.prepend($newContent);
                
                if (action.animate !== false) {
                    $newContent.hide().fadeIn(action.duration || 300);
                }
                
                $(document).trigger('ultraguard:element:prepended', [$element, $newContent, action]);
            }
        }

        handleReplace(action, context) {
            if (!action.selector || !action.content) {
                console.warn('Replace action missing selector or content');
                return;
            }
            
            const $element = $(action.selector);
            if ($element.length) {
                const $newContent = $(action.content);
                
                if (action.animate !== false) {
                    $element.fadeOut(action.duration || 300, function() {
                        $(this).replaceWith($newContent);
                        $newContent.hide().fadeIn(action.duration || 300);
                    });
                } else {
                    $element.replaceWith($newContent);
                }
                
                $(document).trigger('ultraguard:element:replaced', [$newContent, action]);
            }
        }

        handleAddClass(action, context) {
            if (!action.selector || !action.className) {
                console.warn('AddClass action missing selector or className');
                return;
            }
            
            const $element = $(action.selector);
            if ($element.length) {
                $element.addClass(action.className);
            }
        }

        handleRemoveClass(action, context) {
            if (!action.selector || !action.className) {
                console.warn('RemoveClass action missing selector or className');
                return;
            }
            
            const $element = $(action.selector);
            if ($element.length) {
                $element.removeClass(action.className);
            }
        }

        handleToggleClass(action, context) {
            if (!action.selector || !action.className) {
                console.warn('ToggleClass action missing selector or className');
                return;
            }
            
            const $element = $(action.selector);
            if ($element.length) {
                $element.toggleClass(action.className);
            }
        }

        handleUpdateAttribute(action, context) {
            if (!action.selector || !action.attribute) {
                console.warn('UpdateAttribute action missing selector or attribute');
                return;
            }
            
            const $element = $(action.selector);
            if ($element.length) {
                if (action.value !== undefined && action.value !== null) {
                    $element.attr(action.attribute, action.value);
                } else {
                    $element.removeAttr(action.attribute);
                }
            }
        }

        handleTrigger(action, context) {
            if (!action.event) {
                console.warn('Trigger action missing event name');
                return;
            }
            
            if (action.selector) {
                const $element = $(action.selector);
                if ($element.length) {
                    $element.trigger(action.event, action.data);
                }
            } else {
                $(document).trigger(action.event, action.data);
            }
        }

        /**
        * Enhanced Modal Handler - Replace the handleModal method in ultraguard-managers.js
        */
       handleModal(action, context) {
           const operation = action.operation || 'open';
           const modalId = action.modalId || 'file-details-modal';

           // Check if UltraGuardModals is available
           if (!window.UltraGuardModals) {
               console.warn('UltraGuardModals not loaded. Falling back to basic modal handling.');

               // Fallback to basic DOM manipulation
               const $modal = $(`#${modalId}`);
               if (!$modal.length) {
                   console.error('Modal not found:', modalId);
                   return;
               }

               switch (operation) {
                   case 'open':
                       // Handle content if provided
                       if (action.content) {
                           $modal.find('.ultraguard-modal-body').html(action.content);
                       } else if (action.options && action.options.content) {
                           $modal.find('.ultraguard-modal-body').html(action.options.content);
                       }
                       $modal.addClass('show').fadeIn();
                       break;

                   case 'close':
                       $modal.removeClass('show').fadeOut();
                       break;

                   case 'toggle':
                       // Handle content if provided for toggle
                       if (action.content) {
                           $modal.find('.ultraguard-modal-body').html(action.content);
                       } else if (action.options && action.options.content) {
                           $modal.find('.ultraguard-modal-body').html(action.options.content);
                       }
                       $modal.toggleClass('show').fadeToggle();
                       break;

                   case 'setContent':
                       const fallbackTarget = action.target || 'body';
                       const fallbackContent = action.content || '';

                       if (fallbackTarget === 'body') {
                           $modal.find('.ultraguard-modal-body').html(fallbackContent);
                       } else if (fallbackTarget === 'title') {
                           $modal.find('.ultraguard-modal-title').html(fallbackContent);
                       } else if (fallbackTarget === 'header') {
                           $modal.find('.ultraguard-modal-header').html(fallbackContent);
                       } else if (fallbackTarget === 'footer') {
                           $modal.find('.ultraguard-modal-footer').html(fallbackContent);
                       } else {
                           $modal.find(fallbackTarget).html(fallbackContent);
                       }
                       break;
               }
               return;
           }

           // Use the UltraGuardModals API for proper modal handling
           try {
               switch (operation) {
                   case 'open':
                       // Check if content is provided and set it BEFORE opening
                       // Content can be in action.content or action.options.content
                       const openContent = action.content || (action.options && action.options.content);

                       if (openContent) {
                           const contentTarget = action.target || 'body';
                           window.UltraGuardModals.setContent(modalId, openContent, contentTarget);
                       }

                       // Pass any data and source element from context
                       const modalData = action.data || action.options || {};
                       const $trigger = context.sourceElement || null;

                       window.UltraGuardModals.open(modalId, modalData, $trigger);
                       break;

                   case 'close':
                       window.UltraGuardModals.close(modalId);
                       break;

                   case 'toggle':
                       const isCurrentlyOpen = window.UltraGuardModals.isOpen(modalId);

                       if (isCurrentlyOpen) {
                           window.UltraGuardModals.close(modalId);
                       } else {
                           // Check if content is provided and set it BEFORE opening
                           const toggleContent = action.content || (action.options && action.options.content);

                           if (toggleContent) {
                               const toggleTarget = action.target || 'body';
                               window.UltraGuardModals.setContent(modalId, toggleContent, toggleTarget);
                           }

                           const toggleData = action.data || action.options || {};
                           const $toggleTrigger = context.sourceElement || null;
                           window.UltraGuardModals.open(modalId, toggleData, $toggleTrigger);
                       }
                       break;

                   case 'setContent':
                       // Set content in specific modal section
                       const target = action.target || 'body';
                       const content = action.content || '';

                       const setResult = window.UltraGuardModals.setContent(modalId, content, target);

                       if (setResult) {
                       } else {
                           console.warn('Failed to set modal content:', modalId);
                       }
                       break;

                   case 'showLoading':
                       // Show loading state in modal
                       const loadingMessage = action.message || 'Loading...';
                       window.UltraGuardModals.showLoading(modalId, loadingMessage);
                       break;

                   default:
                       console.warn(`Unknown modal operation: ${operation}`);
               }
           } catch (error) {
               console.error('Modal operation failed:', error);
               console.error('Action:', action);
               console.error('Context:', context);
           }
       }

        handleWidget(action, context) {
            const operation = action.operation || 'refresh';
            const widgetId = action.widgetId;
            
            if (!widgetId) {
                console.warn('Widget action missing widgetId');
                return;
            }
            
            const $widget = $(`#${widgetId}`);
            
            if (!$widget.length) {
                console.warn(`Widget not found: ${widgetId}`);
                return;
            }
            
            switch (operation) {
                case 'refresh':
                    $(document).trigger('ultraguard:widget:refresh', [widgetId, $widget]);
                    break;
                    
                case 'update':
                    if (action.content) {
                        $widget.html(action.content);
                    }
                    break;
                    
                case 'remove':
                    $widget.fadeOut(action.duration || 300, function() {
                        $(this).remove();
                    });
                    break;
            }
        }

        handleForm(action, context) {
            const operation = action.operation || 'reset';
            const formId = action.formId || (context.sourceElement && context.sourceElement.attr('id'));
            
            if (!formId) {
                console.warn('Form action missing formId');
                return;
            }
            
            const $form = $(`#${formId}`);
            
            if (!$form.length) {
                console.warn(`Form not found: ${formId}`);
                return;
            }
            
            switch (operation) {
                case 'reset':
                    $form[0].reset();
                    $form.find('.ultraguard-field-error').removeClass('ultraguard-field-error');
                    $form.find('.ultraguard-field-error-message').remove();
                    break;
                    
                case 'populate':
                    if (action.data && typeof action.data === 'object') {
                        Object.keys(action.data).forEach(key => {
                            const $field = $form.find(`[name="${key}"]`);
                            if ($field.length) {
                                if ($field.is(':checkbox') || $field.is(':radio')) {
                                    $field.filter(`[value="${action.data[key]}"]`).prop('checked', true);
                                } else {
                                    $field.val(action.data[key]);
                                }
                            }
                        });
                    }
                    break;
                    
                case 'submit':
                    $form.submit();
                    break;
                    
                case 'enable':
                    $form.find(':input').prop('disabled', false);
                    $form.removeClass('disabled');
                    break;
                    
                case 'disable':
                    $form.find(':input').prop('disabled', true);
                    $form.addClass('disabled');
                    break;
                    
                case 'validate':
                    if (typeof $form.valid === 'function') {
                        $form.valid();
                    }
                    break;
            }
        }

        handleDataTable(action, context) {
            if (typeof $.fn.DataTable === 'undefined') {
                console.warn('DataTables not available');
                return;
            }
            
            const operation = action.operation || 'reload';
            const tableId = action.tableId;
            
            if (!tableId) {
                console.warn('DataTable action missing tableId');
                return;
            }
            
            const $table = $(`#${tableId}`);
            
            if (!$table.length) {
                console.warn(`Table not found: ${tableId}`);
                return;
            }
            
            if (!$.fn.DataTable.isDataTable($table)) {
                console.warn(`Table is not initialized as DataTable: ${tableId}`);
                return;
            }
            
            const dataTable = $table.DataTable();
            
            switch (operation) {
                case 'reload':
                case 'refresh':
                    dataTable.ajax.reload(null, action.resetPaging !== false);
                    break;
                    
                case 'draw':
                    dataTable.draw(action.resetPaging !== false);
                    break;
                    
                case 'clear':
                    dataTable.clear().draw();
                    break;
            }
        }

        handleScript(action, context) {
            // Dynamic code execution is intentionally disabled.
            // The render engine no longer emits 'script' action types from
            // server responses. If this handler is called it means a response
            // contains an unexpected action type — log a warning and skip.
            if (!action.code) { return; }
            console.warn('[UltraGuard] handleScript: dynamic code execution is disabled for security. ' +
                         'Use declarative action types instead.');
        }

        handleStyle(action, context) {
            if (!action.css) {
                console.warn('Style action missing css');
                return;
            }
            
            const styleId = action.id || `ultraguard-dynamic-style-${Date.now()}`;
            
            $(`#${styleId}`).remove();
            
            const $style = $(`<style id="${styleId}">${action.css}</style>`);
            $('head').append($style);
        }

        handleAnimate(action, context) {
            if (!action.selector || !action.properties) {
                console.warn('Animate action missing selector or properties');
                return;
            }
            
            const $element = $(action.selector);
            if ($element.length) {
                const duration = action.duration || 400;
                const easing = action.easing || 'swing';
                const complete = action.complete || null;
                
                $element.animate(action.properties, duration, easing, complete);
            }
        }

        handleScroll(action, context) {
            const duration = action.duration || 500;
            
            if (action.selector) {
                const $element = $(action.selector);
                if ($element.length) {
                    const offset = action.offset || 0;
                    const scrollTop = $element.offset().top + offset;
                    
                    $('html, body').animate({
                        scrollTop: scrollTop
                    }, duration);
                }
            } else if (action.position !== undefined) {
                $('html, body').animate({
                    scrollTop: action.position
                }, duration);
            }
        }

        handleFocus(action, context) {
            if (!action.selector) {
                console.warn('Focus action missing selector');
                return;
            }
            
            const $element = $(action.selector);
            if ($element.length) {
                const delay = action.delay || 0;
                
                setTimeout(() => {
                    $element.focus();
                    
                    if (action.select && $element.is('input, textarea')) {
                        $element.select();
                    }
                }, delay);
            }
        }

        handleDownload(action, context) {
            if (!action.url) {
                console.warn('Download action missing url');
                return;
            }
            
            const link = document.createElement('a');
            link.href = action.url;
            link.download = action.filename || '';
            
            link.style.display = 'none';
            document.body.appendChild(link);
            link.click();
            document.body.removeChild(link);
        }

        // ==================== NEW Enhanced Action Handlers ====================
        
        handleEmpty(action, context) {
            if (!action.selector) {
                console.warn('Empty action missing selector');
                return;
            }
            
            const $element = $(action.selector);
            if ($element.length) {
                if (action.animate) {
                    $element.fadeOut(action.duration || 200, function() {
                        $(this).empty().fadeIn(200);
                    });
                } else {
                    $element.empty();
                }
            }
        }

        handleClone(action, context) {
            if (!action.selector || !action.target || !action.targetSelector) {
                console.warn('Clone action missing required parameters');
                return;
            }
            
            const $element = $(action.selector);
            const $target = $(action.targetSelector);
            
            if (!$element.length || !$target.length) {
                return;
            }
            
            const $clone = $element.clone();
            
            switch (action.target) {
                case 'appendTo':
                    $clone.appendTo($target);
                    break;
                case 'prependTo':
                    $clone.prependTo($target);
                    break;
                case 'insertAfter':
                    $clone.insertAfter($target);
                    break;
                case 'insertBefore':
                    $clone.insertBefore($target);
                    break;
            }
        }

        handleInsertBefore(action, context) {
            if (!action.selector || !action.content) {
                console.warn('InsertBefore action missing selector or content');
                return;
            }
            
            const $element = $(action.selector);
            if ($element.length) {
                $element.before(action.content);
            }
        }

        handleInsertAfter(action, context) {
            if (!action.selector || !action.content) {
                console.warn('InsertAfter action missing selector or content');
                return;
            }
            
            const $element = $(action.selector);
            if ($element.length) {
                $element.after(action.content);
            }
        }

        handleRemoveAttribute(action, context) {
            if (!action.selector || !action.attribute) {
                console.warn('RemoveAttribute action missing selector or attribute');
                return;
            }
            
            const $element = $(action.selector);
            if ($element.length) {
                $element.removeAttr(action.attribute);
            }
        }

        handleUpdateData(action, context) {
            if (!action.selector || !action.key) {
                console.warn('UpdateData action missing selector or key');
                return;
            }
            
            const $element = $(action.selector);
            if ($element.length) {
                $element.data(action.key, action.value);
            }
        }

        handleShow(action, context) {
            if (!action.selector) {
                console.warn('Show action missing selector');
                return;
            }
            
            const $element = $(action.selector);
            if ($element.length) {
                $element.show(action.duration || 0);
            }
        }

        handleHide(action, context) {
            if (!action.selector) {
                console.warn('Hide action missing selector');
                return;
            }
            
            const $element = $(action.selector);
            if ($element.length) {
                $element.hide(action.duration || 0);
            }
        }

        handleToggle(action, context) {
            if (!action.selector) {
                console.warn('Toggle action missing selector');
                return;
            }
            
            const $element = $(action.selector);
            if ($element.length) {
                $element.toggle(action.duration || 0);
            }
        }

        handleFadeIn(action, context) {
            if (!action.selector) {
                console.warn('FadeIn action missing selector');
                return;
            }
            
            const $element = $(action.selector);
            if ($element.length) {
                $element.fadeIn(action.duration || 400, action.easing);
            }
        }

        handleFadeOut(action, context) {
            if (!action.selector) {
                console.warn('FadeOut action missing selector');
                return;
            }
            
            const $element = $(action.selector);
            if ($element.length) {
                $element.fadeOut(action.duration || 400, action.easing);
            }
        }

        handleFadeToggle(action, context) {
            if (!action.selector) {
                console.warn('FadeToggle action missing selector');
                return;
            }
            
            const $element = $(action.selector);
            if ($element.length) {
                $element.fadeToggle(action.duration || 400);
            }
        }

        handleSlideUp(action, context) {
            if (!action.selector) {
                console.warn('SlideUp action missing selector');
                return;
            }
            
            const $element = $(action.selector);
            if ($element.length) {
                $element.slideUp(action.duration || 400);
            }
        }

        handleSlideDown(action, context) {
            if (!action.selector) {
                console.warn('SlideDown action missing selector');
                return;
            }
            
            const $element = $(action.selector);
            if ($element.length) {
                $element.slideDown(action.duration || 400);
            }
        }

        handleSlideToggle(action, context) {
            if (!action.selector) {
                console.warn('SlideToggle action missing selector');
                return;
            }
            
            const $element = $(action.selector);
            if ($element.length) {
                $element.slideToggle(action.duration || 400);
            }
        }

        handleCss(action, context) {
            if (!action.selector || !action.properties) {
                console.warn('Css action missing selector or properties');
                return;
            }
            
            const $element = $(action.selector);
            if ($element.length) {
                $element.css(action.properties);
            }
        }

        handleOn(action, context) {
            if (!action.selector || !action.event) {
                console.warn('On action missing selector or event');
                return;
            }
            
            const $element = $(action.selector);
            if (!$element.length) return;
            
            if (typeof action.handler === 'function') {
                $element.on(action.event, action.handler);
            } else if (typeof action.handler === 'string') {
                try {
                    // Safer approach for dynamic function evaluation
                    // First try to get function from window object
                    if (window[action.handler] && typeof window[action.handler] === 'function') {
                        $element.on(action.event, window[action.handler]);
                    } else {
                        // Function constructor fallback removed — dynamic code execution
                        // is disabled. Only named window functions are allowed.
                        console.warn('[UltraGuard] handleEvent: handler "' + action.handler +
                                     '" not found in window scope. Dynamic strings are not executed.');
                    }
                } catch (e) {
                    console.error('Failed to attach event handler:', e);
                }
            }
        }

        handleOff(action, context) {
            if (!action.selector) {
                console.warn('Off action missing selector');
                return;
            }
            
            const $element = $(action.selector);
            if ($element.length) {
                if (action.event) {
                    $element.off(action.event);
                } else {
                    $element.off();
                }
            }
        }

        handleBatch(action, context) {
            if (!Array.isArray(action.actions)) {
                console.warn('Batch action missing actions array');
                return;
            }
            
            const parallel = action.options && action.options.parallel;
            
            if (parallel) {
                action.actions.forEach(a => this.processAction(a, context));
            } else {
                let delay = 0;
                action.actions.forEach(a => {
                    setTimeout(() => this.processAction(a, context), delay);
                    delay += 50;
                });
            }
        }

        /**
         * Safely resolve a dotted property path against an object.
         * e.g. resolvePath({a:{b:1}}, 'a.b') => 1
         * Returns undefined for missing paths; never executes code.
         */
        resolvePath(obj, path) {
            return String(path).split('.').reduce((o, k) => (o && o[k] !== undefined ? o[k] : undefined), obj);
        }

        handleConditional(action, context) {
            if (!action.condition) {
                console.warn('Conditional action missing condition');
                return;
            }

            // Use a safe property-path lookup instead of new Function().
            // action.condition must be a dotted path string like "data.is_active"
            // or a literal boolean-ish value. Code strings are not executed.
            let result;
            if (typeof action.condition === 'boolean') {
                result = action.condition;
            } else if (typeof action.condition === 'string' && /^[\w.]+$/.test(action.condition)) {
                // Only allow identifier.path patterns — no operators, no expressions
                const val = this.resolvePath(context, action.condition);
                result = Boolean(val);
            } else {
                console.warn('[UltraGuard] handleConditional: condition must be a boolean or ' +
                             'a simple dotted property path. Expression strings are not evaluated.');
                return;
            }

            const actions = result ? action.ifTrue : action.ifFalse;
            if (Array.isArray(actions)) {
                this.processActions(actions, context);
            }
        }

        handleDelay(action, context) {
            if (!action.action) {
                console.warn('Delay action missing nested action');
                return;
            }
            
            setTimeout(() => {
                this.processAction(action.action, context);
            }, action.delay || 0);
        }

        // ==================== Error Handling ====================
        
        parseErrorResponse(response) {
            if (!response.success && response.data) {
                return {
                    message: response.data.message || 'An error occurred',
                    code: response.data.code || 'error',
                    data: response.data
                };
            }

            if (response.data && response.data.error) {
                return {
                    message: response.data.error,
                    code: 'error',
                    data: response.data
                };
            }

            if (response.error) {
                return {
                    message: response.error,
                    code: 'error',
                    data: response
                };
            }

            if (response.message && !response.success) {
                return {
                    message: response.message,
                    code: response.code || 'error',
                    data: response.data || response
                };
            }

            if (response.data && response.data.security_check === false) {
                return {
                    message: 'Security verification failed. Please refresh the page and try again.',
                    code: 'security_failed',
                    data: response.data
                };
            }

            return {
                message: response.data?.message || response.message || 'Request failed',
                code: response.data?.code || 'unknown_error',
                data: response.data || response
            };
        }
    };

    // Log successful initialization

})(jQuery);

// Additional fallback for when jQuery is loaded but $ is not available
if (typeof jQuery !== 'undefined' && typeof $ === 'undefined') {
    window.$ = jQuery;
}
