/**
 * Embedding Settings JavaScript
 * Handles the embedding configuration UI and API calls
 */

// Available providers and models loaded from API
let providerOptions = [];
let availableModels = {};
let currentSettings = null;

/**
 * Safe fetch wrapper with URL validation
 */
async function safeFetch(url, options = {}) {
    // Internal URLs starting with '/' are safe
    if (!url.startsWith('/')) {
        if (!URLValidator.isSafeUrl(url)) {
            throw new Error(`Blocked unsafe URL: ${url}`);
        }
    }
    return fetch(url, options);
}


/**
 * Initialize the page
 */
document.addEventListener('DOMContentLoaded', function() {
    // Load available models first, then settings
    loadAvailableModels().then(() => {
        // After models are loaded, load current settings
        loadCurrentSettings();
    });

    // Setup provider change handler
    document.getElementById('embedding-provider').addEventListener('change', function() {
        updateModelOptions();
        toggleOllamaUrlField();
    });

    // Setup model change handler
    document.getElementById('embedding-model').addEventListener('change', updateModelDescription);

    // Setup Ollama URL change handler
    document.getElementById('ollama-url').addEventListener('input', function() {
        // Mark as changed if needed
    });

    // Setup config form submission
    document.getElementById('rag-config-form').addEventListener('submit', handleConfigSubmit);
});

/**
 * Load available embedding providers and models
 */
async function loadAvailableModels() {
    try {
        const response = await safeFetch('/library/api/rag/models');
        const data = await response.json();

        if (data.success) {
            providerOptions = data.provider_options || [];
            availableModels = data.providers || {};

            // Populate provider dropdown
            populateProviders();

            // Update models for current provider (don't select yet, wait for settings)
            updateModelOptions();

            // Update provider information
            updateProviderInfo();
        } else {
            showError('Failed to load available models: ' + data.error);
        }
    } catch (error) {
        console.error('Error loading models:', error);
        showError('Failed to load available models');
    }
}

/**
 * Load current RAG settings from database
 */
async function loadCurrentSettings() {
    try {
        const response = await safeFetch('/library/api/rag/settings');
        const data = await response.json();

        if (data.success && data.settings) {
            currentSettings = data.settings;
            const settings = data.settings;

            // Set provider
            const providerSelect = document.getElementById('embedding-provider');
            if (settings.embedding_provider) {
                providerSelect.value = settings.embedding_provider;
            }

            // Update models for this provider
            updateModelOptions();

            // Set model
            const modelSelect = document.getElementById('embedding-model');
            if (settings.embedding_model) {
                modelSelect.value = settings.embedding_model;
                updateModelDescription();
            }

            // Set chunk size and overlap
            if (settings.chunk_size) {
                document.getElementById('chunk-size').value = settings.chunk_size;
            }
            if (settings.chunk_overlap) {
                document.getElementById('chunk-overlap').value = settings.chunk_overlap;
            }

            // Set new advanced settings
            if (settings.splitter_type) {
                document.getElementById('splitter-type').value = settings.splitter_type;
            }
            if (settings.distance_metric) {
                document.getElementById('distance-metric').value = settings.distance_metric;
            }
            if (settings.index_type) {
                document.getElementById('index-type').value = settings.index_type;
            }
            if (settings.normalize_vectors !== undefined) {
                document.getElementById('normalize-vectors').checked = settings.normalize_vectors;
            }
            if (settings.text_separators) {
                // Convert array to JSON string for display
                document.getElementById('text-separators').value = JSON.stringify(settings.text_separators);
            }

            // Load Ollama URL from global settings
            loadOllamaUrl();

            // Show/hide Ollama URL field based on provider
            toggleOllamaUrlField();

            // Update the saved defaults display
            renderSavedDefaults(settings);
        }
    } catch (error) {
        console.error('Error loading current settings:', error);
        // Don't show error to user - just use defaults
    }
}

/**
 * Render the saved default settings display
 */
