import { expect } from '@playwright/test';
import { STAGING_URL, TIMEOUTS } from '../config/staging-config';

/**
 * Common actions and utilities for E2E tests
 * Reduces code duplication across test files
 */

export class CommonActions {
  constructor(private page: any) {}

  /**
   * Navigate to a page and wait for load
   */
  async navigateAndWait(path: string) {
    const url = path.startsWith('http') ? path : `${STAGING_URL}${path}`;
    await this.page.goto(url);
    await this.page.waitForLoadState('networkidle');
  }

  /**
   * Take screenshot with descriptive name
   */
  async screenshot(name: string) {
    await this.page.screenshot({ 
      path: `test-results/screenshots/${name}-${Date.now()}.png`,
      fullPage: true 
    });
  }

  /**
   * Fill TinyMCE editor content
   */
  async fillTinyMCE(selector: string, content: string) {
    try {
      const frame = this.page.frameLocator('iframe[id*="_ifr"]');
      await frame.locator('body').fill(content);
    } catch {
      // Fallback to textarea if TinyMCE not available
      await this.page.fill(selector, content);
    }
  }

  /**
   * Handle venue creation in event forms
   */
  async createVenue(venueName: string, address: string = '') {
    if (await this.page.locator('select#saved_tribe_venue').count() > 0) {
      await this.page.selectOption('select#saved_tribe_venue', '-1');
      
      const venueNameField = this.page.locator('input[name="Venue[Venue]"]');
      if (await venueNameField.isVisible()) {
        await venueNameField.fill(venueName);
        if (address) {
          await this.page.fill('input[name="Venue[Address]"]', address);
        }
      }
    }
  }

  /**
   * Handle organizer creation in event forms
   */
  async createOrganizer(organizerName: string) {
    if (await this.page.locator('select#saved_tribe_organizer').count() > 0) {
      await this.page.selectOption('select#saved_tribe_organizer', '-1');
      
      const organizerNameField = this.page.locator('input[name="Organizer[Organizer]"]');
      if (await organizerNameField.isVisible()) {
        await organizerNameField.fill(organizerName);
      }
    }
  }

  /**
   * Wait for and verify navigation items are present
   */
  async verifyNavigation() {
    const navButtons = [
      { text: 'Dashboard', selector: 'a[href*="hvac-dashboard"]' },
      { text: 'Generate Certificates', selector: 'text=Generate Certificates' },
      { text: 'Create Event', selector: 'text=Create Event' }
    ];
    
    for (const button of navButtons) {
      const locator = button.selector.startsWith('text=') 
        ? this.page.locator(button.selector)
        : this.page.locator(button.selector);
      await expect(locator.first()).toBeVisible();
    }
  }

  /**
   * Check for PHP errors in browser console
   */
  async checkForPHPErrors() {
    const errors = [];
    
    this.page.on('console', (msg) => {
      if (msg.type() === 'error' && msg.text().includes('PHP')) {
        errors.push(msg.text());
      }
    });

    return errors;
  }

  /**
   * Wait for AJAX request to complete
   */
  async waitForAjax() {
    await this.page.waitForLoadState('networkidle');
    await this.page.waitForTimeout(500); // Additional buffer for AJAX
  }

  /**
   * Enhanced AJAX wait for complex operations like certificate generation
   */
  async waitForComplexAjax() {
    await this.page.waitForLoadState('networkidle');
    await this.page.waitForTimeout(2000); // Longer wait for complex operations
    
    // Wait for any loading indicators to disappear
    const loadingIndicators = this.page.locator('.loading, .spinner, [class*="loading"]');
    if (await loadingIndicators.count() > 0) {
      await loadingIndicators.first().waitFor({ state: 'hidden', timeout: 10000 });
    }
  }

  /**
   * Generate unique test data with timestamp
   */
  generateTestData(prefix: string) {
    const timestamp = Date.now();
    return {
      title: `${prefix} ${timestamp}`,
      description: `Test ${prefix.toLowerCase()} created at ${new Date().toISOString()}`,
      timestamp
    };
  }

  /**
   * Click button and wait for navigation
   */
  async clickAndWait(selector: string) {
    await this.page.click(selector);
    await this.page.waitForLoadState('networkidle');
  }
}