/**
 * Test for News Subscription Form
 * Tests the test run functionality
 */

const puppeteer = require('puppeteer');
const AuthHelper = require('../../auth_helper');

const BASE_URL = process.env.BASE_URL || 'http://127.0.0.1:5000';

// Breaking news table query
const BREAKING_NEWS_QUERY = `Find UP TO 10 IMPORTANT breaking news stories from TODAY ${new Date().toLocaleDateString()} ONLY.

START YOUR RESPONSE DIRECTLY WITH THE TABLE. NO INTRODUCTION OR PREAMBLE.

CRITICAL: All information MUST be from real, verifiable sources. DO NOT invent or fabricate any news, events, or details. Only report what you find from actual news sources.

OUTPUT FORMAT: Begin immediately with a markdown table using this exact structure:

| SOURCES | DATE | HEADLINE | CATEGORY | WHAT HAPPENED | ANALYSIS | IMPACT |
|---------|------|----------|----------|---------------|----------|--------|
| [Citation numbers] | [YYYY-MM-DD] | [Descriptive headline] | [War/Security/Economy/Disaster/Politics/Tech] | [3 sentences max from actual sources] | [Why it matters + What happens next + Historical context] | [1-10 score] | [Status] |`;

describe('News Subscription Form Tests', () => {
    let browser;
    let page;
    let authHelper;

    beforeAll(async () => {
        browser = await puppeteer.launch({
            headless: false, // Show browser for debugging
            slowMo: 50, // Slow down actions
            devtools: true, // Open DevTools
            args: ['--no-sandbox', '--disable-setuid-sandbox']
        });
        page = await browser.newPage();

        // Set viewport
        await page.setViewport({ width: 1280, height: 800 });

        // Enable console logging
        page.on('console', msg => {
            console.log(`BROWSER LOG [${msg.type()}]:`, msg.text());
        });

        // Log network errors
        page.on('pageerror', error => {
            console.log('PAGE ERROR:', error.message);
        });

        // Log failed requests
        page.on('requestfailed', request => {
            console.log('REQUEST FAILED:', request.url(), request.failure().errorText);
        });

        authHelper = new AuthHelper(page, BASE_URL);
    });

    afterAll(async () => {
        if (browser) {
            await browser.close();
        }
    });

    beforeEach(async () => {
        // Ensure we're logged in before each test
        await authHelper.ensureAuthenticated();
    });

    test('should load subscription form page', async () => {
        console.log('Navigating to subscription form...');
        await page.goto(`${BASE_URL}/news/subscriptions/new`, {
            waitUntil: 'networkidle2',
            timeout: 30000
        });

        // Check if page loaded
        const title = await page.title();
        expect(title).toContain('News Subscription');

        // Check if form exists
        const form = await page.$('#subscription-form');
        expect(form).toBeTruthy();

        // Take screenshot
        await page.screenshot({
            path: 'screenshots/subscription_form_loaded.png',
            fullPage: true
        });
    });

    test('should have test run button', async () => {
        console.log('Checking for test run button...');

        // Navigate to subscription form
        await page.goto(`${BASE_URL}/news/subscriptions/new`, {
            waitUntil: 'networkidle2',
            timeout: 30000
        });

        // Wait for test button
        const testButton = await page.waitForSelector('#test-subscription-btn', {
            timeout: 10000
        });

        expect(testButton).toBeTruthy();

        // Check button text
        const buttonText = await page.evaluate(() => {
            const btn = document.getElementById('test-subscription-btn');
            return btn ? btn.textContent : null;
        });

        console.log('Test button text:', buttonText);
        expect(buttonText).toContain('Test Run');
    });

    test('should show alert when test run clicked without query', async () => {
        console.log('Testing empty query validation...');

        // Navigate to subscription form
        await page.goto(`${BASE_URL}/news/subscriptions/new`, {
            waitUntil: 'networkidle2',
            timeout: 30000
        });

        // Click test run without entering query
        await page.click('#test-subscription-btn');

        // Wait for alert
        await page.waitForSelector('.alert', { timeout: 5000 });

        // Check alert text
        const alertText = await page.evaluate(() => {
            const alert = document.querySelector('.alert');
            return alert ? alert.textContent : null;
        });

        console.log('Alert text:', alertText);
        expect(alertText).toContain('Please enter a query first');

        // Take screenshot
        await page.screenshot({
            path: 'screenshots/subscription_test_empty_query.png',
            fullPage: true
        });
    });

    test('should handle test run with breaking news query', async () => {
        console.log('Testing with breaking news query...');

        // Navigate to subscription form
        await page.goto(`${BASE_URL}/news/subscriptions/new`, {
            waitUntil: 'networkidle2',
            timeout: 30000
        });

        // Enter the breaking news query
        console.log('Entering query...');
        const queryTextarea = await page.$('#subscription-query');
        await queryTextarea.click({ clickCount: 3 }); // Select all
        await queryTextarea.type(BREAKING_NEWS_QUERY);

        // Take screenshot before clicking
        await page.screenshot({
            path: 'screenshots/subscription_before_test_run.png',
            fullPage: true
        });

        // Set up request interception to monitor API calls
        const requests = [];
        page.on('request', request => {
            if (request.url().includes('/research/api/start_research')) {
                console.log('Research API request:', request.method(), request.url());
                console.log('Request headers:', request.headers());
                console.log('Request body:', request.postData());
                requests.push(request);
            }
        });

        // Click test run
        console.log('Clicking test run button...');
        await page.click('#test-subscription-btn');

        // Wait a bit to see what happens
        await new Promise(resolve => setTimeout(resolve, 3000));

        // Take screenshot after clicking
        await page.screenshot({
            path: 'screenshots/subscription_after_test_run.png',
            fullPage: true
        });

        // Check if any requests were made
        console.log('Total research API requests:', requests.length);

        // Check current URL
        const currentUrl = page.url();
        console.log('Current URL after test run:', currentUrl);

        // Check for any alerts or errors
        const alerts = await page.$$('.alert');
        for (const alert of alerts) {
            const text = await page.evaluate(el => el.textContent, alert);
            console.log('Alert found:', text);
        }

        // Check console for errors
        const jsErrors = [];
        page.on('pageerror', error => jsErrors.push(error.message));

        if (jsErrors.length > 0) {
            console.log('JavaScript errors:', jsErrors);
        }

        // Verify if research was started or if we got an error
        if (currentUrl.includes('/news')) {
            console.log('Successfully redirected to news page');
        } else if (currentUrl.includes('/auth/login')) {
            console.log('Redirected to login - authentication issue');
            throw new Error('Test run requires authentication');
        } else {
            console.log('Still on subscription form - checking for errors');

            // Look for error messages
            const errorAlert = await page.$('.alert-danger, .alert-error');
            if (errorAlert) {
                const errorText = await page.evaluate(el => el.textContent, errorAlert);
                console.log('Error alert:', errorText);
            }
        }
    }, 60000); // 60 second timeout

    test('should check button event listeners', async () => {
        console.log('Checking button event listeners...');

        // Navigate to subscription form
        await page.goto(`${BASE_URL}/news/subscriptions/new`, {
            waitUntil: 'networkidle2',
            timeout: 30000
        });

        // Check if button has event listeners
        const hasClickHandler = await page.evaluate(() => {
            const btn = document.getElementById('test-subscription-btn');
            if (!btn) return false;

            // Check jQuery events if jQuery is available
            if (typeof $ !== 'undefined' && $.fn && $.fn.jquery) {
                const events = $._data(btn, 'events');
                console.log('jQuery events:', events);
                return events && events.click && events.click.length > 0;
            }

            // Check native event listeners (this is limited)
            // We can't directly access event listeners added with addEventListener
            // But we can check if clicking triggers anything
            return true; // Assume it has handlers if button exists
        });

        console.log('Has click handler:', hasClickHandler);

        // Try to manually trigger the function
        const functionExists = await page.evaluate(() => {
            return typeof handleTestRun === 'function';
        });

        console.log('handleTestRun function exists:', functionExists);

        // Check if all required elements exist
        const elements = await page.evaluate(() => {
            return {
                queryField: !!document.getElementById('subscription-query'),
                providerField: !!document.getElementById('subscription-provider'),
                modelField: !!document.getElementById('subscription-model'),
                testButton: !!document.getElementById('test-subscription-btn'),
                form: !!document.getElementById('subscription-form')
            };
        });

        console.log('Page elements:', elements);
        expect(elements.queryField).toBe(true);
        expect(elements.testButton).toBe(true);
    });
});