function renderSavedDefaults(settings) {
    const container = document.getElementById('saved-default-settings');
    if (!container) return;

    // Get provider display name
    const providerLabels = {
        'sentence_transformers': 'Sentence Transformers (Local)',
        'ollama': 'Ollama (Local)',
        'openai': 'OpenAI API'
    };
    const providerLabel = providerLabels[settings.embedding_provider] || settings.embedding_provider;

    container.innerHTML = `
        <div class="ldr-info-item">
            <span class="ldr-info-label">Provider:</span>
            <span class="ldr-info-value">${providerLabel}</span>
        </div>
        <div class="ldr-info-item">
            <span class="ldr-info-label">Embedding Model:</span>
            <span class="ldr-info-value">${settings.embedding_model}</span>
        </div>
        <div class="ldr-info-item">
            <span class="ldr-info-label">Chunk Size:</span>
            <span class="ldr-info-value">${settings.chunk_size} characters</span>
        </div>
        <div class="ldr-info-item">
            <span class="ldr-info-label">Chunk Overlap:</span>
            <span class="ldr-info-value">${settings.chunk_overlap} characters</span>
        </div>
        <div class="ldr-info-item">
            <span class="ldr-info-label">Splitter Type:</span>
            <span class="ldr-info-value">${settings.splitter_type || 'recursive'}</span>
        </div>
        <div class="ldr-info-item">
            <span class="ldr-info-label">Distance Metric:</span>
            <span class="ldr-info-value">${settings.distance_metric || 'cosine'}</span>
        </div>
        <div class="ldr-info-item">
            <span class="ldr-info-label">Index Type:</span>
            <span class="ldr-info-value">${settings.index_type || 'flat'}</span>
        </div>
    `;
}

/**
 * Populate provider dropdown
 */
function populateProviders() {
    const providerSelect = document.getElementById('embedding-provider');
    const currentValue = providerSelect.value;

    // Clear existing options
    providerSelect.innerHTML = '';

    // Add provider options
    providerOptions.forEach(provider => {
        const option = document.createElement('option');
        option.value = provider.value;
        option.textContent = provider.label;
        providerSelect.appendChild(option);
    });

    // Restore previous value if it exists
    if (currentValue && Array.from(providerSelect.options).some(opt => opt.value === currentValue)) {
        providerSelect.value = currentValue;
    } else if (providerSelect.options.length > 0) {
        providerSelect.value = providerSelect.options[0].value;
    }
}

/**
 * Update model dropdown based on selected provider
 */
function updateModelOptions() {
    const provider = document.getElementById('embedding-provider').value;
    const modelSelect = document.getElementById('embedding-model');
    const descriptionSpan = document.getElementById('model-description');

    // Clear existing options
    modelSelect.innerHTML = '';

    // Add models for selected provider
    const models = availableModels[provider] || [];
    models.forEach(modelData => {
        const option = document.createElement('option');
        option.value = modelData.value;
        option.textContent = modelData.label;
        modelSelect.appendChild(option);
    });

    // Update description for first model
    updateModelDescription();

    // Add change handler for model selection (remove old handler first)
    modelSelect.removeEventListener('change', updateModelDescription);
    modelSelect.addEventListener('change', updateModelDescription);
}

/**
 * Update model description text
 */
function updateModelDescription() {
    const provider = document.getElementById('embedding-provider').value;
    const modelSelect = document.getElementById('embedding-model');
    const descriptionSpan = document.getElementById('model-description');

    // Get selected model's label which contains the description
    const selectedOption = modelSelect.options[modelSelect.selectedIndex];
    if (selectedOption) {
        // Extract description from label (after the dash)
        const label = selectedOption.textContent;
        const parts = label.split(' - ');
        if (parts.length > 1) {
            descriptionSpan.textContent = parts.slice(1).join(' - ');
        } else {
            descriptionSpan.textContent = '';
        }
    } else {
        descriptionSpan.textContent = '';
    }
}

/**
 * Update provider information display
 */
function updateProviderInfo() {
    const providerInfo = document.getElementById('provider-info');

    let infoHTML = '';

    providerOptions.forEach(provider => {
        const providerKey = provider.value;
        const models = availableModels[providerKey] || [];

        infoHTML += `
            <div class="ldr-stat-card">
                <h4>${provider.label}</h4>
                <p><strong>Models Available:</strong> ${models.length}</p>
                <p><strong>Status:</strong> <span class="provider-status">Available</span></p>
                <div class="provider-status">
                    <i class="fas fa-check-circle"></i> Ready
                </div>
            </div>
        `;
    });

    providerInfo.innerHTML = infoHTML;
}

/**
 * Handle configuration form submission
 */
