/**
 * Research form handling with settings management and warnings
 * Note: URLValidator is available globally via /static/js/security/url-validator.js
 */

// Global settings cache for warning logic
let globalSettings = {};

document.addEventListener('DOMContentLoaded', function() {
    // Initialize the research form
    initResearchForm();
});

/**
 * Initialize the research form with values from settings
 */
function initResearchForm() {
    // Get form elements
    const iterationsInput = document.getElementById('iterations');
    const questionsInput = document.getElementById('questions_per_iteration');

    // Fetch all settings at once (more efficient)
    fetch(URLS.SETTINGS_API.BASE)
        .then(response => {
            if (!response.ok) {
                throw new Error('Failed to fetch settings');
            }
            return response.json();
        })
        .then(data => {
            if (data && data.status === 'success' && data.settings) {
                // Find our specific settings
                const settings = data.settings;

                // Cache settings globally for warning logic
                globalSettings = settings;

                // Look for the iterations setting
                for (const key in settings) {
                    const setting = settings[key];
                    if (key === 'search.iterations' && iterationsInput) {
                        iterationsInput.value = setting.value;
                    }

                    if (key === 'search.questions_per_iteration' && questionsInput) {
                        questionsInput.value = setting.value;
                    }
                }

                // Initialize warnings after settings are loaded
                initializeWarnings();
            }
        })
        .catch(_error => {
            // Form will use default values if settings can't be loaded
        });

    // Add our settings saving to the form submission process
    patchFormSubmitHandler();
}

/**
 * Patch the existing form submit handler to include our settings saving functionality
 */
function patchFormSubmitHandler() {
    // Get the form element
    const form = document.getElementById('research-form');
    if (!form) return;

    // Monitor for form submissions using the capture phase to run before other handlers
    form.addEventListener('submit', function() {
        // Save research settings first, before the main form handler processes the submission
        saveResearchSettings();

        // Let the event continue normally to the other handlers
    }, true); // true enables capture phase
}

/**
 * Save research settings to the database
 */
function saveResearchSettings() {
    const iterationsInput = document.getElementById('iterations');
    const questionsInput = document.getElementById('questions_per_iteration');

    // Only save if the elements exist (not on follow-up modal)
    if (!iterationsInput || !questionsInput) {
        return;
    }

    const iterations = iterationsInput.value;
    const questions = questionsInput.value;

    // Get CSRF token
    const csrfToken = window.api ? window.api.getCsrfToken() : '';

    if (!csrfToken) {
        SafeLogger.warn('CSRF token not found, skipping settings save');
        return;
    }

    // Save settings
    fetch(URLS.SETTINGS_API.SAVE_ALL_SETTINGS, {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
            'X-CSRFToken': csrfToken
        },
        body: JSON.stringify({
            'search.iterations': parseInt(iterations, 10),
            'search.questions_per_iteration': parseInt(questions, 10)
        })
    })
    .then(response => response.json())
    .then(_data => {
        SafeLogger.log('Research settings saved');
    })
    .catch(error => {
        SafeLogger.error('Error saving research settings:', error);
    });
}

/**
 * Initialize warning system
 */
function initializeWarnings() {

    // Check warnings on form load
    checkAndDisplayWarnings();

    // Monitor form changes for dynamic warnings
    setupWarningListeners();

    // Clear any stale warnings immediately when initializing
    setTimeout(() => {
        checkAndDisplayWarnings();
    }, 100);
}

/**
 * Setup event listeners for settings changes
 */
function setupWarningListeners() {
    // Monitor provider changes directly and refetch settings
    const providerSelect = document.getElementById('model_provider');
    if (providerSelect) {
        providerSelect.addEventListener('change', function() {
            // Wait a bit longer for the saveProviderSetting API call to complete
            setTimeout(refetchSettingsAndUpdateWarnings, 500);
        });
    }

    // Hook into the existing saveProviderSetting function if it exists
    // This will trigger when the research.js calls saveProviderSetting
    if (typeof window.saveProviderSetting === 'function') {
        const originalSaveProviderSetting = window.saveProviderSetting;
        window.saveProviderSetting = function(...args) {
            // Call the original function
            const result = originalSaveProviderSetting.apply(this, args);
            // After it completes, refetch settings and update warnings
            setTimeout(refetchSettingsAndUpdateWarnings, 200);
            return result;
        };
    }

    // Monitor search engine changes
    const searchEngineInput = document.getElementById('search_engine');
    if (searchEngineInput) {
        searchEngineInput.addEventListener('change', function() {
            // Refresh warnings immediately when search engine changes
            setTimeout(checkAndDisplayWarnings, 100);
        });
    }

    const strategySelect = document.getElementById('strategy');
    if (strategySelect) {
        strategySelect.addEventListener('change', function() {
            // Strategy is saved via settings_sync.js handler
            // Just update warnings after change
            setTimeout(checkAndDisplayWarnings, 100);
        });
    }

    // Use the global socket manager to listen for settings changes (backup)
    const socketInstance = window.socket ? (window.socket.getSocketInstance() || window.socket.init()) : null;
    if (socketInstance) {
        socketInstance.on('settings_changed', function(data) {
            // Update global settings cache
            if (data.settings) {
                Object.assign(globalSettings, data.settings);
            }
            // Recheck warnings with new settings
            setTimeout(checkAndDisplayWarnings, 100);
        });
    }
}

