import { test, expect } from './fixtures/auth';
import { CommonActions } from './utils/common-actions';

/**
 * Complete Trainer Journey Test Suite
 * 
 * Tests the full workflow of a trainer:
 * 1. Login and dashboard access
 * 2. Create a new event using TEC Community Events
 * 3. View event in dashboard
 * 4. Edit the event
 * 5. Generate certificates (if attendees exist)
 * 6. View trainer profile
 */
test.describe('Complete Trainer Journey', () => {
  let eventTitle: string;
  let eventId: string;

  test.beforeEach(async ({ authenticatedPage: page }) => {
    const actions = new CommonActions(page);
    
    // Verify we're logged in and on dashboard
    await expect(page).toHaveURL(/hvac-dashboard/);
    await actions.screenshot('journey-start-dashboard');
  });

  test('1. Dashboard Overview', async ({ authenticatedPage: page }) => {
    test.setTimeout(30000);
    const actions = new CommonActions(page);

    // Check dashboard elements
    await expect(page.locator('h1:has-text("Trainer Dashboard")')).toBeVisible();
    
    // Verify navigation elements
    const navElements = {
      createEvent: page.locator('a:has-text("Create Event")').first(),
      myEvents: page.locator('a:has-text("My Events")').first(),
      certificateReports: page.locator('a:has-text("Certificate Reports")').first(),
      generateCertificates: page.locator('a:has-text("Generate Certificates")').first(),
      profile: page.locator('a:has-text("View Profile")').first()
    };

    for (const [name, element] of Object.entries(navElements)) {
      await expect(element).toBeVisible({ timeout: 5000 });
      console.log(`✓ ${name} link is visible`);
    }

    // Check statistics
    const stats = await page.locator('.hvac-stat-card').count();
    console.log(`Dashboard shows ${stats} statistics cards`);
    
    // Check events table
    const eventsTable = page.locator('.hvac-events-table, table').first();
    await expect(eventsTable).toBeVisible();
    
    await actions.screenshot('journey-dashboard-verified');
  });

  test('2. Create New Event', async ({ authenticatedPage: page }) => {
    test.setTimeout(90000);
    const actions = new CommonActions(page);

    // Navigate to Create Event
    await page.click('a:has-text("Create Event")');
    await page.waitForLoadState('networkidle');
    await actions.screenshot('journey-create-event-page');

    // Generate unique event data
    const testData = actions.generateTestData('Training');
    eventTitle = `${testData.title} - Trainer Journey Test`;
    
    const eventDetails = {
      title: eventTitle,
      description: `${testData.description}

This comprehensive HVAC training covers:
- System diagnostics and troubleshooting
- Energy efficiency optimization
- Latest industry standards and regulations
- Hands-on practical exercises

Prerequisites: Basic HVAC knowledge
Duration: Full day workshop
Certification: Completion certificate provided`,
      venue: 'HVAC Excellence Training Center',
      address: '456 Training Blvd, Suite 100',
      city: 'Dallas',
      state: 'TX',
      zip: '75201'
    };

    // Wait for form to be ready
    await page.waitForTimeout(2000);

    // Try different form selectors based on what TEC might use
    const titleSelectors = [
      'input[name="post_title"]',
      'input#post_title',
      'input[name="event_title"]',
      '#event_title',
      'input[placeholder*="Event Title"]'
    ];

    let titleFilled = false;
    for (const selector of titleSelectors) {
      const field = page.locator(selector).first();
      if (await field.count() > 0 && await field.isVisible()) {
        await field.fill(eventDetails.title);
        titleFilled = true;
        console.log(`✓ Filled title using selector: ${selector}`);
        break;
      }
    }

    if (!titleFilled) {
      throw new Error('Could not find event title field');
    }

    // Fill description - try different approaches
    const contentFilled = await fillEventDescription(page, eventDetails.description);
    if (!contentFilled) {
      console.log('Warning: Could not fill event description');
    }

    // Set event dates (1 week from now)
    const eventDate = new Date();
    eventDate.setDate(eventDate.getDate() + 7);
    const dateStr = eventDate.toISOString().split('T')[0];

    const dateSelectors = [
      { field: 'EventStartDate', value: dateStr },
      { field: 'EventEndDate', value: dateStr },
      { field: 'event_start_date', value: dateStr },
      { field: 'event_end_date', value: dateStr }
    ];

    for (const { field, value } of dateSelectors) {
      const input = page.locator(`input[name="${field}"], input#${field}`).first();
      if (await input.count() > 0 && await input.isVisible()) {
        await input.fill(value);
        console.log(`✓ Filled ${field}`);
      }
    }

    // Set times if separate fields exist
    const timeFields = [
      { field: 'EventStartTime', value: '09:00' },
      { field: 'EventEndTime', value: '17:00' },
      { field: 'event_start_time', value: '09:00 AM' },
      { field: 'event_end_time', value: '05:00 PM' }
    ];

    for (const { field, value } of timeFields) {
      const input = page.locator(`input[name="${field}"], input#${field}`).first();
      if (await input.count() > 0 && await input.isVisible()) {
        await input.fill(value);
      }
    }

    // Fill venue information
    const venueFields = [
      { field: 'venue[Venue]', value: eventDetails.venue },
      { field: 'venue[Address]', value: eventDetails.address },
      { field: 'venue[City]', value: eventDetails.city },
      { field: 'venue[State]', value: eventDetails.state },
      { field: 'venue[Zip]', value: eventDetails.zip }
    ];

    for (const { field, value } of venueFields) {
      const input = page.locator(`input[name="${field}"], input#venue-${field.toLowerCase()}`).first();
      if (await input.count() > 0 && await input.isVisible()) {
        await input.fill(value);
        console.log(`✓ Filled venue ${field}`);
      }
    }

    await actions.screenshot('journey-event-form-filled');

    // Find and click submit button
    const submitSelectors = [
      'input[type="submit"][value*="Submit"]',
      'button[type="submit"]',
      'input[type="submit"].button-primary',
      '#submitButton',
      '.tribe-submit-button'
    ];

    let submitted = false;
    for (const selector of submitSelectors) {
      const button = page.locator(selector).first();
      if (await button.count() > 0 && await button.isVisible()) {
        await Promise.all([
          page.waitForNavigation({ timeout: 30000, waitUntil: 'networkidle' }).catch(() => {}),
          button.click()
        ]);
        submitted = true;
        console.log(`✓ Clicked submit using selector: ${selector}`);
        break;
      }
    }

    if (!submitted) {
      throw new Error('Could not find submit button');
    }

    await actions.screenshot('journey-after-event-submit');

    // Check for success
    const successSelectors = [
      '.tribe-success',
      '.notice-success',
      '.updated',
      'text=successfully',
      'text=pending review'
    ];

    let successFound = false;
    for (const selector of successSelectors) {
      const element = page.locator(selector).first();
      if (await element.count() > 0) {
        successFound = true;
        console.log(`✓ Success indicator found: ${selector}`);
        console.log(`Message: ${await element.textContent()}`);
        break;
      }
    }

    expect(successFound).toBe(true);
  });

  test('3. Verify Event in Dashboard', async ({ authenticatedPage: page }) => {
    test.setTimeout(30000);
    const actions = new CommonActions(page);

    // Navigate to dashboard
    await actions.navigateAndWait('/hvac-dashboard/');
    
    // Look for our event
    const eventRow = page.locator(`tr:has-text("${eventTitle}")`).first();
    const eventFound = await eventRow.count() > 0;

    if (eventFound) {
      console.log('✓ Event found in dashboard!');
      
      // Get event details
      const status = await eventRow.locator('td').first().textContent();
      console.log(`Event status: ${status}`);
      
      // Find edit link to get event ID
      const editLink = eventRow.locator('a:has-text("Edit")').first();
      if (await editLink.count() > 0) {
        const href = await editLink.getAttribute('href');
        const match = href?.match(/event_id=(\d+)/);
        if (match) {
          eventId = match[1];
          console.log(`Event ID: ${eventId}`);
        }
      }
      
      await actions.screenshot('journey-event-in-dashboard');
    } else {
      console.log('Event not immediately visible (may be pending approval)');
      
      // Try different filters
      const filters = ['pending', 'draft', 'all'];
      for (const filter of filters) {
        const filterLink = page.locator(`a:has-text("${filter}")`).first();
        if (await filterLink.count() > 0) {
          await filterLink.click();
          await page.waitForTimeout(1000);
          
          const found = await page.locator(`tr:has-text("${eventTitle}")`).count() > 0;
          if (found) {
            console.log(`✓ Event found under ${filter} filter`);
            break;
          }
        }
      }
    }
  });

  test('4. Edit Event', async ({ authenticatedPage: page }) => {
    test.setTimeout(60000);
    const actions = new CommonActions(page);

    // Start from dashboard
    await actions.navigateAndWait('/hvac-dashboard/');
    
    // Find our event or any event to edit
    let editLink = page.locator(`tr:has-text("${eventTitle}") a:has-text("Edit")`).first();
    
    if (await editLink.count() === 0) {
      // If our specific event isn't found, edit any available event
      editLink = page.locator('a:has-text("Edit")').first();
    }

    const hasEditableEvent = await editLink.count() > 0;
    
    if (!hasEditableEvent) {
      console.log('No editable events found, skipping edit test');
      test.skip();
      return;
    }

    // Click edit
    await editLink.click();
    await page.waitForLoadState('networkidle');
    await actions.screenshot('journey-edit-event-page');

    // Update title
    const titleField = page.locator('input[name="post_title"], input#post_title').first();
    await expect(titleField).toBeVisible();
    
    const currentTitle = await titleField.inputValue();
    const updatedTitle = `${currentTitle} (Updated ${new Date().toLocaleTimeString()})`;
    await titleField.fill(updatedTitle);

    // Add to description
    const updateNote = `\n\n[Update ${new Date().toLocaleString()}]: Schedule confirmed, materials updated.`;
    const contentUpdated = await fillEventDescription(page, updateNote, true);

    await actions.screenshot('journey-edit-form-updated');

    // Submit changes
    const submitButton = page.locator('input[type="submit"], button[type="submit"]').first();
    await expect(submitButton).toBeVisible();
    
    await Promise.all([
      page.waitForNavigation({ timeout: 30000 }).catch(() => {}),
      submitButton.click()
    ]);

    await actions.screenshot('journey-after-edit-submit');

    // Verify update success
    const successMessage = page.locator('.tribe-success, .notice-success, .updated').first();
    const hasSuccess = await successMessage.count() > 0;
    
    if (hasSuccess) {
      console.log('✓ Event updated successfully');
    }
  });

  test('5. View Trainer Profile', async ({ authenticatedPage: page }) => {
    test.setTimeout(30000);
    const actions = new CommonActions(page);

    // Navigate to profile
    await page.click('a:has-text("View Profile")');
    await page.waitForLoadState('networkidle');
    await actions.screenshot('journey-trainer-profile');

    // Verify profile elements
    await expect(page.locator('h1, h2').filter({ hasText: /profile/i }).first()).toBeVisible();
    
    // Check for trainer information
    const profileSections = [
      'contact information',
      'bio',
      'experience',
      'certifications'
    ];

    for (const section of profileSections) {
      const element = page.locator(`text=/${section}/i`).first();
      if (await element.count() > 0) {
        console.log(`✓ Profile shows ${section}`);
      }
    }

    // Check for edit profile option
    const editProfileLink = page.locator('a:has-text("Edit Profile")').first();
    if (await editProfileLink.count() > 0) {
      console.log('✓ Edit profile option available');
    }
  });

  test('6. Certificate Management', async ({ authenticatedPage: page }) => {
    test.setTimeout(30000);
    const actions = new CommonActions(page);

    // Navigate to certificate reports
    await actions.navigateAndWait('/certificate-reports/');
    await actions.screenshot('journey-certificate-reports');

    // Check page loaded
    await expect(page.locator('h1, h2').filter({ hasText: /certificate/i }).first()).toBeVisible();

    // Check for statistics
    const stats = await page.locator('.stat-value, .metric-value').count();
    console.log(`Certificate reports shows ${stats} statistics`);

    // Navigate to generate certificates
    await page.click('a:has-text("Generate Certificates")');
    await page.waitForLoadState('networkidle');
    await actions.screenshot('journey-generate-certificates');

    // Check if any events are available for certificate generation
    const eventDropdown = page.locator('select[name="event_id"], #event_id').first();
    if (await eventDropdown.count() > 0) {
      const options = await eventDropdown.locator('option').count();
      console.log(`Found ${options - 1} events available for certificate generation`);
      
      if (options > 1) {
        // Select first real event (skip the placeholder option)
        await eventDropdown.selectOption({ index: 1 });
        await page.waitForTimeout(1000);
        
        // Check if attendees loaded
        const attendeeCheckboxes = page.locator('input[type="checkbox"][name="attendee_ids[]"]');
        const attendeeCount = await attendeeCheckboxes.count();
        console.log(`Found ${attendeeCount} attendees for selected event`);
      }
    }
  });
});

