import { test, expect } from '@playwright/test';
import fs from 'fs';

// --- GLOBAL NETWORK LOGGING ---
const allNetworkLogs = [];
test.beforeEach(async ({ page }) => {
  page.on('request', request => {
    allNetworkLogs.push({
      type: 'request',
      url: request.url(),
      method: request.method(),
      headers: request.headers(),
      postData: request.postData(),
      timestamp: Date.now()
    });
  });
  page.on('response', async response => {
    let body = '';
    try {
      body = await response.text();
    } catch (e) {
      body = '[unavailable]';
    }
    allNetworkLogs.push({
      type: 'response',
      url: response.url(),
      status: response.status(),
      statusText: response.statusText(),
      headers: response.headers(),
      body: body,
      timestamp: Date.now()
    });
  });
});
test.afterEach(async () => {
  fs.writeFileSync(
    'test-results/all-network-traffic.json',
    JSON.stringify(allNetworkLogs, null, 2),
    { encoding: 'utf8' }
  );
});

test.describe('Create Event', () => {
  test.beforeEach(async ({ page }) => {
    page.on('console', msg => {
      if (msg.type() === 'error') {
        fs.appendFileSync('test-results/browser-console-errors.log', `[${new Date().toISOString()}] ${msg.text()}\n`);
      }
    });
    page.on('pageerror', error => {
      fs.appendFileSync('test-results/browser-console-errors.log', `[${new Date().toISOString()}] PAGE ERROR: ${error.message}\n`);
    });
  });
  test('should allow a logged-in trainer to create a new event', async ({ page }) => {
    // --- Login Steps (reused from login.test.ts) ---
    // Navigate to the community login page
    await page.goto('/community-login/');

    // Check if the login form fields are visible and enabled
    const usernameField = page.locator('#user_login');
    const passwordField = page.locator('#user_pass');
    const loginButton = page.locator('#wp-submit');

    await expect(usernameField).toBeVisible();
    await expect(usernameField).toBeEnabled();
    await expect(passwordField).toBeVisible();
    await expect(passwordField).toBeEnabled();
    await expect(loginButton).toBeVisible();
    await expect(loginButton).toBeEnabled();

    // Fill in login credentials
    const username = 'test_trainer';
    const password = 'Test123!';

    await usernameField.fill(username);
    console.log(`Filled in username field with: ${username}`);

    await passwordField.fill(password);
    console.log('Filled in password field.');

    // Click the login button
    await loginButton.click();
    console.log('Clicked login button.');

    // Assert successful login (redirection to dashboard)
    await page.waitForURL('/hvac-dashboard/', { timeout: 15000 });
    console.log('Successfully logged in and redirected to dashboard.');
    // --- End Login Steps ---

    // --- Create Event Steps ---
    // Navigate to the dashboard after login
    await page.goto('/hvac-dashboard/');
    console.log('Navigated to Dashboard:', page.url());
    await page.screenshot({ path: 'dashboard-before-create-event.png', fullPage: true });

    // Look for a link or button to create a new event on the dashboard
    // Look for and click the "Create Event" link on the dashboard
    const createEventLink = page.locator('a', { hasText: 'Create Event' }).first();

    await expect(createEventLink).toBeVisible();
    console.log('Found "Create Event" link.');

    // Click the link to navigate to the event creation page
    await createEventLink.click();
    console.log('Clicked "Create Event" link.');

    // Wait for navigation to the event creation page (/manage-event/)
    await page.waitForURL('/manage-event/', { timeout: 20000 }); // Increase timeout slightly
    console.log('Navigated to event creation page. Current URL:', page.url());
    await page.screenshot({ path: 'create-event-page.png', fullPage: true });

    // Wait for network to be idle after navigation
    await page.waitForLoadState('networkidle');
    console.log('Network idle on event creation page.');

    // --- Force CREATE mode: Remove hidden post_ID input if present ---
// Log current URL and title before waiting for elements
console.log('Current URL before element checks:', page.url());
console.log('Current Page Title before element checks:', await page.title());

// --- Select Venue and Organizer, and populate all other fields ---
// Select the first available Venue
const venueDropdown = page.locator('#saved_tribe_venue');
await expect(venueDropdown).toBeVisible({ timeout: 10000 });
const venueOptions = await venueDropdown.locator('option').all();
if (venueOptions.length > 1) {
  // Skip the first option ("Create or Find a Venue"), select the next
  const firstVenueValue = await venueOptions[1].getAttribute('value');
  await venueDropdown.selectOption(firstVenueValue || '');
  console.log('Selected Venue:', await venueOptions[1].textContent());
}

// Select the first available Organizer
const organizerDropdown = page.locator('#saved_tribe_organizer');
await expect(organizerDropdown).toBeVisible({ timeout: 10000 });
const organizerOptions = await organizerDropdown.locator('option').all();
if (organizerOptions.length > 1) {
  // Skip the first option ("Create or Find an Organizer"), select the next
  const firstOrganizerValue = await organizerOptions[1].getAttribute('value');
  await organizerDropdown.selectOption(firstOrganizerValue || '');
  console.log('Selected Organizer:', await organizerOptions[1].textContent());
}

// Fill Event Website (optional)
const eventWebsiteField = page.locator('#EventURL');
if (await eventWebsiteField.count()) {
  await eventWebsiteField.fill('https://example.com');
  console.log('Filled Event Website');
}

// Set Event Status to "Scheduled" if dropdown exists
const statusDropdown = page.locator('#tribe-events-status-status');
if (await statusDropdown.count()) {
  await statusDropdown.selectOption('scheduled');
  console.log('Set Event Status to Scheduled');
}

// Optionally, select the first category and tag if present
const categoryDropdown = page.locator('select[name="tax_input[tribe_events_cat][]"]');
if (await categoryDropdown.count()) {
  const catOptions = await categoryDropdown.locator('option').all();
  if (catOptions.length > 0) {
    const firstCatValue = await catOptions[0].getAttribute('value');
    if (firstCatValue && firstCatValue !== '') {
      await categoryDropdown.selectOption(firstCatValue);
      console.log('Selected first Event Category');
    }
  }
}
const tagDropdown = page.locator('select[name="tax_input[post_tag][]"]');
if (await tagDropdown.count()) {
  const tagOptions = await tagDropdown.locator('option').all();
  if (tagOptions.length > 0) {
    const firstTagValue = await tagOptions[0].getAttribute('value');
    if (firstTagValue && firstTagValue !== '') {
      await tagDropdown.selectOption(firstTagValue);
      console.log('Selected first Event Tag');
    }
  }
}

// Optionally, configure virtual event fields if present
// Optionally check Virtual Event if interactable (skip if covered)
const virtualCheckbox = page.locator('#tribe-events-virtual-setup');
if (await virtualCheckbox.count() && !(await virtualCheckbox.isChecked())) {
  try {
    await virtualCheckbox.check({ trial: true, force: false, timeout: 1000 });
    await virtualCheckbox.check();
    console.log('Checked Virtual Event');
  } catch (e) {
    console.log('Virtual Event checkbox not interactable, skipping.');
  }
}
// End of additional field population


    // Identify and fill in event form fields (selectors based on typical TEC Community Events forms)
    // Enhanced selectors with fallbacks
    const eventTitleField = page.locator('#post_title, [name="post_title"]');
    const startDateField = page.locator('input[name="EventStartDate"], [data-testid="event-start-date"]');
    const endDateField = page.locator('input[name="EventEndDate"], [data-testid="event-end-date"]');
    const publishButton = page.locator('#post, .events-community-submit');
    
    // Time selectors will be defined after interacting with date fields

    await expect(eventTitleField).toBeVisible({ timeout: 15000 }); // Keep increased timeout
    // Wait for the rich text editor iframe and its content to be visible
    // Click the "Code" tab for the event description to switch to text mode
    const descriptionCodeTab = page.locator('button', { hasText: 'Code' });
    await expect(descriptionCodeTab).toBeVisible();
    await descriptionCodeTab.click();
    console.log('Switched to Code view for event description.');

    // Now the description field should be a visible textarea with ID tcepostcontent
    const eventDescriptionField = page.locator('#tcepostcontent'); // Correct selector for the textarea in Code mode
    await expect(eventDescriptionField).toBeVisible({ timeout: 15000 }); // Wait for the textarea to be visible
    console.log('Event description textarea is visible.');


    await expect(eventTitleField).toBeVisible({ timeout: 15000 });
    await expect(startDateField).toBeVisible({ timeout: 15000 });
    
    // Interact with date field first to trigger time fields to load
    await startDateField.click();
    await startDateField.fill('04/30/2025');
    
    // Wait for time fields to be loaded - try multiple selector patterns
    let startTimeSelect = page.locator('.tribe-timepicker-hour, .tribe-timepicker-minute, .tribe-timepicker-meridian, [data-name="EventStartTime"] input, [name*="EventStartTime"]').first();
    await expect(startTimeSelect).toBeVisible({ timeout: 20000 });
    
    await expect(endDateField).toBeVisible({ timeout: 15000 });
    await endDateField.click();
    await endDateField.fill('04/30/2025');
    
    let endTimeSelect = page.locator('.tribe-timepicker-hour, .tribe-timepicker-minute, .tribe-timepicker-meridian, [data-name="EventEndTime"] input, [name*="EventEndTime"]').first();
    await expect(endTimeSelect).toBeVisible({ timeout: 20000 });

    // --- Enhanced DEBUG: Log page state before looking for publish button ---
    const fs = require('fs');
    const debugDir = 'test-results';
    if (!fs.existsSync(debugDir)) {
      fs.mkdirSync(debugDir, { recursive: true });
    }

    // Capture page HTML and console logs
    const pageHtml = await page.content();
    const consoleLogs: string[] = [];
    page.on('console', msg => {
      if (msg.text()) {
        consoleLogs.push(msg.text());
      }
    });

    // Enhanced debug info
    const debugInfo = {
      timestamp: new Date().toISOString(),
      url: page.url(),
      title: await page.title(),
      buttons: await page.locator('button').allTextContents(),
      inputs: await page.locator('input').allTextContents(),
      links: await page.locator('a').allTextContents(),
      publishButtonExists: await page.locator('#post, .events-community-submit').count() > 0,
      consoleErrors: consoleLogs.filter(log => log.includes('Error')),
      pageHtml: pageHtml
    };

    // Write debug files
    fs.writeFileSync(
      `${debugDir}/debug-before-publish-button.json`,
      JSON.stringify(debugInfo, null, 2),
      { encoding: 'utf8' }
    );
    await page.screenshot({
      path: `${debugDir}/debug-before-publish-button.png`,
      fullPage: true
    });
    console.log('DEBUG: Saved detailed debug information to test-results/');
    // --- END DEBUG ---

    await expect(publishButton).toBeVisible({ timeout: 15000 });

    const eventTitle = `Test Event ${Date.now()}`;
    const eventDescription = 'This is a test event created by Playwright.';
    const eventDate = '2025-12-31'; // Example date in the future
    const eventTime = '10:00'; // Example time

    await eventTitleField.fill(eventTitle);
    console.log(`Filled in event title: ${eventTitle}`);

    // Fill in the event description in the textarea
    await eventDescriptionField.fill(eventDescription);
    console.log('Filled in event description.');

    await startDateField.fill(eventDate);
    console.log(`Filled in start date: ${eventDate}`);

    await startTimeSelect.fill(eventTime); // Fill time input directly
    console.log(`Filled in start time: ${eventTime}`);

    await endDateField.fill(eventDate); // Assuming same end date
    console.log(`Filled in end date: ${eventDate}`);

    await endTimeSelect.fill('12:00'); // Example end time
    console.log('Filled in end time.');

    await publishButton.click();
    console.log('Clicked Publish button.');

    // --- Enhanced Diagnostics after Submission ---
    // 1. Wait for network to be idle
    await page.waitForLoadState('networkidle', { timeout: 15000 });

    // 2. Log current URL after clicking publish
    const postPublishUrl = page.url();
    console.log('URL after clicking Publish:', postPublishUrl);

    // 3. Capture error and notice messages
    const errorNotice = page.locator('.tribe-community-notice.tribe-error, .notice-error, .event-error, .tribe-error, .notice, .tribe-community-notice');
    const successNotice = page.locator('.tribe-community-notice, .notice-success, .event-success, .updated, .tribe-message');
    let errorMessages: string[] = [];
    let successMessages: string[] = [];
    let errorVisible = false;
    let successVisible = false;

    try {
      await expect(errorNotice).toBeVisible({ timeout: 5000 });
      errorVisible = true;
      errorMessages = await errorNotice.allTextContents();
      console.log('Error notice(s) visible after publishing:', errorMessages);
    } catch (e) {
      console.log('No visible error notices after publishing.');
    }

    try {
      await expect(successNotice).toBeVisible({ timeout: 10000 });
      successVisible = true;
      successMessages = await successNotice.allTextContents();
      console.log('Success notice(s) visible after publishing:', successMessages);
    } catch (e) {
      console.log('No visible success notice after publishing.');
    }

    // 4. Capture page HTML after submission
    const postSubmitHtml = await page.content();
    const postSubmitDebug = {
      timestamp: new Date().toISOString(),
      url: postPublishUrl,
      errorVisible,
      errorMessages,
      successVisible,
      successMessages,
      html: postSubmitHtml
    };
    fs.writeFileSync(
      'test-results/debug-after-publish.json',
      JSON.stringify(postSubmitDebug, null, 2),
      { encoding: 'utf8' }
    );
    await page.screenshot({ path: 'test-results/event-created-after-submit.png', fullPage: true });

    // 5. Capture browser console logs
    // (consoleLogs array is already being filled above)
    fs.writeFileSync(
      'test-results/console-logs-after-publish.json',
      JSON.stringify(consoleLogs, null, 2),
      { encoding: 'utf8' }
    );

    // 6. Capture network response for the form submission (added for diagnosis)
    const networkLogs = [];
    const networkListener = async (response) => {
      try {
        const req = response.request();
        if (
          req.method() === 'POST' &&
          req.url().includes('/manage-event')
        ) {
          const body = await response.text();
          networkLogs.push({
            url: req.url(),
            status: response.status(),
            statusText: response.statusText(),
            requestHeaders: req.headers(),
            postData: req.postData(),
            responseHeaders: response.headers(),
            body: body,
          });
        }
      } catch (err) {
        networkLogs.push({ error: err.message });
      }
    };
    page.on('response', networkListener);

    // --- DEBUG LOGGING ADDED FOR DIAGNOSIS ---
    // Log the actual post-submission URL
    console.log('DEBUG: postPublishUrl:', postPublishUrl);

    // Log the value of successVisible
    console.log('DEBUG: successVisible:', successVisible);

    // Log the DOM content after submission
    const domContent = await page.content();
    require('fs').writeFileSync(
      'test-results/dom-content-after-publish.html',
      domContent,
      { encoding: 'utf8' }
    );
    console.log('DEBUG: DOM content after publish written to test-results/dom-content-after-publish.html');

    // Log any visible notices (success/error)
    const notices = await page.$$eval(
      '.tribe-community-notice, .notice-success, .event-success, .updated, .tribe-message, .tribe-community-notice.tribe-error, .notice-error, .event-error, .tribe-error, .notice',
      els => els.map(el => el.textContent)
    );
    console.log('DEBUG: Notices found after publish:', notices);

    // Assert: Either redirected to event page or success notice is visible
    // --- New: After submission, follow "View Your Submitted Events" and check for the new event ---
    // Try to find and click the "View Your Submitted Events" link
    const submittedEventsLink = page.locator('a', { hasText: 'View Your Submitted Events' });
    await expect(submittedEventsLink).toBeVisible({ timeout: 10000 });
    await submittedEventsLink.click();
    // Wait for navigation to the submitted events list
    await page.waitForLoadState('networkidle');
    // Assert the new event appears in the list
    await expect(page.locator('body')).toContainText(eventTitle);

    // --- End Create Event Steps ---
    // Write network logs after test
    fs.writeFileSync(
      'test-results/event-form-network-response.json',
      JSON.stringify(networkLogs, null, 2),
      { encoding: 'utf8' }
    );
    page.off('response', networkListener);
  });
});
