Source: frontend/js/components/settings.js

/**
 * Settings form functionality
 */
import { apiConfig, fetchWithTimeout } from '../utils/api.js';
import { displayError } from '../utils/errorHandler.js';

/**
 * Initialize settings form
 */
export function initSettingsForm() {
    const settingsForm = document.getElementById('settings-form');
    if (!settingsForm) return;

    // Load config from server first, then populate UI
    loadConfigFromServer();
    
    // Listen for settings tab activation to reload config
    window.addEventListener('settingsTabActivated', () => {
        loadConfigFromServer();
    });

    // Handle storage type changes
    const storageType = document.getElementById('storage-type');
    const sparqlConfigGroup = document.getElementById('sparql-config-group');
    
    if (storageType && sparqlConfigGroup) {
        storageType.addEventListener('change', (e) => {
            if (e.target.value === 'sparql') {
                sparqlConfigGroup.style.display = 'block';
            } else {
                sparqlConfigGroup.style.display = 'none';
            }
        });
    }
    
    // Handle SPARQL endpoint selection
    const sparqlEndpoint = document.getElementById('sparql-endpoint');
    const customEndpointGroup = document.getElementById('custom-endpoint-group');
    
    if (sparqlEndpoint && customEndpointGroup) {
        sparqlEndpoint.addEventListener('change', (e) => {
            if (e.target.value === 'custom') {
                customEndpointGroup.style.display = 'block';
            } else {
                customEndpointGroup.style.display = 'none';
            }
        });
    }
    
    // Handle Chat Provider selection
    const chatProvider = document.getElementById('chat-provider');
    const customChatProviderGroup = document.getElementById('custom-chat-provider-group');
    
    if (chatProvider && customChatProviderGroup) {
        chatProvider.addEventListener('change', (e) => {
            if (e.target.value === 'custom') {
                customChatProviderGroup.style.display = 'block';
            } else {
                customChatProviderGroup.style.display = 'none';
            }
        });
    }
    
    // Handle Embedding Provider selection
    const embeddingProvider = document.getElementById('embedding-provider');
    const customEmbeddingProviderGroup = document.getElementById('custom-embedding-provider-group');
    
    if (embeddingProvider && customEmbeddingProviderGroup) {
        embeddingProvider.addEventListener('change', (e) => {
            if (e.target.value === 'custom') {
                customEmbeddingProviderGroup.style.display = 'block';
            } else {
                customEmbeddingProviderGroup.style.display = 'none';
            }
        });
    }

    // Handle form submission
    settingsForm.addEventListener('submit', async (e) => {
        e.preventDefault();
        
        const formData = new FormData(settingsForm);
        
        // Handle custom endpoint
        let sparqlEndpoint = formData.get('sparqlEndpoint');
        let customEndpointData = null;
        
        if (sparqlEndpoint === 'custom') {
            const customUrl = document.getElementById('custom-endpoint-url').value;
            const customUser = document.getElementById('custom-endpoint-user').value;
            const customPassword = document.getElementById('custom-endpoint-password').value;
            
            if (customUrl) {
                sparqlEndpoint = customUrl;
                customEndpointData = {
                    url: customUrl,
                    user: customUser,
                    password: customPassword
                };
            }
        }
        
        // Handle custom chat provider
        let chatProvider = formData.get('chatProvider');
        let customChatProviderData = null;
        
        if (chatProvider === 'custom') {
            const customType = document.getElementById('custom-chat-type').value;
            const customUrl = document.getElementById('custom-chat-url').value;
            const customApiKey = document.getElementById('custom-chat-api-key').value;
            
            if (customType) {
                chatProvider = customType;
                customChatProviderData = {
                    type: customType,
                    baseUrl: customUrl,
                    apiKey: customApiKey
                };
            }
        }
        
        // Handle custom embedding provider
        let embeddingProvider = formData.get('embeddingProvider');
        let customEmbeddingProviderData = null;
        
        if (embeddingProvider === 'custom') {
            const customType = document.getElementById('custom-embedding-type').value;
            const customUrl = document.getElementById('custom-embedding-url').value;
            const customApiKey = document.getElementById('custom-embedding-api-key').value;
            
            if (customType) {
                embeddingProvider = customType;
                customEmbeddingProviderData = {
                    type: customType,
                    baseUrl: customUrl,
                    apiKey: customApiKey
                };
            }
        }
        
        const settings = {
            storageType: formData.get('storageType'),
            sparqlEndpoint: sparqlEndpoint,
            customEndpoint: customEndpointData,
            chatProvider: chatProvider,
            chatModel: formData.get('chatModel'),
            customChatProvider: customChatProviderData,
            embeddingProvider: embeddingProvider,
            embeddingModel: formData.get('embeddingModel'),
            customEmbeddingProvider: customEmbeddingProviderData
        };

        try {
            // Save settings to localStorage
            localStorage.setItem('sememSettings', JSON.stringify(settings));
            
            // Show success message
            const resultDiv = document.createElement('div');
            resultDiv.className = 'success-message';
            resultDiv.textContent = 'Settings saved successfully!';
            
            // Remove any existing messages
            const existingMessages = settingsForm.querySelector('.success-message, .error-message');
            if (existingMessages) {
                existingMessages.remove();
            }
            
            settingsForm.prepend(resultDiv);
            
            // Auto-hide success message after 3 seconds
            setTimeout(() => {
                resultDiv.remove();
            }, 3000);
            
        } catch (error) {
            console.error('Error saving settings:', error);
            displayError('Failed to save settings. Please try again.', settingsForm);
        }
    });
}