async function handleConfigSubmit(event) {
    event.preventDefault();
    console.log('🚀 Configuration form submitted!');

    const provider = document.getElementById('embedding-provider').value;

    // Save Ollama URL first if provider is ollama
    if (provider === 'ollama') {
        const ollamaUrlSaved = await saveOllamaUrl();
        if (!ollamaUrlSaved) {
            showError('Failed to save Ollama URL');
            return;
        }
    }

    // Get text separators and parse JSON
    let textSeparators;
    const textSeparatorsValue = document.getElementById('text-separators').value.trim();
    if (textSeparatorsValue) {
        try {
            textSeparators = JSON.parse(textSeparatorsValue);
            if (!Array.isArray(textSeparators)) {
                showError('Text separators must be a JSON array');
                return;
            }
        } catch (e) {
            showError('Invalid JSON format for text separators');
            return;
        }
    } else {
        // Use default if empty
        textSeparators = ["\n\n", "\n", ". ", " ", ""];
    }

    const formData = {
        embedding_provider: provider,
        embedding_model: document.getElementById('embedding-model').value,
        chunk_size: parseInt(document.getElementById('chunk-size').value),
        chunk_overlap: parseInt(document.getElementById('chunk-overlap').value),
        splitter_type: document.getElementById('splitter-type').value,
        distance_metric: document.getElementById('distance-metric').value,
        index_type: document.getElementById('index-type').value,
        normalize_vectors: document.getElementById('normalize-vectors').checked,
        text_separators: textSeparators
    };

    console.log('📋 Form data:', formData);

    // Validation
    if (!formData.embedding_provider) {
        console.error('❌ No provider selected');
        showError('Please select an embedding provider');
        return;
    }

    if (!formData.embedding_model) {
        console.error('❌ No model selected');
        showError('Please select an embedding model');
        return;
    }

    if (formData.chunk_size < 100 || formData.chunk_size > 5000) {
        console.error('❌ Invalid chunk size:', formData.chunk_size);
        showError('Chunk size must be between 100 and 5000 characters');
        return;
    }

    if (formData.chunk_overlap < 0 || formData.chunk_overlap > 1000) {
        console.error('❌ Invalid chunk overlap:', formData.chunk_overlap);
        showError('Chunk overlap must be between 0 and 1000 characters');
        return;
    }

    console.log('✅ Form validation passed');

    try {
        const csrfToken = document.querySelector('meta[name="csrf-token"]')?.getAttribute('content');
        console.log('🔐 CSRF Token:', csrfToken ? 'Found' : 'Not found');

        const response = await safeFetch('/library/api/rag/configure', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
                'X-CSRFToken': csrfToken
            },
            body: JSON.stringify(formData)
        });

        console.log('📡 Response status:', response.status);
        const responseText = await response.text();
        console.log('📄 Response text:', responseText);

        let data;
        try {
            data = JSON.parse(responseText);
        } catch (parseError) {
            console.error('❌ Failed to parse JSON:', parseError);
            console.error('❌ Response was:', responseText);
            showError('Server returned invalid response. Check console for details.');
            return;
        }

        if (data.success) {
            console.log('✅ Default settings saved successfully!');
            showSuccess('Default embedding settings saved successfully! New collections will use these settings.');
            currentSettings = formData;
            // Update the saved defaults display
            renderSavedDefaults(formData);
        } else {
            console.error('❌ Server returned error:', data.error);
            showError('Failed to save default settings: ' + data.error);
        }
    } catch (error) {
        console.error('❌ Error updating configuration:', error);
        showError('Failed to save configuration: ' + error.message);
    }
}

/**
 * Test configuration by sending a real embedding request
 */
async function testConfiguration() {
    const provider = document.getElementById('embedding-provider').value;
    const model = document.getElementById('embedding-model').value;
    const testBtn = document.getElementById('test-config-btn');
    const testResult = document.getElementById('test-result');

    if (!provider || !model) {
        showError('Please select a provider and model first');
        return;
    }

    // Disable button during test
    testBtn.disabled = true;
    testBtn.innerHTML = '<i class="fas fa-spinner fa-spin"></i> Testing...';

    testResult.style.display = 'block';
    testResult.innerHTML = '<div class="ldr-alert ldr-alert-info"><i class="fas fa-spinner fa-spin"></i> Testing embedding model...</div>';

    try {
        const csrfToken = document.querySelector('meta[name="csrf-token"]')?.getAttribute('content');

        // Send test embedding request with selected configuration
        const response = await safeFetch('/library/api/rag/test-embedding', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
                'X-CSRFToken': csrfToken
            },
            body: JSON.stringify({
                provider: provider,
                model: model,
                test_text: 'This is a test sentence to verify the embedding model is working correctly.'
            })
        });

        const data = await response.json();

        if (data.success) {
            testResult.innerHTML = `
                <div class="ldr-alert ldr-alert-success">
                    <i class="fas fa-check-circle"></i> <strong>Test Passed!</strong><br>
                    Model: ${window.XSSProtection.escapeHtml(model)}<br>
                    Provider: ${window.XSSProtection.escapeHtml(provider)}<br>
                    Embedding dimension: ${window.XSSProtection.escapeHtml(data.dimension)}<br>
                    Response time: ${window.XSSProtection.escapeHtml(data.response_time_ms)}ms
                </div>
            `;
            showSuccess('Embedding test passed!');
        } else {
            testResult.innerHTML = `
                <div class="ldr-alert ldr-alert-danger">
                    <i class="fas fa-times-circle"></i> <strong>Test Failed!</strong><br>
                    Error: ${window.XSSProtection.escapeHtml(data.error || 'Unknown error')}
                </div>
            `;
            showError('Embedding test failed: ' + window.XSSProtection.escapeHtml(data.error || 'Unknown error'));
        }
    } catch (error) {
        testResult.innerHTML = `
            <div class="ldr-alert ldr-alert-danger">
                <i class="fas fa-times-circle"></i> <strong>Test Failed!</strong><br>
                Error: ${window.XSSProtection.escapeHtml(error.message)}
            </div>
        `;
        showError('Test failed: ' + window.XSSProtection.escapeHtml(error.message));
    } finally {
        // Re-enable button
        testBtn.disabled = false;
        testBtn.innerHTML = '<i class="fas fa-play"></i> Test Embedding Model';
    }
}

