/**
 * UI Tests for Library Document Management
 * Tests document viewing, searching, and management in the Library.
 */

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

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

// Helper function for delays (Puppeteer doesn't have waitForTimeout like Playwright)
const delay = (ms) => new Promise(resolve => setTimeout(resolve, ms));

describe('Library Documents UI Tests', () => {
    let browser;
    let page;
    let authHelper;

    beforeAll(async () => {
        browser = await puppeteer.launch(getPuppeteerLaunchOptions());
    });

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

    beforeEach(async () => {
        page = await browser.newPage();
        page.setDefaultTimeout(TIMEOUT);
        authHelper = new AuthHelper(page, BASE_URL);

        // Authenticate before each test
        await page.goto(BASE_URL, { waitUntil: 'networkidle2' });
        await authHelper.ensureAuthenticated();
    });

    afterEach(async () => {
        if (page) {
            await page.close();
        }
    });

    describe('Library Page Load', () => {
        test('should load library page', async () => {
            await page.goto(`${BASE_URL}/library/`, { waitUntil: 'networkidle2' });

            const pageTitle = await page.title();
            expect(pageTitle.toLowerCase()).toContain('library');
        });

        test('should display navigation elements', async () => {
            await page.goto(`${BASE_URL}/library/`, { waitUntil: 'networkidle2' });

            // Check for main navigation elements
            const mainNav = await page.$('nav, .navbar, .sidebar');
            expect(mainNav).toBeTruthy();

            // Check for library-specific navigation
            const libraryNav = await page.$('.library-nav, .collection-sidebar, [role="navigation"]');
            // Library nav is optional but page should load
            const pageContent = await page.content();
            expect(pageContent.length).toBeGreaterThan(0);
        });

        test('should show search functionality', async () => {
            await page.goto(`${BASE_URL}/library/`, { waitUntil: 'networkidle2' });

            // Look for search input
            const searchInput = await page.$(
                'input[type="search"], input[name="query"], .search-input, #library-search'
            );

            // Search should be available
            expect(searchInput).toBeTruthy();
        });
    });

    describe('Document Search', () => {
        test('should allow entering search query', async () => {
            await page.goto(`${BASE_URL}/library/`, { waitUntil: 'networkidle2' });

            const searchInput = await page.$(
                'input[type="search"], input[name="query"], .search-input'
            );

            if (searchInput) {
                await searchInput.type('test query');

                const inputValue = await page.$eval(
                    'input[type="search"], input[name="query"], .search-input',
                    el => el.value
                );
                expect(inputValue).toBe('test query');
            }
        });

        test('should submit search form', async () => {
            await page.goto(`${BASE_URL}/library/`, { waitUntil: 'networkidle2' });

            const searchInput = await page.$(
                'input[type="search"], input[name="query"], .search-input'
            );

            if (searchInput) {
                await searchInput.type('machine learning');

                // Submit search
                await page.keyboard.press('Enter');

                // Wait for results or loading state
                await delay(2000);

                // Check for results or empty state
                const pageContent = await page.content();
                const hasResults = pageContent.includes('result') ||
                    pageContent.includes('document') ||
                    pageContent.includes('No results');

                expect(hasResults).toBeTruthy();
            }
        });
    });

    describe('Document Viewer', () => {
        test('should open document when clicked', async () => {
            await page.goto(`${BASE_URL}/library/`, { waitUntil: 'networkidle2' });

            // Look for a document link
            const documentLink = await page.$(
                '.document-item a, [data-document-id], .doc-title'
            );

            if (documentLink) {
                const initialUrl = page.url();
                await documentLink.click();
                await delay(1000);

                const newUrl = page.url();
                // URL should change or modal should open
                const urlChanged = newUrl !== initialUrl;
                const modalOpened = await page.$('.modal.show, .document-viewer');

                expect(urlChanged || modalOpened).toBeTruthy();
            }
        });

        test('should display document content', async () => {
            // Navigate to a specific document if available
            await page.goto(`${BASE_URL}/library/`, { waitUntil: 'networkidle2' });

            const documentLink = await page.$(
                '.document-item a, [data-document-id]'
            );

            if (documentLink) {
                await documentLink.click();
                await delay(2000);

                // Look for document content area
                const contentArea = await page.$(
                    '.document-content, .doc-viewer, .pdf-viewer, .text-content'
                );

                // Content area should exist if document was opened
                const pageContent = await page.content();
                expect(pageContent.length).toBeGreaterThan(0);
            }
        });
    });

    describe('Document Actions', () => {
        test('should show document action menu', async () => {
            await page.goto(`${BASE_URL}/library/`, { waitUntil: 'networkidle2' });

            // Look for action menu button
            const actionButton = await page.$(
                '.doc-actions, .dropdown-toggle, [data-action="more"]'
            );

            if (actionButton) {
                await actionButton.click();

                // Menu should appear
                const menu = await page.$('.dropdown-menu.show, .action-menu');
                expect(menu).toBeTruthy();
            }
        });

        test('should allow document deletion', async () => {
            await page.goto(`${BASE_URL}/library/`, { waitUntil: 'networkidle2' });

            // Look for delete option
            const deleteButton = await page.$(
                'button[data-action="delete-doc"], .delete-doc-btn'
            );

            if (deleteButton) {
                await deleteButton.click();

                // Should show confirmation
                const confirmDialog = await page.$('.confirm-dialog, .modal-confirm');
                expect(confirmDialog).toBeTruthy();
            }
        });
    });

    describe('RAG Integration', () => {
        test('should show RAG search option', async () => {
            await page.goto(`${BASE_URL}/library/`, { waitUntil: 'networkidle2' });

            // Look for RAG/semantic search option
            const ragOption = await page.$(
                '.rag-search, [data-action="semantic-search"], .ai-search'
            );

            // RAG search may be available
            const pageContent = await page.content();
            const hasRagFeature = ragOption !== null ||
                pageContent.includes('semantic') ||
                pageContent.includes('AI search') ||
                pageContent.includes('RAG');

            // Just verify page loaded
            expect(pageContent.length).toBeGreaterThan(0);
        });

        test('should show index status', async () => {
            await page.goto(`${BASE_URL}/library/`, { waitUntil: 'networkidle2' });

            // Look for index status indicator
            const indexStatus = await page.$(
                '.index-status, [data-testid="rag-status"], .embedding-status'
            );

            // Status may or may not be visible
            const pageContent = await page.content();
            expect(pageContent.length).toBeGreaterThan(0);
        });
    });

    describe('Download Manager', () => {
        test('should show download queue link', async () => {
            await page.goto(`${BASE_URL}/library/`, { waitUntil: 'networkidle2' });

            // Look for download queue link
            const downloadQueueLink = await page.$(
                'a[href*="downloads"], .download-queue-link'
            );

            const pageContent = await page.content();
            const hasDownloadFeature = downloadQueueLink !== null ||
                pageContent.includes('download') ||
                pageContent.includes('queue');

            expect(pageContent.length).toBeGreaterThan(0);
        });

        test('should open download queue page', async () => {
            // Navigate directly to downloads page
            await page.goto(`${BASE_URL}/library/downloads`, { waitUntil: 'networkidle2' });

            const pageTitle = await page.title();
            const pageContent = await page.content();

            // Should load without error
            expect(pageContent.length).toBeGreaterThan(0);
        });
    });
});

// Run tests
if (require.main === module) {
    const { execSync } = require('child_process');
    try {
        execSync('npx jest ' + __filename + ' --testTimeout=60000', { stdio: 'inherit' });
    } catch (error) {
        process.exit(1);
    }
}
