import { test, expect } from '@playwright/test';
import { Config } from './utils/Config';
import { BasePage } from './pages/BasePage';
import { LoginPage } from './pages/LoginPage';
import { DashboardPage } from './pages/DashboardPage';

/**
 * Optimized Certificate Tests
 * 
 * This file contains E2E tests for the certificate system with a focus
 * on verifying the attendee search filter functionality.
 */

// Simple CertificatePage implementation that doesn't depend on external files
class CertificatePage extends BasePage {
    // Certificate Reports page selectors
    private readonly certificateTitle = 'h1:has-text("Certificate Reports")';
    private readonly certificateTable = '.hvac-certificate-table';
    private readonly eventFilter = '#filter_event';
    private readonly attendeeSearch = '#search_attendee';
    private readonly revokedFilter = '#filter_revoked';
    private readonly filterSubmit = 'button[type="submit"]';
    private readonly clearFilters = 'a.hvac-clear-filters';
    private readonly totalCountText = '.hvac-total-count';
    private readonly pagination = '.hvac-pagination';
    private readonly nextPage = '.hvac-pagination a.next';
    private readonly previousPage = '.hvac-pagination a.prev';
    private readonly certificateRows = '.hvac-certificate-table tbody tr';
    private readonly certificateEventCells = 'td.certificate-event';
    private readonly certificateAttendeeCells = 'td.certificate-attendee';

    async navigateToCertificateReports(): Promise<void> {
        await this.page.goto(Config.certificateReportsUrl);
        await this.page.waitForLoadState('networkidle');
    }

    async isCertificateReportsPageVisible(): Promise<boolean> {
        return this.page.locator(this.certificateTitle).isVisible();
    }

    async clearAllFilters(): Promise<void> {
        if (await this.page.locator(this.clearFilters).isVisible()) {
            await this.page.click(this.clearFilters);
            await this.page.waitForTimeout(1000);
        }
    }

    async filterByEvent(eventId: string): Promise<void> {
        await this.clearAllFilters();
        await this.page.selectOption(this.eventFilter, eventId);
        await this.page.click(this.filterSubmit);
        await this.page.waitForSelector(this.certificateTable);
    }

    async filterByAttendee(searchTerm: string): Promise<void> {
        await this.clearAllFilters();
        await this.page.fill(this.attendeeSearch, searchTerm);
        await this.page.click(this.filterSubmit);
        await this.page.waitForSelector(this.certificateTable);
    }

    async filterByRevoked(revoked: boolean): Promise<void> {
        await this.clearAllFilters();
        await this.page.selectOption(this.revokedFilter, revoked ? '1' : '0');
        await this.page.click(this.filterSubmit);
        await this.page.waitForSelector(this.certificateTable);
    }

    async getCertificateCount(): Promise<number> {
        const countText = await this.page.locator(this.totalCountText).textContent();
        const match = countText?.match(/of (\d+) certificates/);
        return match ? parseInt(match[1]) : 0;
    }

    async getEventCellTexts(): Promise<string[]> {
        return this.page.locator(this.certificateEventCells).allTextContents();
    }

    async getAttendeeCellTexts(): Promise<string[]> {
        return this.page.locator(this.certificateAttendeeCells).allTextContents();
    }

    async hasPagination(): Promise<boolean> {
        return this.page.locator(this.pagination).isVisible();
    }

    async clickNextPage(): Promise<void> {
        await this.page.click(this.nextPage);
        await this.page.waitForSelector(this.certificateTable);
    }
}

