/**
 * Research API Test
 * Direct test of the research API endpoint
 */

const puppeteer = require('puppeteer');
const AuthHelper = require('./auth_helper');
const { getPuppeteerLaunchOptions } = require('./puppeteer_config');

// NAVIGATION NOTE: Using 'domcontentloaded' instead of 'networkidle2' for page.goto()
// because networkidle2 waits for no network activity for 500ms, but WebSocket
// connections and background polling keep the network active, causing infinite hangs.
// See: test_login_validation.js and auth_helper.js for detailed explanation.
async function testResearchAPI() {
    const browser = await puppeteer.launch(getPuppeteerLaunchOptions());

    const page = await browser.newPage();
    const baseUrl = 'http://127.0.0.1:5000';
    const authHelper = new AuthHelper(page, baseUrl);

    console.log('🔬 Research API Test\n');

    try {
        // Login first to get session cookies
        console.log('🔐 Getting authentication...');
        await authHelper.ensureAuthenticatedWithTimeout();

        // Get cookies
        const cookies = await page.cookies();
        console.log(`✅ Got ${cookies.length} cookies\n`);

        // Go to home page to get CSRF token
        await page.goto(baseUrl, {
            waitUntil: 'domcontentloaded',
            timeout: 30000
        });

        // Extract CSRF token and form defaults
        const pageData = await page.evaluate(() => {
            // Try to find CSRF token
            let csrfToken = '';
            const csrfInput = document.querySelector('input[name="csrf_token"]');
            if (csrfInput) {
                csrfToken = csrfInput.value;
            } else {
                // Check meta tags
                const csrfMeta = document.querySelector('meta[name="csrf-token"]');
                if (csrfMeta) {
                    csrfToken = csrfMeta.content;
                }
            }

            // Get default values
            return {
                csrf_token: csrfToken,
                model_provider: document.querySelector('#model_provider')?.value || 'OLLAMA',
                model: document.querySelector('#model, input[name="model"]')?.value || 'llama3.2:3b',
                search_engine: document.querySelector('#search_engine, input[name="search_engine"]')?.value || 'searxng',
                iterations: document.querySelector('#iterations')?.value || '2',
                questions_per_iteration: document.querySelector('#questions_per_iteration')?.value || '3'
            };
        });

        console.log('📋 Page data extracted:');
        console.log(`  CSRF Token: ${pageData.csrf_token ? '✅ Found' : '❌ Not found'}`);
        console.log(`  Model Provider: ${pageData.model_provider}`);
        console.log(`  Model: ${pageData.model}`);
        console.log(`  Search Engine: ${pageData.search_engine}`);

        // Test 1: Try the API directly with fetch
        console.log('\n🧪 Test 1: Direct API call with page.evaluate()');

        const apiResult1 = await page.evaluate(async () => {
            try {
                const response = await fetch('/api/start_research', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json',
                        'Accept': 'application/json'
                    },
                    body: JSON.stringify({
                        query: 'What is 2+2?',
                        mode: 'quick',
                        model_provider: 'OLLAMA',
                        model: 'llama3.2:3b',
                        custom_endpoint: '',
                        search_engine: 'searxng',
                        iterations: 2,
                        questions_per_iteration: 3,
                        strategy: 'source-based'
                    })
                });

                const text = await response.text();
                return {
                    status: response.status,
                    statusText: response.statusText,
                    headers: Object.fromEntries(response.headers.entries()),
                    body: text.substring(0, 500)
                };
            } catch (error) {
                return { error: error.message };
            }
        });

        console.log('API Response:');
        console.log(`  Status: ${apiResult1.status} ${apiResult1.statusText}`);
        console.log(`  Body preview: ${apiResult1.body}`);

        // Test 2: Try with form submission simulation
        console.log('\n🧪 Test 2: Form submission simulation');

        // Fill the form
        await page.type('#query', 'Test query for research');

        // Intercept the next request
        await page.setRequestInterception(true);
        let capturedRequest = null;

        page.on('request', request => {
            if (request.url().includes('/api/start_research')) {
                capturedRequest = {
                    url: request.url(),
                    method: request.method(),
                    headers: request.headers(),
                    postData: request.postData()
                };
            }
            request.continue();
        });

        // Click submit
        const submitButton = await page.$('button[type="submit"]');
        if (submitButton) {
            await submitButton.click();
            await new Promise(resolve => setTimeout(resolve, 2000));

            if (capturedRequest) {
                console.log('Captured request:');
                console.log(`  Method: ${capturedRequest.method}`);
                console.log(`  URL: ${capturedRequest.url}`);
                console.log(`  Body: ${capturedRequest.postData}`);
            }
        }

        // Test 3: Check server health
        console.log('\n🧪 Test 3: Server health check');

        const healthCheck = await page.evaluate(async () => {
            const endpoints = [
                '/api/health',
                '/health',
                '/',
                '/settings/api/available-models'
            ];

            const results = {};
            for (const endpoint of endpoints) {
                try {
                    const response = await fetch(endpoint);
                    results[endpoint] = {
                        status: response.status,
                        ok: response.ok
                    };
                } catch (e) {
                    results[endpoint] = { error: e.message };
                }
            }
            return results;
        });

        console.log('Health check results:');
        Object.entries(healthCheck).forEach(([endpoint, result]) => {
            console.log(`  ${endpoint}: ${result.ok ? '✅' : '❌'} ${result.status || result.error}`);
        });

        // Summary
        console.log('\n📊 Summary:');
        console.log('The research API is failing with a 500 error due to SQLAlchemy transaction issues.');
        console.log('This is a server-side database transaction management problem.');
        console.log('\nPossible causes:');
        console.log('1. Database session is being closed prematurely');
        console.log('2. Multiple threads/processes accessing the same session');
        console.log('3. Missing session.commit() or session.rollback() calls');
        console.log('4. Flask-SQLAlchemy configuration issues');

    } catch (error) {
        console.error('\n❌ Test error:', error.message);
    }

    await browser.close();
    console.log('\n🏁 Test completed');
    process.exit(0);
}

// Run the test
testResearchAPI().catch(error => {
    console.error('Fatal error:', error);
    process.exit(1);
});