/**
 * Helper function to fill event description in various editor types
 */
async function fillEventDescription(page: any, content: string, append: boolean = false): Promise<boolean> {
  // Try TinyMCE first
  const tinyMCEFrames = [
    '#tcepostcontent_ifr',
    '#content_ifr',
    'iframe[id*="content"]'
  ];

  for (const frameSelector of tinyMCEFrames) {
    const frame = page.frameLocator(frameSelector).first();
    const body = frame.locator('body');
    
    if (await body.count() > 0) {
      try {
        if (append) {
          const current = await body.textContent();
          await body.fill(current + content);
        } else {
          await body.fill(content);
        }
        console.log('✓ Filled content in TinyMCE editor');
        return true;
      } catch (e) {
        continue;
      }
    }
  }

  // Try regular textarea
  const textareaSelectors = [
    'textarea[name="post_content"]',
    'textarea#tcepostcontent',
    'textarea[name="event_description"]',
    '#event_description'
  ];

  for (const selector of textareaSelectors) {
    const textarea = page.locator(selector).first();
    if (await textarea.count() > 0 && await textarea.isVisible()) {
      if (append) {
        const current = await textarea.inputValue();
        await textarea.fill(current + content);
      } else {
        await textarea.fill(content);
      }
      console.log(`✓ Filled content in textarea: ${selector}`);
      return true;
    }
  }

  return false;
}