// Simple test that verifies the certificate data and attendee search functionality
test('Certificate data and attendee search verification', async ({ page }) => {
    // Create page objects
    const loginPage = new LoginPage(page);
    const dashboardPage = new DashboardPage(page);
    const certificatePage = new CertificatePage(page);
    
    // Test event IDs
    const testEvents = [
        { id: '5641', name: 'HVAC System Design Fundamentals' },
        { id: '5668', name: 'Advanced Refrigeration Technology' },
        { id: '5688', name: 'Building Automation Systems Workshop' }
    ];
    
    // Step 1: Login
    console.log('Step 1: Logging in as test trainer');
    await loginPage.navigate();
    await loginPage.login(Config.testTrainer.username, Config.testTrainer.password);
    
    // Verify successful login
    const isLoggedIn = await dashboardPage.isVisible('h1:has-text("Dashboard")');
    expect(isLoggedIn).toBeTruthy();
    
    // Step 2: Navigate to certificate reports
    console.log('Step 2: Navigating to certificate reports page');
    await certificatePage.navigateToCertificateReports();
    
    // Verify certificate page loaded
    const certificatePageVisible = await certificatePage.isCertificateReportsPageVisible();
    expect(certificatePageVisible).toBeTruthy();
    
    // Step 3: Check total certificate count
    console.log('Step 3: Checking total certificate count');
    const totalCount = await certificatePage.getCertificateCount();
    console.log(`Total certificates: ${totalCount}`);
    expect(totalCount).toBeGreaterThanOrEqual(47); // We expect at least 47 certificates from our test data
    
    // Step 4: Test event filtering
    console.log('Step 4: Testing event filtering');
    for (const event of testEvents) {
        await certificatePage.filterByEvent(event.id);
        const eventCount = await certificatePage.getCertificateCount();
        console.log(`Event "${event.name}" has ${eventCount} certificates`);
        
        // Verify all event cells contain the correct name
        const eventCells = await certificatePage.getEventCellTexts();
        for (const cellText of eventCells) {
            expect(cellText).toContain(event.name);
        }
        
        // Take screenshot for verification
        await page.screenshot({ path: `event-filter-${event.id}.png` });
    }
    
    // Step 5: Test attendee name filtering
    console.log('Step 5: Testing attendee name filtering');
    await certificatePage.filterByAttendee('Ben Tester');
    const benCount = await certificatePage.getCertificateCount();
    console.log(`Attendee "Ben Tester" has ${benCount} certificates`);
    
    // Verify attendee cells contain Ben Tester
    const benCells = await certificatePage.getAttendeeCellTexts();
    for (const cellText of benCells) {
        expect(cellText.toLowerCase()).toContain('ben tester');
    }
    
    // Take screenshot for verification
    await page.screenshot({ path: 'attendee-name-filter.png' });
    
    // Step 6: Test attendee email filtering
    console.log('Step 6: Testing attendee email filtering');
    await certificatePage.filterByAttendee('ben@tealmaker.com');
    const emailCount = await certificatePage.getCertificateCount();
    console.log(`Email "ben@tealmaker.com" has ${emailCount} certificates`);
    
    // Take screenshot for verification
    await page.screenshot({ path: 'attendee-email-filter.png' });
    
    // Step 7: Test partial name filtering
    console.log('Step 7: Testing partial name filtering');
    await certificatePage.filterByAttendee('Smith');
    const smithCount = await certificatePage.getCertificateCount();
    console.log(`Partial name "Smith" has ${smithCount} certificates`);
    
    // Take screenshot for verification
    await page.screenshot({ path: 'partial-name-filter.png' });
    
    // Step 8: Test partial email filtering
    console.log('Step 8: Testing partial email filtering');
    await certificatePage.filterByAttendee('@gmail');
    const gmailCount = await certificatePage.getCertificateCount();
    console.log(`Partial email "@gmail" has ${gmailCount} certificates`);
    
    // Take screenshot for verification
    await page.screenshot({ path: 'partial-email-filter.png' });
    
    // Step 9: Test revoked filtering
    console.log('Step 9: Testing revocation status filtering');
    await certificatePage.filterByRevoked(true);
    const revokedCount = await certificatePage.getCertificateCount();
    console.log(`Found ${revokedCount} revoked certificates`);
    
    // Take screenshot for verification
    await page.screenshot({ path: 'revoked-filter.png' });
    
    // Step 10: Test pagination
    console.log('Step 10: Testing pagination if applicable');
    await certificatePage.clearAllFilters();
    const hasPagination = await certificatePage.hasPagination();
    
    if (hasPagination) {
        console.log('Pagination is available, testing navigation');
        await certificatePage.clickNextPage();
        // Take screenshot of second page
        await page.screenshot({ path: 'pagination-page-2.png' });
    } else {
        console.log('No pagination available (not enough certificates)');
    }
    
    console.log('Certificate verification tests completed');
});