HEX
Server: Apache/2.4.6 (CentOS) OpenSSL/1.0.2k-fips PHP/7.4.30
System: Linux iZj6c1151k3ad370bosnmsZ 3.10.0-1160.76.1.el7.x86_64 #1 SMP Wed Aug 10 16:21:17 UTC 2022 x86_64
User: root (0)
PHP: 7.4.30
Disabled: NONE
Upload Files
File: /var/www/html/www.winghung.com/wp-content/plugins/upkyk-assistant-ai/admin/js/admin-script.js
jQuery(document).ready(function($) {
    // Check if we're on the plugin's admin page
    if (!$('.upkyk-assistant-ai-admin').length) {
        // Not on our admin page, exit early
        return;
    }

    // Initialize settings on page load
    if ($('#upkyk-assistant-ai-preview').length) {
        generatePreview();
    }
    
    // Function to animate the preview - needed for live preview
    function animatePreview() {
        // Add animation class to preview container
        const $container = $('#upkyk-preview-container');
        if ($container.length) {
            // Use fade animation for preview
            $container.addClass('upkyk-animation-fade');
            
            // Reset animation by removing and re-adding class
            setTimeout(function() {
                $container.removeClass('upkyk-animation-fade');
                setTimeout(function() {
                    $container.addClass('upkyk-animation-fade');
                }, 50);
            }, 50);
        }
    }

    // START: Show Post-Save Notice
    // Check if the settings were just saved (using sessionStorage flag)
    if (sessionStorage.getItem('upkykSettingsSaved') === 'true') {
        // Determine which tab was likely saved (optional, could just show generic message)
        const activeTab = localStorage.getItem('upkyk_active_tab') || '#assistant-ai-settings'; // Get last known active tab
        let settingType = 'Settings';
        if (activeTab === '#assistant-ai-settings') settingType = 'Assistant AI Settings';
        if (activeTab === '#appearance') settingType = 'Appearance Settings';
        // Note: API Key tab uses AJAX, so won't trigger this normally

        showNotice('success', `${settingType} saved successfully.`); // Use existing showNotice function
        
        // Clear the flag so it doesn't show again on refresh
        sessionStorage.removeItem('upkykSettingsSaved');
    }
    // END: Show Post-Save Notice

    // Initialize color pickers
    if ($.fn.wpColorPicker) {
        $('.upkyk-color-picker').wpColorPicker({
            change: function(event, ui) {
                // Delay to ensure color is updated
                setTimeout(function() {
                    generatePreview();
                }, 100);
            }
        });
    }
    
    // Tab navigation - ONLY run if NOT on the training page
    if (!$('.upkyk-training-tabs').length) {
        $('.upkyk-tab-link').on('click', function(e) {
            e.preventDefault();
            var targetId = $(this).attr('href').substring(1); // Remove the # from the beginning
            
            // Update active tab
            $('.upkyk-tab-link').removeClass('active');
            $(this).addClass('active');
            
            // Show target content - both methods for backwards compatibility
            $('.upkyk-tab-pane').removeClass('active').hide();
            $('#' + targetId).addClass('active').show();
            
            // Save active tab to localStorage
            localStorage.setItem('upkyk_active_tab', '#' + targetId);
            
            // Load preview if on appearance tab
            if (targetId === 'appearance') {
                if (typeof generatePreview === 'function') {
                    generatePreview();
                }
            }
        });
        
        // Restore active tab from localStorage
        var activeTab = localStorage.getItem('upkyk_active_tab');
        if (activeTab && $(activeTab).length) {
            var targetId = activeTab.substring(1);
            
            // Update active tab classes
            $('.upkyk-tab-link').removeClass('active');
            $('.upkyk-tab-link[href="' + activeTab + '"]').addClass('active');
            
            // Show the active tab
            $('.upkyk-tab-pane').removeClass('active').hide();
            $('#' + targetId).addClass('active').show();
        } else {
            // Default to first tab
            var firstTabHref = $('.upkyk-tab-link').first().attr('href');
            var firstTabId = firstTabHref.substring(1);
            
            // Set active classes
            $('.upkyk-tab-link').first().addClass('active');
            $('.upkyk-tab-pane').removeClass('active').hide();
            $('#' + firstTabId).addClass('active').show();
        }
    }
    // END Conditional Tab Logic
    
    // Media uploader for avatar
    if ($('#upkyk_upload_avatar').length) {
        $('#upkyk_upload_avatar').on('click', function(e) {
            e.preventDefault();
            
            var imageFrame;
            
            if (imageFrame) {
                imageFrame.open();
                return;
            }
            
            imageFrame = wp.media({
                title: 'Select Avatar Image',
                button: {
                    text: 'Use this image'
                },
                multiple: false,
                library: {
                    type: 'image'
                }
            });
            
            imageFrame.on('select', function() {
                var attachment = imageFrame.state().get('selection').first().toJSON();
                $('#upkyk_assistant_ai_avatar').val(attachment.url);
                $('#upkyk_avatar_preview').html('<img src="' + attachment.url + '" alt="Avatar">');
                
                // Update preview
                generatePreview();
            });
            
            imageFrame.open();
        });
        
        // Remove avatar button
        $('#upkyk_remove_avatar').on('click', function(e) {
            e.preventDefault();
            $('#upkyk_assistant_ai_avatar').val('');
            $('#upkyk_avatar_preview').html('<div class="upkyk-no-avatar">No Avatar</div>');
            
            // Update preview
            generatePreview();
        });
    }
    
    // Icon Selector Modal Functionality
    jQuery(document).ready(function($) {
        // Define available icons
        const availableIcons = ['chat-balloon', 'comment', 'comments', 'robot', 'question', 'envelope'];

        // Function to open the icon selector modal
        function openIconSelector(selectedIcon, targetInput) {
            // First, remove any existing modal to avoid duplicates
            $('#upkyk-icon-modal').remove();
            
            // Create a fresh modal each time
            const modalHTML = `
                <div id="upkyk-icon-modal" class="upkyk-modal">
                    <div class="upkyk-modal-content">
                        <div class="upkyk-modal-header">
                            <h3>Selecteer icoon</h3>
                            <span class="upkyk-modal-close">&times;</span>
                        </div>
                        <div class="upkyk-icon-grid"></div>
                    </div>
                </div>
            `;
            $('body').append(modalHTML);
            
            // Store the target input
            $('#upkyk-icon-modal').data('target', targetInput);
            
            // Populate the icon grid
            const $iconGrid = $('.upkyk-icon-grid');
            
            availableIcons.forEach(icon => {
                const isSelected = (icon === selectedIcon) ? 'selected' : '';
                const iconItem = $(`
                    <div class="upkyk-icon-item ${isSelected}" data-value="${icon}">
                        <div class="upkyk-icon-preview ${icon}"></div>
                        <span>${icon.charAt(0).toUpperCase() + icon.slice(1)}</span>
                    </div>
                `);
                $iconGrid.append(iconItem);
                
                // Add direct click handler to each icon item
                iconItem.on('click', function() {
                    // First hide the modal
                    $('#upkyk-icon-modal').hide().remove();
                    
                    // Then update the input and preview
                    $(targetInput).val(icon);
                    
                    const $button = $(targetInput).siblings('.upkyk-icon-select-button');
                    $button.html(`
                        <div class="upkyk-icon-preview ${icon}"></div>
                        ${icon.charAt(0).toUpperCase() + icon.slice(1)}
                    `);
                    
                    // Trigger change event
                    $(targetInput).trigger('change');
                });
            });
            
            // Close button handler
            $('.upkyk-modal-close').on('click', function() {
                $('#upkyk-icon-modal').hide().remove();
            });
            
            // Close when clicking outside
            $('#upkyk-icon-modal').on('click', function(e) {
                if (e.target === this) {
                    $(this).hide().remove();
                }
            });
            
            // Show the modal
            $('#upkyk-icon-modal').show();
        }

        // Add click handler to icon selector buttons
        $(document).on('click', '.upkyk-icon-select-button', function() {
            const targetInput = $(this).siblings('input[type="hidden"]');
            const currentIcon = targetInput.val();
            openIconSelector(currentIcon, targetInput);
        });

        // Initialize icon buttons with their current values
        $('.upkyk-icon-select-button').each(function() {
            const $input = $(this).siblings('input[type="hidden"]');
            const currentIcon = $input.val();
            
            if (currentIcon) {
                $(this).html(`
                    <div class="upkyk-icon-preview ${currentIcon}"></div>
                    ${currentIcon.charAt(0).toUpperCase() + currentIcon.slice(1)}
                `);
            }
        });
    });
    
    // Custom SVG Icon Upload (PRO Feature)
    $('#upkyk_upload_svg').on('click', function(e) {
        e.preventDefault();
        
        // Show upgrade message
        alert('This feature is only available in the PRO version.');
        
        // Redirect to upgrade page (optional)
        if (confirm('Would you like to learn more about the PRO version?')) {
            window.open('https://upkyk.com/assistant-ai', '_blank');
        }
    });
    
    // Remove Custom SVG Icon (PRO Feature)
    $('#upkyk_remove_svg').on('click', function(e) {
        e.preventDefault();
        
        // Show upgrade message
        alert('This feature is only available in the PRO version.');
        
        // Redirect to upgrade page (optional)
        if (confirm('Would you like to learn more about the PRO version?')) {
            window.open('https://upkyk.com/assistant-ai', '_blank');
        }
    });
    
    // Initialize custom icon preview if there's a value
    if ($('#upkyk_assistant_ai_custom_icon').val()) {
        const iconUrl = $('#upkyk_assistant_ai_custom_icon').val();
        const backgroundColor = $('#upkyk_assistant_ai_color').val() || '#0084ff';
        // Preview is already handled in the PHP side
    }
    
    // Update settings data for preview to include custom icon
    function generatePreview() {
        // Check if we have the preview nonce
        if (!upkykAssistantAIAdmin.previewNonce) {
            $('#upkyk-assistant-ai-preview').html('<div class="upkyk-preview-error">Error: Preview nonce is missing.</div>');
            return;
        }
        
        const settings = {
            color: $('#upkyk_assistant_ai_color').val() || '#0084ff',
            user_color: $('#upkyk_assistant_ai_user_color').val() || '#e9ecef',
            font: $('#upkyk_assistant_ai_font').val() || 'Roboto, sans-serif',
            avatar: $('#upkyk_assistant_ai_avatar').val() || '',
            assistant_ai_name: $('#upkyk_assistant_ai_name').val() || 'Chat Support',
            button_shape: $('#upkyk_assistant_ai_button_shape').val() || 'circle',
            button_size: $('#upkyk_assistant_ai_button_size').val() || 'medium',
            font_size: $('#upkyk_assistant_ai_font_size').val() || 'medium',
            message_padding: $('#upkyk_assistant_ai_message_padding').val() || 'normal',
            input_placeholder: $('#upkyk_assistant_ai_input_placeholder').val() || 'Type your message...',
            button_icon: $('#upkyk_assistant_ai_button_icon').val() || 'chat',
            custom_icon: $('#upkyk_assistant_ai_custom_icon').val() || '',
            custom_icon_size: $('#upkyk_assistant_ai_custom_icon_size').val() || 'medium',
            animation_style: $('#upkyk_assistant_ai_animation_style').val() || 'fade',
            window_size: $('#upkyk_assistant_ai_window_size').val() || 'medium',
            window_width: $('#upkyk_assistant_ai_window_width').val() || '380',
            window_height: $('#upkyk_assistant_ai_window_height').val() || '600',
            window_width_mobile: $('#upkyk_assistant_ai_window_width_mobile').val() || '95',
            window_height_mobile: $('#upkyk_assistant_ai_window_height_mobile').val() || '80'
        };
        
        // Show loading state
        $('#upkyk-assistant-ai-preview').html('<div class="upkyk-preview-loading">Loading preview...</div>');
        
        // Helper function to adjust color brightness
        function adjustColor(color, amount) {
            // Default to returning the original color if there's an error
            if (!color) return '#0084ff';
            
            try {
                // Convert hex to RGB
                let hex = color;
                if (hex.startsWith('#')) {
                    hex = hex.slice(1);
                }
                
                // Convert 3-char hex to 6-char
                if (hex.length === 3) {
                    hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2];
                }
                
                // Parse the hex values to rgb
                let r = parseInt(hex.substr(0, 2), 16);
                let g = parseInt(hex.substr(2, 2), 16);
                let b = parseInt(hex.substr(4, 2), 16);
                
                // Adjust the values
                r = Math.max(0, Math.min(255, r + amount));
                g = Math.max(0, Math.min(255, g + amount));
                b = Math.max(0, Math.min(255, b + amount));
                
                // Convert back to hex
                return '#' + 
                    ((1 << 24) + (r << 16) + (g << 8) + b)
                    .toString(16)
                    .slice(1);
            } catch (e) {
                return color; // Return original if there's an error
            }
        }
        
        $.ajax({
            url: upkykAssistantAIAdmin.ajax_url,
            type: 'POST',
            data: {
                action: 'upkyk_generate_preview',
                nonce: upkykAssistantAIAdmin.previewNonce,
                settings: settings
            },
            success: function(response) {
                if (response.success && response.data && response.data.preview) {
                    $('#upkyk-assistant-ai-preview').html(response.data.preview);
                    // Animate the preview after updating
                    animatePreview();
                } else {
                    let errorMessage = 'Failed to load preview.';
                    
                    if (response.data && response.data.message) {
                        errorMessage += ' Error: ' + response.data.message;
                    }
                    
                    $('#upkyk-assistant-ai-preview').html('<div class="upkyk-preview-error">' + errorMessage + '</div>');
                }
            },
            error: function(xhr, status, error) {
                try {
                    // Try to parse the response to get more detailed error
                    const jsonResponse = JSON.parse(xhr.responseText);
                    
                    $('#upkyk-assistant-ai-preview').html('<div class="upkyk-preview-error">Error: ' + (jsonResponse.data?.message || error) + '</div>');
                } catch (e) {
                    $('#upkyk-assistant-ai-preview').html('<div class="upkyk-preview-error">Error: ' + error + '</div>');
                }
            }
        });
    }
    
    // Test API connection
    $('#test_ai_connection').on('click', function() {
        // Set up variables
        let $button = $(this);
        let $status = $('#connection_status');
        let currentApiKey = $('#upkyk_assistant_ai_api_key').val();
        let provider = $('#upkyk_assistant_ai_provider').val();
        
        // Validate API key
        if (!currentApiKey) {
            $status.html('<span style="color: red;">✗ Please enter an API key first</span>');
            return;
        }
        
        $button.prop('disabled', true);
        $status.html('<span style="color: #666;">Testing connection...</span>');
        
        $.ajax({
            url: upkykAssistantAIAdmin.ajax_url,
            type: 'POST',
            data: {
                action: 'upkyk_test_connection',
                nonce: upkykAssistantAIAdmin.nonce,
                api_key: currentApiKey,
                provider: provider
            },
            success: function(response) {
                if (response.success) {
                    $status.html('<span style="color: green;">✓ ' + response.data.message + '</span>');
                } else {
                    $status.html('<span style="color: red;">✗ ' + response.data.message + '</span>');
                }
            },
            error: function() {
                $status.html('<span style="color: red;">✗ Connection test failed</span>');
            },
            complete: function() {
                $button.prop('disabled', false);
            }
        });
    });

    // Toggle model fields based on selected AI provider
    $('#upkyk_assistant_ai_provider').on('change', function() {
        const provider = $(this).val();
        
        // Hide all model rows first
        $('.openai-model-row, tr:has([name="upkyk_assistant_ai_deepseek_model"])').hide();
        
        // Show the appropriate row based on selection
        if (provider === 'openai') {
            $('.openai-model-row').show();
        } else if (provider === 'deepseek') {
            $('tr:has([name="upkyk_assistant_ai_deepseek_model"])').show();
        }
    });

    // Function to show notification
    function showNotification(message, type = 'success') {
        // Create notification element
        const notification = document.createElement('div');
        notification.className = `upkyk-admin-notification ${type} show`;
        notification.innerHTML = `
            <div class="upkyk-notification-message">${message}</div>
            <div class="upkyk-notification-close">&times;</div>
        `;
        document.body.appendChild(notification);
        
        // Add close handler
        notification.querySelector('.upkyk-notification-close').addEventListener('click', function() {
            notification.classList.remove('show');
            setTimeout(() => {
                notification.remove();
            }, 300);
        });
        
        // Auto-remove after 5 seconds
        setTimeout(() => {
            notification.classList.remove('show');
            setTimeout(() => {
                notification.remove();
            }, 300);
        }, 5000);
    }
    
    // Generic function to show notices in admin
    function showNotice(type, message) {
        // Create notice element using WP style
        const noticeClass = type === 'success' ? 'notice-success' : 'notice-error';
        const $notice = $(`<div class="notice ${noticeClass} is-dismissible"><p>${message}</p></div>`);
        
        // Add to the page
        $('#wpbody-content > .wrap > h1, .wrap > .upkyk-admin-header').first().after($notice);
        
        // Auto-dismiss after 5 seconds
        setTimeout(function() {
            $notice.fadeOut(function() {
                $(this).remove();
            });
        }, 5000);
    }
    
    // Watch for form submissions
    $('.upkyk-form').on('submit', function(e) {
        const $form = $(this);
        
        // Show notification after form submission
        setTimeout(() => {
            let message = 'Settings saved successfully!';
            
            // Customize message based on form
            if ($form.hasClass('api-settings-form')) {
                message = 'AI Provider settings saved successfully!';
            } else if ($form.closest('#settings').length) {
                message = 'Assistant AI settings saved successfully!';
            } else if ($form.closest('#appearance').length) {
                message = 'Appearance settings saved successfully!';
            }
            
            showNotification(message);
        }, 500);
    });
    
    // Make sure API settings form has the right class
    $('#api-key .upkyk-form').addClass('api-settings-form');

    // Add this with the other event handlers for the API tab
    $('#delete_api_key').on('click', function() {
        if (confirm('Are you sure you want to delete your API key? This action cannot be undone.')) {
            // Get button reference
            const $button = $(this);
            
            // Show loading state
            $button.attr('disabled', true).text('Deleting...');
            
            // Always clear the field on user confirmation, regardless of server response
            $('#upkyk_assistant_ai_api_key').val('');
            
            // Call AJAX to delete the key from the database
            $.ajax({
                url: upkykAssistantAIAdmin.ajax_url,
                type: 'POST',
                data: {
                    action: 'upkyk_delete_api_key',
                    nonce: upkykAssistantAIAdmin.nonce
                },
                success: function(response) {
                    if (response.success) {
                        showNotice('success', 'API key successfully deleted.');
                    } else {
                        showNotice('error', response.data.message);
                    }
                },
                error: function(xhr, status, error) {
                    showNotice('error', 'An error occurred: ' + error);
                },
                complete: function() {
                    $button.attr('disabled', false).text('Delete API Key');
                }
            });
        }
    });

    // Find all settings forms in tabs
    $('.upkyk-tab-content form').each(function() {
        // Only target forms posting to options.php (exclude potential AJAX forms if any)
        if ($(this).attr('action') === 'options.php') {
            $(this).addClass('upkyk-settings-form');
            
            // Add submit event handler for standard WP settings forms
            $(this).on('submit', function() {
                // Set a flag in sessionStorage before the page reloads
                sessionStorage.setItem('upkykSettingsSaved', 'true');
                // Allow the form to submit normally, which causes the reload
            });
        }
    });

    // Handle API settings form submission
    $('.api-settings-form').on('submit', function() {
        // Store the value of the tab we're on before submitting
        localStorage.setItem('upkyk_active_tab', '#api-key');
        
        // Show the API key saved notification (for Ajax-less approach)
        $('#api_save_notification').slideDown().delay(3000).slideUp();
    });

    // Initialize preview generator
    function initAssistantAIPreview() {
        const $previewSection = $('#assistant-ai-preview');
        
        // Create update preview function
        function updatePreview() {
            const settings = {
                color: $('#upkyk_assistant_ai_color').val(),
                user_color: $('#upkyk_assistant_ai_user_message_color').val(),
                font: $('#upkyk_assistant_ai_font').val(),
                avatar: $('#upkyk_assistant_ai_avatar_url').val(),
                assistant_ai_name: $('#upkyk_assistant_ai_name').val() || 'Chat Support',
                button_shape: $('#upkyk_assistant_ai_button_shape').val(),
                button_size: $('#upkyk_assistant_ai_button_size').val(),
                font_size: $('#upkyk_assistant_ai_font_size').val(),
                message_padding: $('#upkyk_assistant_ai_message_padding').val(),
                input_placeholder: $('#upkyk_assistant_ai_input_placeholder').val() || 'Type your message...',
                button_icon: $('#upkyk_assistant_ai_button_icon').val(),
                custom_icon: $('#upkyk_assistant_ai_custom_icon').val(),
                custom_icon_size: $('#upkyk_assistant_ai_custom_icon_size').val() || 'medium',
                animation_style: $('#upkyk_assistant_ai_animation_style').val() || 'default'
            };
            
            $.ajax({
                url: upkykAssistantAIAdmin.ajax_url,
                type: 'post',
                data: {
                    action: 'upkyk_generate_preview',
                    settings: settings,
                    nonce: upkykAssistantAIAdmin.previewNonce,
                },
                success: function(response) {
                    if (response.success && response.data && response.data.preview) {
                        $previewSection.html(response.data.preview);
                        animatePreview();
                    } else {
                        $previewSection.html('<p class="upkyk-error">Error generating preview</p>');
                    }
                },
                error: function() {
                    $previewSection.html('<p class="upkyk-error">Error generating preview</p>');
                }
            });
        }
        
        // Update preview when settings change
        $('.upkyk-preview-control').on('change input', function() {
            updatePreview();
        });
        
        // Generate initial preview
        updatePreview();
    }
    
    // Listen for changes to custom icon size and update preview
    $('#upkyk_assistant_ai_custom_icon_size').on('change', function() {
        const iconUrl = $('#upkyk_assistant_ai_custom_icon').val();
        if (iconUrl) {
            const backgroundColor = $('#upkyk_assistant_ai_color').val() || '#0084ff';
            const iconSize = $(this).val() || 'medium';
            
            // Calculate dimensions based on size
            let dimensions = 24; // Default for medium
            if (iconSize === 'small') {
                dimensions = 18;
            } else if (iconSize === 'large') {
                dimensions = 32;
            }
            
            $('#upkyk_svg_preview').html(`
                <div class="upkyk-svg-preview-container" style="width: 60px; height: 60px; background-color: ${backgroundColor}; display: flex; align-items: center; justify-content: center; border-radius: 50%;">
                    <img src="${iconUrl}" alt="Custom Icon" style="width: ${dimensions}px; height: ${dimensions}px; filter: brightness(0) invert(1);">
                </div>
            `);
            
            // Update the preview
            generatePreview();
        }
    });
    
    // Handle changes to button shape
    $('#upkyk_assistant_ai_button_shape').on('change', function() {
        generatePreview();
    });
    
    // Handle changes to button size
    $('#upkyk_assistant_ai_button_size').on('change', function() {
        generatePreview();
    });
    
    // Handle changes to animation style
    $('#upkyk_assistant_ai_animation_style').on('change', function() {
        generatePreview();
        
        // Show animation effect in the preview
        setTimeout(function() {
            const animationStyle = $('#upkyk_assistant_ai_animation_style').val();
            const $previewChat = $('.upkyk-preview-chat');
            
            // First reset to trigger animation
            $previewChat.removeClass('animated');
            
            // Force reflow to make sure the animation replays
            void $previewChat[0].offsetWidth;
            
            // Add animation class
            $previewChat.addClass('animated');
        }, 300); // Small delay to ensure preview is updated first
    });
    
    // Handle changes to button icon or style
    $('#upkyk_assistant_ai_button_icon').on('change', function() {
        generatePreview();
    });
    
    // Handle changes to font and other appearance options

    // Handle window size preset selection
    $('#upkyk_assistant_ai_window_size').on('change', function() {
        const selectedSize = $(this).val();
        const $customFields = $('.custom-size-field');
        const $widthInput = $('#upkyk_assistant_ai_window_width');
        const $heightInput = $('#upkyk_assistant_ai_window_height');
        
        // Set width and height values based on preset
        if (selectedSize === 'small') {
            $widthInput.val('320');
            $heightInput.val('450');
            $customFields.hide();
        } else if (selectedSize === 'medium') {
            $widthInput.val('380');
            $heightInput.val('600');
            $customFields.hide();
        } else if (selectedSize === 'large') {
            $widthInput.val('450');
            $heightInput.val('650');
            $customFields.hide();
        } else if (selectedSize === 'extra-large') {
            $widthInput.val('550');
            $heightInput.val('700');
            $customFields.hide();
        } else if (selectedSize === 'custom') {
            $customFields.show();
        }
        
        // Update preview if it exists
        if (typeof generatePreview === 'function') {
            generatePreview();
        }
    });
    
    // Trigger change event to set initial state
    $('#upkyk_assistant_ai_window_size').trigger('change');

    // Handle Icon Selector Modal in settings page
    jQuery(document).ready(function($) {
        // Open icon selector modal
        $('#open_icon_selector').on('click', function() {
            $('#upkyk_icon_selector_modal').show();
            
            // Highlight currently selected icon
            const currentValue = $('#upkyk_assistant_ai_button_icon').val();
            $('.upkyk-icon-item').removeClass('selected');
            $(`.upkyk-icon-item[data-value="${currentValue}"]`).addClass('selected');
        });
        
        // Close icon selector modal
        $('#close_icon_selector').on('click', function() {
            $('#upkyk_icon_selector_modal').hide();
        });
        
        // Close when clicking outside the modal content
        $('#upkyk_icon_selector_modal').on('click', function(e) {
            if (e.target === this) {
                $(this).hide();
            }
        });
        
        // Handle icon selection
        $('.upkyk-icon-item').on('click', function() {
            const iconValue = $(this).data('value');
            const iconName = $(this).find('span').text();
            
            // Update the hidden input value
            $('#upkyk_assistant_ai_button_icon').val(iconValue).trigger('change');
            
            // Get the correct file name based on icon value
            let iconFile = iconValue;
            if (iconValue === 'chat' || iconValue === 'comment') {
                iconFile = 'comment';
            } else if (iconValue === 'question') {
                iconFile = 'question-circle';
            }
            
            // Get the plugin URL
            const pluginUrl = upkykAssistantAIAdmin?.plugin_url || '';
            
            // Update the selected icon preview
            const iconHtml = `<img src="${pluginUrl}assets/images/chat-icons/${iconFile}.svg" alt="${iconValue}" style="width:24px; height:24px; filter:brightness(0) invert(1);">`;
            $('.upkyk-selected-icon-preview .upkyk-icon-preview').attr('class', 'upkyk-icon-preview ' + iconValue).html(iconHtml);
            $('.upkyk-selected-icon-preview span').text(iconName);
            
            // Highlight the selected icon
            $('.upkyk-icon-item').removeClass('selected');
            $(this).addClass('selected');
            
            // Close the modal
            $('#upkyk_icon_selector_modal').hide();
            
            // Update the preview if available
            if (typeof generatePreview === 'function') {
                generatePreview();
            }
        });
    });

    // Update preview when any appearance setting changes
    $('#upkyk_assistant_ai_color, #upkyk_assistant_ai_user_color, #upkyk_assistant_ai_link_bg_color, #upkyk_assistant_ai_link_text_color, #upkyk_assistant_ai_font, #upkyk_assistant_ai_avatar, #upkyk_assistant_ai_position, #upkyk_assistant_ai_button_shape, #upkyk_assistant_ai_button_size, #upkyk_assistant_ai_font_size, #upkyk_assistant_ai_message_padding, #upkyk_assistant_ai_input_placeholder, #upkyk_assistant_ai_button_icon, #upkyk_assistant_ai_custom_icon, #upkyk_assistant_ai_custom_icon_size, #upkyk_assistant_ai_window_size, #upkyk_assistant_ai_window_width, #upkyk_assistant_ai_window_height').on('change', function() {
        generatePreview();
        setTimeout(animatePreview, 300);
    });

    // START: Save Button Feedback
    // Add a handler for the standard WordPress settings forms in our tabs
    $('#assistant-ai-settings form, #appearance form').on('submit', function(e) {
        const $form = $(this);
        const $submitButton = $form.find('input[type="submit"].button-primary'); // Find the primary save button

        if ($submitButton.length) {
            // Add a spinner icon next to the button
            // Ensure the spinner doesn't already exist
            if (!$submitButton.next('.upkyk-spinner').length) {
                $submitButton.after('<span class="upkyk-spinner spinner is-active" style="display: inline-block; float: none; vertical-align: middle; margin-left: 5px;"></span>');
            }
            // The spinner will automatically disappear on page reload after save
        }
        // Allow the form to submit normally
    });
    // END: Save Button Feedback
});