/**
 * Show success message
 */
function showSuccess(message) {
    const alertDiv = document.createElement('div');
    alertDiv.className = 'ldr-alert ldr-alert-success';
    alertDiv.innerHTML = `<i class="fas fa-check-circle"></i>${message}`;

    // Insert at the top of the container
    const container = document.querySelector('.ldr-library-container');
    container.insertBefore(alertDiv, container.firstChild);

    // Auto-remove after 5 seconds
    setTimeout(() => {
        if (alertDiv.parentNode) {
            alertDiv.parentNode.removeChild(alertDiv);
        }
    }, 5000);
}

/**
 * Show info message
 */
function showInfo(message) {
    const alertDiv = document.createElement('div');
    alertDiv.className = 'ldr-alert ldr-alert-info';
    alertDiv.innerHTML = `<i class="fas fa-info-circle"></i>${message}`;

    // Insert at the top of the container
    const container = document.querySelector('.ldr-library-container');
    container.insertBefore(alertDiv, container.firstChild);

    // Auto-remove after 3 seconds
    setTimeout(() => {
        if (alertDiv.parentNode) {
            alertDiv.parentNode.removeChild(alertDiv);
        }
    }, 3000);
}

/**
 * Show error message
 */
function showError(message) {
    const alertDiv = document.createElement('div');
    alertDiv.className = 'ldr-alert ldr-alert-danger';
    alertDiv.innerHTML = `<i class="fas fa-exclamation-triangle"></i>${message}`;

    // Insert at the top of the container
    const container = document.querySelector('.ldr-library-container');
    container.insertBefore(alertDiv, container.firstChild);

    // Auto-remove after 5 seconds
    setTimeout(() => {
        if (alertDiv.parentNode) {
            alertDiv.parentNode.removeChild(alertDiv);
        }
    }, 5000);
}

/**
 * Escape HTML to prevent XSS
 */
function escapeHtml(text) {
    const div = document.createElement('div');
    div.textContent = text;
    return div.innerHTML;
}

/**
 * Toggle Ollama URL field visibility based on selected provider
 */
function toggleOllamaUrlField() {
    const provider = document.getElementById('embedding-provider').value;
    const ollamaUrlGroup = document.getElementById('ollama-url-group');

    if (provider === 'ollama') {
        ollamaUrlGroup.style.display = 'block';
    } else {
        ollamaUrlGroup.style.display = 'none';
    }
}

/**
 * Load Ollama URL from settings
 */
async function loadOllamaUrl() {
    try {
        const response = await safeFetch('/settings/api/embeddings.ollama.url');
        const data = await response.json();

        if (data && data.value) {
            document.getElementById('ollama-url').value = data.value;
        }
    } catch (error) {
        console.error('Error loading Ollama URL:', error);
    }
}

/**
 * Save Ollama URL to settings
 */
async function saveOllamaUrl() {
    const ollamaUrl = document.getElementById('ollama-url').value.trim();

    try {
        const csrfToken = document.querySelector('meta[name="csrf-token"]')?.getAttribute('content');

        const response = await safeFetch('/settings/api/embeddings.ollama.url', {
            method: 'PUT',
            headers: {
                'Content-Type': 'application/json',
                'X-CSRFToken': csrfToken
            },
            body: JSON.stringify({
                value: ollamaUrl
            })
        });

        const data = await response.json();
        if (data.error) {
            console.error('Failed to save Ollama URL:', data.error);
            return false;
        }
        return true;
    } catch (error) {
        console.error('Error saving Ollama URL:', error);
        return false;
    }
}
