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

// Test changing API key via direct API calls
(async () => {
    let browser;
    let authHelper;

    try {
        console.log('=== Starting API Key Test via API ===');

        // Test configuration
        const TEST_API_KEY_1 = 'test-api-key-12345';
        const TEST_API_KEY_2 = 'changed-api-key-67890';
        const BASE_URL = 'http://localhost:5000';

        // Launch browser
        browser = await puppeteer.launch(getPuppeteerLaunchOptions());

        const page = await browser.newPage();

        // Initialize auth helper
        authHelper = new AuthHelper(page);

        // Create test user
        const timestamp = Date.now();
        const testUsername = `api_test_${timestamp}`;
        const testPassword = 'testpass123';

        console.log(`Creating user: ${testUsername}`);
        await authHelper.register(testUsername, testPassword);

        const isAuthenticated = await authHelper.isLoggedIn();
        if (!isAuthenticated) {
            throw new Error('Failed to authenticate after registration');
        }
        console.log('✓ User authenticated successfully');

        // Test 1: Get current settings via API
        console.log('\nTest 1: Getting current settings...');
        const currentSettings = await page.evaluate(async () => {
            const response = await fetch('/api/settings', {
                credentials: 'same-origin'
            });
            return await response.json();
        });

        console.log(`Total settings: ${currentSettings.settings?.length || 0}`);
        const apiKeySetting = currentSettings.settings?.find(s =>
            s.key === 'llm.openai_endpoint.api_key' ||
            s.setting_key === 'llm.openai_endpoint.api_key'
        );
        console.log(`Current API key setting found: ${!!apiKeySetting}`);
        if (apiKeySetting) {
            console.log(`Current value: ${apiKeySetting.value ? '***' + apiKeySetting.value.slice(-5) : 'empty'}`);
        }

        // Test 2: Update API key via API
        console.log(`\nTest 2: Setting API key to: ${TEST_API_KEY_1}`);
        const updateResult1 = await page.evaluate(async (key) => {
            const response = await fetch('/api/settings', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                },
                credentials: 'same-origin',
                body: JSON.stringify({
                    'llm.openai_endpoint.api_key': key
                })
            });
            return {
                ok: response.ok,
                status: response.status,
                data: await response.json()
            };
        }, TEST_API_KEY_1);

        console.log(`Update result: ${updateResult1.ok ? 'SUCCESS' : 'FAILED'} (status: ${updateResult1.status})`);
        if (updateResult1.data.message) {
            console.log(`Message: ${updateResult1.data.message}`);
        }

        // Test 3: Verify the update
        console.log('\nTest 3: Verifying update...');
        const verifySettings1 = await page.evaluate(async () => {
            const response = await fetch('/api/settings', {
                credentials: 'same-origin'
            });
            return await response.json();
        });

        const updatedSetting1 = verifySettings1.settings?.find(s =>
            s.key === 'llm.openai_endpoint.api_key' ||
            s.setting_key === 'llm.openai_endpoint.api_key'
        );

        if (updatedSetting1) {
            console.log(`Verified value: ${updatedSetting1.value ? '***' + updatedSetting1.value.slice(-5) : 'empty'}`);
            if (updatedSetting1.value && updatedSetting1.value.includes(TEST_API_KEY_1.slice(-5))) {
                console.log('✓ API key 1 set successfully!');
            } else {
                console.log('✗ API key 1 was not set correctly');
            }
        }

        // Test 4: Change to second API key
        console.log(`\nTest 4: Changing API key to: ${TEST_API_KEY_2}`);
        const updateResult2 = await page.evaluate(async (key) => {
            const response = await fetch('/api/settings', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                },
                credentials: 'same-origin',
                body: JSON.stringify({
                    'llm.openai_endpoint.api_key': key
                })
            });
            return {
                ok: response.ok,
                status: response.status,
                data: await response.json()
            };
        }, TEST_API_KEY_2);

        console.log(`Update result: ${updateResult2.ok ? 'SUCCESS' : 'FAILED'} (status: ${updateResult2.status})`);

        // Test 5: Final verification
        console.log('\nTest 5: Final verification...');
        const verifySettings2 = await page.evaluate(async () => {
            const response = await fetch('/api/settings', {
                credentials: 'same-origin'
            });
            return await response.json();
        });

        const updatedSetting2 = verifySettings2.settings?.find(s =>
            s.key === 'llm.openai_endpoint.api_key' ||
            s.setting_key === 'llm.openai_endpoint.api_key'
        );

        if (updatedSetting2) {
            console.log(`Final value: ${updatedSetting2.value ? '***' + updatedSetting2.value.slice(-5) : 'empty'}`);
            if (updatedSetting2.value && updatedSetting2.value.includes(TEST_API_KEY_2.slice(-5))) {
                console.log('✓ API key 2 set successfully!');
            } else {
                console.log('✗ API key 2 was not set correctly');
            }
        }

        // Test 6: Check if settings persist after navigation
        console.log('\nTest 6: Checking persistence after navigation...');
        await page.goto(`${BASE_URL}/`, { waitUntil: 'domcontentloaded' });
        await page.goto(`${BASE_URL}/settings`, { waitUntil: 'domcontentloaded' });

        const finalCheck = await page.evaluate(async () => {
            const response = await fetch('/api/settings', {
                credentials: 'same-origin'
            });
            return await response.json();
        });

        const finalSetting = finalCheck.settings?.find(s =>
            s.key === 'llm.openai_endpoint.api_key' ||
            s.setting_key === 'llm.openai_endpoint.api_key'
        );

        if (finalSetting && finalSetting.value) {
            console.log(`Settings persisted after navigation: ${finalSetting.value ? '***' + finalSetting.value.slice(-5) : 'empty'}`);
        }

        console.log('\n=== API Key Test Completed ===');

    } catch (error) {
        console.error(`Test failed: ${error.message}`);
        console.error(error);
        process.exit(1);
    } finally {
        if (browser) {
            await browser.close();
            console.log('Browser closed');
        }
    }
})();
