import { Page, expect } from '@playwright/test';
import { BasePage } from './BasePage';

/**
 * Page object representing the Certificate-related pages
 * Handles both Certificate Generation and Certificate Reports pages
 */
export class CertificatePage extends BasePage {
  // Selectors for Generate Certificates page
  private readonly generatePageTitle = 'h1:text("Generate Certificates")';
  private readonly eventSelectDropdown = '#event_id';
  private readonly selectedEventName = '.hvac-selected-event strong';
  private readonly attendeeList = '.hvac-attendee-list';
  private readonly attendeeItems = '.hvac-attendee-item';
  private readonly checkedInLabel = '.hvac-checked-in';
  private readonly checkAllButton = 'button:text("Select All")';
  private readonly checkCheckedInButton = 'button:text("Select Checked-In")';
  private readonly generateButton = 'button[type="submit"]:text("Generate Certificates")';
  private readonly successMessage = '.hvac-success-message';
  private readonly errorMessage = '.hvac-error-message';

  // Selectors for Certificate Reports page
  private readonly reportsPageTitle = 'h1:text("Certificate Reports")';
  private readonly filterForm = 'form.hvac-certificate-filters';
  private readonly eventFilterSelect = '#filter_event';
  private readonly attendeeSearchInput = '#search_attendee';
  private readonly revokedFilterSelect = '#filter_revoked';
  private readonly filterButton = 'button[type="submit"]:text("Filter")';
  private readonly resetButton = 'button[type="reset"]:text("Reset Filters")';
  private readonly certificateTable = '.hvac-certificate-table';
  private readonly certificateItems = '.hvac-certificate-item';
  private readonly viewCertificateLinks = 'a:text("View")';
  private readonly certificatePreview = '.hvac-certificate-preview';
  private readonly closePreviewButton = '.hvac-preview-close';

  constructor(page: Page) {
    super(page);
  }

  /**
   * Navigate to the Generate Certificates page
   */
  async navigateToGenerateCertificates(): Promise<void> {
    await this.page.goto('/generate-certificates/');
    await this.page.waitForLoadState('networkidle');
    await this.page.waitForSelector(this.generatePageTitle);
  }

  /**
   * Navigate to the Certificate Reports page
   */
  async navigateToCertificateReports(): Promise<void> {
    await this.page.goto('/certificate-reports/');
    await this.page.waitForLoadState('networkidle');
    await this.page.waitForSelector(this.reportsPageTitle);
  }

  /**
   * Check if the Generate Certificates page is visible
   */
  async isGenerateCertificatesPageVisible(): Promise<boolean> {
    return await this.page.isVisible(this.generatePageTitle);
  }

  /**
   * Check if the Certificate Reports page is visible
   */
  async isCertificateReportsPageVisible(): Promise<boolean> {
    return await this.page.isVisible(this.reportsPageTitle);
  }

  /**
   * Select an event from the dropdown on Generate Certificates page
   */
  async selectEvent(eventName: string): Promise<void> {
    await this.page.selectOption(this.eventSelectDropdown, {
      label: new RegExp(eventName, 'i')
    });
    await this.page.waitForSelector(this.attendeeList);
    
    // Verify the selected event
    const selectedText = await this.page.textContent(this.selectedEventName);
    expect(selectedText).toContain(eventName);
  }

  /**
   * Get total number of attendees listed
   */
  async getAttendeeCount(): Promise<number> {
    return await this.page.locator(this.attendeeItems).count();
  }

  /**
   * Get number of checked-in attendees
   */
  async getCheckedInAttendeeCount(): Promise<number> {
    return await this.page.locator(this.checkedInLabel).count();
  }

  /**
   * Select all attendees
   */
  async selectAllAttendees(): Promise<void> {
    await this.page.click(this.checkAllButton);
  }

  /**
   * Select only checked-in attendees
   */
  async selectCheckedInAttendees(): Promise<void> {
    await this.page.click(this.checkCheckedInButton);
  }

  /**
   * Generate certificates for selected attendees
   */
  async generateCertificates(): Promise<void> {
    await this.page.click(this.generateButton);
    await this.page.waitForLoadState('networkidle');
    // Wait for either success or error message
    await this.page.waitForSelector(`${this.successMessage}, ${this.errorMessage}`);
  }

  /**
   * Check if success message is visible
   */
  async isSuccessMessageVisible(): Promise<boolean> {
    return await this.page.isVisible(this.successMessage);
  }

  /**
   * Get success message text
   */
  async getSuccessMessage(): Promise<string | null> {
    return await this.page.textContent(this.successMessage);
  }

  /**
   * Filter certificates by event name
   */
  async searchCertificates(eventName: string): Promise<void> {
    await this.page.selectOption(this.eventFilterSelect, {
      label: new RegExp(eventName, 'i')
    });
    await this.page.click(this.filterButton);
    await this.page.waitForLoadState('networkidle');
  }

  /**
   * Filter certificates by attendee name or email
   */
  async searchAttendee(searchTerm: string): Promise<void> {
    await this.page.fill(this.attendeeSearchInput, searchTerm);
    await this.page.click(this.filterButton);
    await this.page.waitForLoadState('networkidle');
  }

  /**
   * Reset all filters
   */
  async resetFilters(): Promise<void> {
    await this.page.click(this.resetButton);
    await this.page.waitForLoadState('networkidle');
  }

  /**
   * Get the number of certificates in the table
   */
  async getCertificateCount(): Promise<number> {
    return await this.page.locator(this.certificateItems).count();
  }

  /**
   * View a certificate by index
   */
  async viewCertificate(index: number): Promise<void> {
    const viewLinks = this.page.locator(this.viewCertificateLinks);
    const count = await viewLinks.count();
    
    if (index >= count) {
      throw new Error(`Cannot view certificate at index ${index}. Only ${count} certificates available.`);
    }
    
    await viewLinks.nth(index).click();
    await this.page.waitForSelector(this.certificatePreview);
  }

  /**
   * Close the certificate preview
   */
  async closePreview(): Promise<void> {
    await this.page.click(this.closePreviewButton);
    await this.page.waitForSelector(this.certificatePreview, { state: 'hidden' });
  }
}