/**
 * Load config from server and populate UI
 */
async function loadConfigFromServer() {
    try {
        const response = await fetchWithTimeout(`${apiConfig.baseUrl}/api/config`);
        if (response.ok) {
            const result = await response.json();
            if (result.success) {
                const config = result.data;
                
                // Store server config in localStorage for reference
                localStorage.setItem('sememServerConfig', JSON.stringify(config));
                
                // Populate UI with server config
                populateSettingsFromConfig(config);
                
                // Load any user overrides from localStorage
                loadSettings();
            } else {
                console.warn('Failed to load config from server:', result.error);
                // Fall back to localStorage only
                loadSettings();
            }
        } else {
            console.warn('Config endpoint returned error:', response.status);
            loadSettings();
        }
    } catch (error) {
        console.error('Error loading config from server:', error);
        // Fall back to localStorage only
        loadSettings();
    }
}

/**
 * Populate settings form from server config
 */
function populateSettingsFromConfig(config) {
    // Populate storage type options
    const storageType = document.getElementById('storage-type');
    if (storageType && config.storage) {
        storageType.value = config.storage.current;
        // Trigger change event to show/hide SPARQL config
        storageType.dispatchEvent(new Event('change'));
    }

    // Populate SPARQL endpoints
    const sparqlEndpoint = document.getElementById('sparql-endpoint');
    if (sparqlEndpoint) {
        // Clear existing options except first
        sparqlEndpoint.innerHTML = '<option value="">-- Select SPARQL Endpoint --</option>';
        
        let defaultEndpoint = null;
        let endpointsToProcess = [];
        
        // Handle both config.sparqlEndpoints (from Config.js) and config.sparqlEndpoints (from config.json)
        if (config.sparqlEndpoints && config.sparqlEndpoints.length > 0) {
            // Process endpoints from either format
            config.sparqlEndpoints.forEach((endpoint, index) => {
                let endpointData;
                
                if (endpoint.urlBase) {
                    // Config.js format
                    endpointData = {
                        url: endpoint.urlBase,
                        label: endpoint.label || `Endpoint ${index + 1}`,
                        auth: {
                            user: endpoint.user,
                            password: endpoint.password
                        }
                    };
                } else if (endpoint.queryEndpoint) {
                    // config.json format
                    endpointData = {
                        url: endpoint.queryEndpoint.replace('/semem/query', ''),
                        label: `SPARQL Server ${index + 1}`,
                        auth: endpoint.auth
                    };
                }
                
                if (endpointData) {
                    endpointsToProcess.push(endpointData);
                    
                    const option = document.createElement('option');
                    option.value = endpointData.url;
                    option.textContent = `${endpointData.label} (${endpointData.url})`;
                    
                    // Add auth info to the display if available
                    if (endpointData.auth && endpointData.auth.user) {
                        option.textContent += ` [${endpointData.auth.user}]`;
                    }
                    
                    sparqlEndpoint.appendChild(option);
                    
                    // Use first endpoint as default
                    if (index === 0) {
                        defaultEndpoint = endpointData.url;
                    }
                }
            });
        }
        
        // Always add custom endpoint option at the end
        const customOption = document.createElement('option');
        customOption.value = 'custom';
        customOption.textContent = '+ Add Custom Endpoint';
        sparqlEndpoint.appendChild(customOption);
        
        // Store processed endpoints for reference
        if (endpointsToProcess.length > 0) {
            localStorage.setItem('sememSparqlEndpoints', JSON.stringify(endpointsToProcess));
        }
        
        // Set default SPARQL endpoint
        if (defaultEndpoint) {
            sparqlEndpoint.value = defaultEndpoint;
        }
    }

    // Populate LLM providers and set current selections
    const chatProvider = document.getElementById('chat-provider');
    const embeddingProvider = document.getElementById('embedding-provider');
    
    let currentChatProvider = null;
    let currentEmbeddingProvider = null;
    
    // Determine current providers from config
    if (config.models?.chat?.provider) {
        currentChatProvider = config.models.chat.provider;
    }
    if (config.models?.embedding?.provider) {
        currentEmbeddingProvider = config.models.embedding.provider;
    }
    
    if (config.llmProviders && config.llmProviders.length > 0) {
        // Clear existing options
        if (chatProvider) {
            chatProvider.innerHTML = '<option value="">-- Select Chat Provider --</option>';
        }
        if (embeddingProvider) {
            embeddingProvider.innerHTML = '<option value="">-- Select Embedding Provider --</option>';
        }
        
        // Sort providers by priority (lower number = higher priority)
        const sortedProviders = [...config.llmProviders].sort((a, b) => 
            (a.priority || 999) - (b.priority || 999)
        );
        
        sortedProviders.forEach(provider => {
            if (provider.capabilities?.includes('chat') && chatProvider) {
                const option = document.createElement('option');
                option.value = provider.type;
                option.textContent = `${provider.type}${provider.implementation ? ` (${provider.implementation})` : ''} - ${provider.description || 'No description'}`;
                chatProvider.appendChild(option);
            }
            
            if (provider.capabilities?.includes('embedding') && embeddingProvider) {
                const option = document.createElement('option');
                option.value = provider.type;
                option.textContent = `${provider.type}${provider.implementation ? ` (${provider.implementation})` : ''} - ${provider.description || 'No description'}`;
                embeddingProvider.appendChild(option);
            }
        });
        
        // Add custom provider options
        if (chatProvider) {
            const customChatOption = document.createElement('option');
            customChatOption.value = 'custom';
            customChatOption.textContent = '+ Add Custom Chat Provider';
            chatProvider.appendChild(customChatOption);
        }
        
        if (embeddingProvider) {
            const customEmbeddingOption = document.createElement('option');
            customEmbeddingOption.value = 'custom';
            customEmbeddingOption.textContent = '+ Add Custom Embedding Provider';
            embeddingProvider.appendChild(customEmbeddingOption);
        }
        
        // Set current provider selections
        if (currentChatProvider && chatProvider) {
            chatProvider.value = currentChatProvider;
        } else if (chatProvider && chatProvider.children.length > 1) {
            // Select first available option if no current provider
            chatProvider.selectedIndex = 1;
        }
        
        if (currentEmbeddingProvider && embeddingProvider) {
            embeddingProvider.value = currentEmbeddingProvider;
        } else if (embeddingProvider && embeddingProvider.children.length > 1) {
            // Select first available option if no current provider
            embeddingProvider.selectedIndex = 1;
        }
    } else {
        // No providers configured in llmProviders, but add current active providers
        if (chatProvider) {
            chatProvider.innerHTML = '<option value="">-- Select Chat Provider --</option>';
            
            // Add current chat provider if available
            if (currentChatProvider) {
                const currentOption = document.createElement('option');
                currentOption.value = currentChatProvider;
                currentOption.textContent = `${currentChatProvider} (current)`;
                chatProvider.appendChild(currentOption);
            }
            
            const customChatOption = document.createElement('option');
            customChatOption.value = 'custom';
            customChatOption.textContent = '+ Add Custom Chat Provider';
            chatProvider.appendChild(customChatOption);
        }
        
        if (embeddingProvider) {
            embeddingProvider.innerHTML = '<option value="">-- Select Embedding Provider --</option>';
            
            // Add current embedding provider if available
            if (currentEmbeddingProvider) {
                const currentOption = document.createElement('option');
                currentOption.value = currentEmbeddingProvider;
                currentOption.textContent = `${currentEmbeddingProvider} (current)`;
                embeddingProvider.appendChild(currentOption);
            }
            
            const customEmbeddingOption = document.createElement('option');
            customEmbeddingOption.value = 'custom';
            customEmbeddingOption.textContent = '+ Add Custom Embedding Provider';
            embeddingProvider.appendChild(customEmbeddingOption);
        }
        
        // Set current provider selections
        if (currentChatProvider && chatProvider) {
            chatProvider.value = currentChatProvider;
        }
        
        if (currentEmbeddingProvider && embeddingProvider) {
            embeddingProvider.value = currentEmbeddingProvider;
        }
    }

    // Set model values
    const chatModel = document.getElementById('chat-model');
    const embeddingModel = document.getElementById('embedding-model');
    
    if (chatModel) {
        if (config.models?.chat?.model) {
            chatModel.value = config.models.chat.model;
        } else if (config.defaultChatModel) {
            chatModel.value = config.defaultChatModel;
        } else {
            // Use a reasonable default placeholder
            chatModel.placeholder = 'e.g., qwen2:1.5b, gpt-3.5-turbo';
        }
    }
    
    if (embeddingModel) {
        if (config.models?.embedding?.model) {
            embeddingModel.value = config.models.embedding.model;
        } else if (config.defaultEmbeddingModel) {
            embeddingModel.value = config.defaultEmbeddingModel;
        } else {
            // Use a reasonable default placeholder
            embeddingModel.placeholder = 'e.g., nomic-embed-text, text-embedding-3-small';
        }
    }
    
    // Debug logging
    const sparqlCount = config.sparqlEndpoints ? config.sparqlEndpoints.length : 0;
    const providerCount = config.llmProviders ? config.llmProviders.length : 0;
    window.showDebug && window.showDebug(`Config loaded: Storage=${config.storage?.current || config.storage?.type}, SPARQL endpoints=${sparqlCount}, LLM providers=${providerCount}, Chat=${currentChatProvider}/${config.models?.chat?.model}, Embedding=${currentEmbeddingProvider}/${config.models?.embedding?.model}`);
}