/**
 * Refetch settings from the server and update warnings
 */
function refetchSettingsAndUpdateWarnings() {

    fetch(URLS.SETTINGS_API.BASE)
        .then(response => {
            if (!response.ok) {
                throw new Error('Failed to fetch settings');
            }
            return response.json();
        })
        .then(data => {
            if (data && data.status === 'success' && data.settings) {
                // Update global settings cache
                globalSettings = data.settings;
            }
            // Recheck warnings from backend (not from cached settings)
            setTimeout(checkAndDisplayWarnings, 100);
        })
        .catch(_error => {
            // Still try to check warnings from backend
            setTimeout(checkAndDisplayWarnings, 100);
        });
}

/**
 * Manually clear all warnings (useful for debugging stale warnings)
 */
function clearAllWarnings() {
    displayWarnings([]);
}

// Make functions globally available for other scripts
window.refetchSettingsAndUpdateWarnings = refetchSettingsAndUpdateWarnings;
window.displayWarnings = displayWarnings;
window.clearAllWarnings = clearAllWarnings;
window.checkAndDisplayWarnings = checkAndDisplayWarnings;

/**
 * Check warning conditions by fetching from backend
 */
function checkAndDisplayWarnings() {

    // Get warnings from backend API instead of calculating locally
    fetch(URLS.SETTINGS_API.WARNINGS)
        .then(response => {
            if (!response.ok) {
                throw new Error('Failed to fetch warnings');
            }
            return response.json();
        })
        .then(data => {
            if (data && data.warnings) {
                displayWarnings(data.warnings);
            } else {
                displayWarnings([]);
            }
        })
        .catch(_error => {
            // Clear warnings on error
            displayWarnings([]);
        });
}

/**
 * Display warnings in the alert container
 */
function displayWarnings(warnings) {
    const alertContainer = document.getElementById('research-alert');
    if (!alertContainer) return;

    if (warnings.length === 0) {
        alertContainer.style.display = 'none';
        alertContainer.innerHTML = '';
        return;
    }

    // Security: escapeHtml applied to API-controlled warning fields before innerHTML insertion
    // bearer:disable javascript_lang_manual_html_sanitization
    const esc = window.escapeHtml || (s => String(s || '').replace(/[&<>"']/g, m => ({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":"&#39;"})[m]));
    const warningsHtml = warnings.map(warning => {
        // Use success styling for recommendations/tips, warning for others
        const isInfo = warning.type === 'searxng_recommendation' || warning.type === 'legacy_server_config' || warning.type === 'backup_info';
        const alertClass = isInfo ? 'ldr-alert-info' : 'ldr-alert-warning';

        // Only render an action link for safe internal paths (start with "/" but not "//")
        const safeActionUrl = (typeof warning.actionUrl === 'string'
            && warning.actionUrl.startsWith('/')
            && !warning.actionUrl.startsWith('//'))
            ? warning.actionUrl
            : null;
        const actionHtml = safeActionUrl
            ? `<a href="${esc(safeActionUrl)}" class="ldr-alert-action">
                  ${esc(warning.actionLabel || 'View details')}
                  <span aria-hidden="true">→</span>
               </a>`
            : '';
        return `
        <div class="ldr-alert ${alertClass} warning-banner warning-${esc(warning.type)}" style="
            border-radius: 6px;
            padding: 12px 16px;
            margin-bottom: 8px;
            display: flex;
            align-items: flex-start;
            gap: 12px;
        ">
            <span style="font-size: 16px; flex-shrink: 0;">${esc(warning.icon)}</span>
            <div style="flex: 1;">
                <div style="font-weight: 600; margin-bottom: 4px;">
                    ${esc(warning.title)}
                </div>
                <div style="font-size: 14px; line-height: 1.4;">
                    ${esc(warning.message)}
                </div>
                ${actionHtml}
            </div>
            <button onclick="dismissWarning('${esc(warning.dismissKey)}')" style="
                background: none;
                border: none;
                color: inherit;
                cursor: pointer;
                padding: 4px;
                font-size: 16px;
                flex-shrink: 0;
                opacity: 0.7;
            ">&times;</button>
        </div>
        `;
    }).join('');

    // bearer:disable javascript_lang_dangerous_insert_html
    // eslint-disable-next-line no-unsanitized/property -- audited 2026-03-28: variable built from escaped/numeric values above
    alertContainer.innerHTML = warningsHtml;
    alertContainer.style.display = 'block';
}

/**
 * Dismiss a warning by updating the setting
 */
function dismissWarning(dismissKey) {

    // Get CSRF token
    const csrfToken = window.api ? window.api.getCsrfToken() : '';

    // Update dismissal setting
    fetch(URLS.SETTINGS_API.SAVE_ALL_SETTINGS, {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
            'X-CSRFToken': csrfToken
        },
        body: JSON.stringify({
            [dismissKey]: true
        })
    })
    .then(response => response.json())
    .then(_data => {
        // Update global settings cache
        globalSettings[dismissKey] = { value: true };
        // Recheck warnings
        checkAndDisplayWarnings();
    })
    .catch(_error => {
    });
}

/**
 * Helper function to get settings
 */
function getSetting(key, defaultValue) {
    return globalSettings[key] ? globalSettings[key].value : defaultValue;
}
