import { Page } from '@playwright/test';

/**
 * Utility class for creating test data for certificate tests
 * 
 * This class handles:
 * 1. Setting up test events with attendees
 * 2. Checking in some attendees
 * 3. Cleaning up test data after tests
 */
export class CertificateTestData {
  private page: Page;
  private readonly baseUrl = 'https://wordpress-974670-5399585.cloudwaysapps.com';
  private readonly loginUrl = '/community-login/';
  private readonly dashboardUrl = '/hvac-dashboard/';
  private readonly adminUrl = '/wp-admin/';
  
  private readonly username = 'test_trainer';
  private readonly password = 'Test123!';
  
  private testEventId: string | null = null;
  private testEventName: string | null = null;

  constructor(page: Page) {
    this.page = page;
  }

  /**
   * Login as a trainer user for test setup
   */
  async loginAsTrainer(): Promise<void> {
    await this.page.goto(`${this.baseUrl}${this.loginUrl}`);
    await this.page.fill('#user_login', this.username);
    await this.page.fill('#user_pass', this.password);
    await this.page.click('#wp-submit');
    await this.page.waitForLoadState('networkidle');
    
    // Verify login was successful
    const url = this.page.url();
    if (!url.includes(this.dashboardUrl)) {
      throw new Error(`Login failed. Expected URL to contain ${this.dashboardUrl}, but got ${url}`);
    }
  }

  /**
   * Set up a test event with attendees for certificate testing
   * @returns The name of the created test event
   */
  async setupCertificateTestEvent(): Promise<string | null> {
    // Generate a unique event name with timestamp
    const timestamp = new Date().getTime();
    this.testEventName = `Certificate Test Event ${timestamp}`;
    
    // Navigate to create event page
    await this.page.goto(`${this.baseUrl}/community-events/`);
    await this.page.waitForLoadState('networkidle');
    
    // Populate the event form with test data
    await this.page.fill('#post_title', this.testEventName);
    
    // Set event date (today + 1 day)
    const tomorrow = new Date();
    tomorrow.setDate(tomorrow.getDate() + 1);
    const dateString = tomorrow.toISOString().split('T')[0]; // Format as YYYY-MM-DD
    
    // Fill event date fields
    await this.page.fill('input[name="EventStartDate"]', dateString);
    await this.page.fill('input[name="EventEndDate"]', dateString);
    
    // Set content using TinyMCE if available
    const tinyMceFrame = this.page.frameLocator('.mce-edit-area iframe');
    if (await tinyMceFrame.count() > 0) {
      await tinyMceFrame.locator('body').fill('This is a test event for certificate generation testing.');
    } else {
      // Fallback to regular textarea
      await this.page.fill('#post_content', 'This is a test event for certificate generation testing.');
    }
    
    // Fill other required fields
    await this.page.fill('#EventVenueName', 'Test Venue');
    await this.page.fill('#EventVenueAddress', '123 Test Street');
    await this.page.fill('#EventVenueCity', 'Test City');
    await this.page.fill('#EventVenueCountry', 'United States');
    await this.page.fill('#EventVenueZip', '12345');
    
    // Create ticket
    await this.page.click('text=Tickets');
    await this.page.click('text=Add a new ticket');
    await this.page.fill('.tribe-ticket-field-name input', 'General Admission');
    await this.page.fill('.tribe-ticket-field-price input', '10');
    await this.page.fill('.tribe-ticket-field-capacity input', '100');
    
    // Save event
    await this.page.click('#community-events-submit');
    await this.page.waitForLoadState('networkidle');
    
    // Extract the event ID from the URL or response
    const url = this.page.url();
    const match = url.match(/post=(\d+)/);
    if (match && match[1]) {
      this.testEventId = match[1];
      console.log(`Created test event with ID: ${this.testEventId}`);
    } else {
      console.error('Failed to extract event ID from URL:', url);
    }
    
    // Create test attendees via API for efficiency
    await this.createTestAttendees();
    
    return this.testEventName;
  }

  /**
   * Create test attendees for the event
   * Creates 5 attendees: 3 checked-in, 2 not checked-in
   */
  private async createTestAttendees(): Promise<void> {
    if (!this.testEventId) {
      throw new Error('Cannot create attendees: No test event ID available');
    }

    // Login to admin to create test attendees
    await this.page.goto(`${this.baseUrl}${this.adminUrl}`);
    await this.page.fill('#user_login', this.username);
    await this.page.fill('#user_pass', this.password);
    await this.page.click('#wp-submit');
    await this.page.waitForLoadState('networkidle');

    // Create 5 test attendees
    const attendeeData = [
      { name: 'Test Attendee 1', email: 'test1@example.com', checkedIn: true },
      { name: 'Test Attendee 2', email: 'test2@example.com', checkedIn: true },
      { name: 'Test Attendee 3', email: 'test3@example.com', checkedIn: true },
      { name: 'Test Attendee 4', email: 'test4@example.com', checkedIn: false },
      { name: 'Test Attendee 5', email: 'test5@example.com', checkedIn: false }
    ];

    // Navigate to Event Tickets > Attendees page
    await this.page.goto(`${this.baseUrl}${this.adminUrl}edit.php?post_type=tribe_events&page=tickets-attendees&event_id=${this.testEventId}`);
    await this.page.waitForLoadState('networkidle');

    for (const attendee of attendeeData) {
      // Add attendee manually
      await this.page.click('a:text("Add a new attendee")');
      await this.page.waitForSelector('form.tribe-attendees-page-add-attendee-form');
      
      // Fill attendee details
      await this.page.selectOption('select[name="ticket_id"]', { index: 0 }); // Select the first ticket
      await this.page.fill('input[name="attendee[full_name]"]', attendee.name);
      await this.page.fill('input[name="attendee[email]"]', attendee.email);
      
      // Submit the form
      await this.page.click('button:text("Add")');
      await this.page.waitForLoadState('networkidle');
      
      // Check in the attendee if needed
      if (attendee.checkedIn) {
        // Find the attendee row
        const attendeeRow = this.page.locator(`tr:has-text("${attendee.email}")`).first();
        
        // Click the check-in button
        await attendeeRow.locator('.check-in').click();
        await this.page.waitForLoadState('networkidle');
      }
    }

    console.log(`Created ${attendeeData.length} test attendees for event ${this.testEventId}`);
  }

  /**
   * Clean up test data
   */
  async cleanup(): Promise<void> {
    if (!this.testEventId) {
      console.log('No test data to clean up');
      return;
    }

    try {
      // Login to admin if needed
      if (!this.page.url().includes(this.adminUrl)) {
        await this.page.goto(`${this.baseUrl}${this.adminUrl}`);
        await this.page.fill('#user_login', this.username);
        await this.page.fill('#user_pass', this.password);
        await this.page.click('#wp-submit');
        await this.page.waitForLoadState('networkidle');
      }

      // Move the event to trash
      await this.page.goto(`${this.baseUrl}${this.adminUrl}post.php?post=${this.testEventId}&action=trash`);
      await this.page.waitForLoadState('networkidle');
      
      console.log(`Cleaned up test event with ID: ${this.testEventId}`);
      this.testEventId = null;
      this.testEventName = null;
    } catch (error) {
      console.error('Error during test data cleanup:', error);
    }
  }
}