/**
 * Load saved settings from localStorage
 */
function loadSettings() {
    try {
        const savedSettings = localStorage.getItem('sememSettings');
        if (savedSettings) {
            const settings = JSON.parse(savedSettings);
            
            // Set form values from saved settings
            const storageType = document.getElementById('storage-type');
            const sparqlEndpoint = document.getElementById('sparql-endpoint');
            const chatProvider = document.getElementById('chat-provider');
            const chatModel = document.getElementById('chat-model');
            const embeddingProvider = document.getElementById('embedding-provider');
            const embeddingModel = document.getElementById('embedding-model');
            
            if (storageType && settings.storageType) {
                storageType.value = settings.storageType;
                // Trigger change event to show/hide SPARQL config
                storageType.dispatchEvent(new Event('change'));
            }
            if (sparqlEndpoint && settings.sparqlEndpoint) {
                sparqlEndpoint.value = settings.sparqlEndpoint;
            }
            if (chatProvider && settings.chatProvider) {
                chatProvider.value = settings.chatProvider;
            }
            if (chatModel && settings.chatModel) {
                chatModel.value = settings.chatModel;
            }
            if (embeddingProvider && settings.embeddingProvider) {
                embeddingProvider.value = settings.embeddingProvider;
            }
            if (embeddingModel && settings.embeddingModel) {
                embeddingModel.value = settings.embeddingModel;
            }
        }
    } catch (error) {
        console.error('Error loading settings:', error);
    }
}