// @ts-check
const { test, expect } = require('@playwright/test');

/**
 * E2E Tests for HVAC Trainer Announcements System
 * 
 * Tests the complete user journey for:
 * - Master trainers creating and managing announcements
 * - Regular trainers viewing announcements
 * - Email notifications
 * - Security and permissions
 */

// Test configuration
const BASE_URL = process.env.UPSKILL_STAGING_URL || 'https://upskill-staging.measurequick.com';
const ADMIN_USER = process.env.STAGING_ADMIN_USER || 'benr';
const ADMIN_PASS = process.env.STAGING_ADMIN_PASS || 'Xy8$kP#mN2@Lq9Z!';

// Test users
const MASTER_TRAINER = {
  username: 'JoeMedosch@gmail.com',
  password: 'JoeTrainer2025@',
  displayName: 'Joe Medosch'
};

const REGULAR_TRAINER = {
  username: 'test_trainer',
  password: 'TestTrainer123!',
  displayName: 'Test Trainer'
};

// Helper function to login
async function loginAsUser(page, username, password) {
  await page.goto(`${BASE_URL}/wp-login.php`);
  await page.fill('#user_login', username);
  await page.fill('#user_pass', password);
  await page.click('#wp-submit');
  await page.waitForURL(/\/wp-admin|\/trainer\//);
}

// Helper function to navigate to trainer page
async function navigateToTrainerPage(page, path) {
  await page.goto(`${BASE_URL}/trainer/${path}/`);
  await page.waitForLoadState('networkidle');
}

test.describe('HVAC Announcements - Master Trainer Features', () => {
  test.beforeEach(async ({ page }) => {
    await loginAsUser(page, MASTER_TRAINER.username, MASTER_TRAINER.password);
  });

  test('Master trainer can access announcements management page', async ({ page }) => {
    // Navigate to master announcements page
    await navigateToTrainerPage(page, 'master-trainer/manage-announcements');
    
    // Verify page loaded
    await expect(page.locator('h1')).toContainText('Manage Announcements');
    
    // Verify admin interface elements
    await expect(page.locator('#announcements-admin-container')).toBeVisible();
    await expect(page.locator('.announcement-header')).toBeVisible();
    await expect(page.locator('#announcement-list')).toBeVisible();
    
    // Verify action buttons
    await expect(page.locator('#new-announcement-btn')).toBeVisible();
    await expect(page.locator('#new-announcement-btn')).toHaveText('New Announcement');
  });

  test('Master trainer can create a new announcement', async ({ page }) => {
    await navigateToTrainerPage(page, 'master-trainer/manage-announcements');
    
    // Click new announcement button
    await page.click('#new-announcement-btn');
    
    // Wait for form to appear
    await expect(page.locator('#announcement-form')).toBeVisible();
    
    // Fill in announcement details
    const testTitle = `E2E Test Announcement ${Date.now()}`;
    const testContent = 'This is a test announcement created by Playwright E2E tests.';
    const testExcerpt = 'Test excerpt for E2E';
    
    await page.fill('#announcement-title', testTitle);
    
    // Handle rich text editor (TinyMCE or plain textarea)
    const editorFrame = page.frameLocator('#announcement-content_ifr');
    const hasIframe = await editorFrame.locator('body').count() > 0;
    
    if (hasIframe) {
      // TinyMCE editor
      await editorFrame.locator('body').fill(testContent);
    } else {
      // Plain textarea
      await page.fill('#announcement-content', testContent);
    }
    
    await page.fill('#announcement-excerpt', testExcerpt);
    
    // Select status
    await page.selectOption('#announcement-status', 'draft');
    
    // Add categories (if available)
    const categoryCheckboxes = await page.locator('.category-checkbox').count();
    if (categoryCheckboxes > 0) {
      await page.locator('.category-checkbox').first().check();
    }
    
    // Add tags
    await page.fill('#announcement-tags', 'e2e-test, playwright, automated');
    
    // Save announcement
    await page.click('#save-announcement-btn');
    
    // Wait for success message
    await expect(page.locator('.notice-success')).toBeVisible({ timeout: 10000 });
    await expect(page.locator('.notice-success')).toContainText(/created|saved|success/i);
    
    // Verify announcement appears in list
    await expect(page.locator('#announcement-list')).toContainText(testTitle);
  });

  test('Master trainer can edit an existing announcement', async ({ page }) => {
    await navigateToTrainerPage(page, 'master-trainer/manage-announcements');
    
    // Wait for announcements to load
    await page.waitForSelector('.announcement-item', { timeout: 10000 });
    
    // Click edit on first announcement
    const firstAnnouncement = page.locator('.announcement-item').first();
    await firstAnnouncement.locator('.edit-announcement').click();
    
    // Wait for form to load with data
    await expect(page.locator('#announcement-form')).toBeVisible();
    await expect(page.locator('#announcement-title')).not.toBeEmpty();
    
    // Edit the title
    const currentTitle = await page.locator('#announcement-title').inputValue();
    const updatedTitle = currentTitle + ' (Updated)';
    await page.fill('#announcement-title', updatedTitle);
    
    // Update status to publish
    await page.selectOption('#announcement-status', 'publish');
    
    // Save changes
    await page.click('#save-announcement-btn');
    
    // Wait for success message
    await expect(page.locator('.notice-success')).toBeVisible({ timeout: 10000 });
    
    // Verify updated title in list
    await expect(page.locator('#announcement-list')).toContainText(updatedTitle);
  });

  test('Master trainer can delete an announcement', async ({ page }) => {
    await navigateToTrainerPage(page, 'master-trainer/manage-announcements');
    
    // Wait for announcements to load
    await page.waitForSelector('.announcement-item', { timeout: 10000 });
    
    // Count initial announcements
    const initialCount = await page.locator('.announcement-item').count();
    
    // Find an announcement with "E2E Test" in title (if exists)
    const testAnnouncements = page.locator('.announcement-item:has-text("E2E Test")');
    const hasTestAnnouncement = await testAnnouncements.count() > 0;
    
    if (hasTestAnnouncement) {
      // Click delete on test announcement
      await testAnnouncements.first().locator('.delete-announcement').click();
      
      // Confirm deletion
      page.on('dialog', dialog => dialog.accept());
      
      // Wait for announcement to be removed
      await expect(page.locator('.notice-success')).toBeVisible({ timeout: 10000 });
      
      // Verify count decreased
      const newCount = await page.locator('.announcement-item').count();
      expect(newCount).toBeLessThan(initialCount);
    }
  });

  test('Master trainer can filter announcements by status', async ({ page }) => {
    await navigateToTrainerPage(page, 'master-trainer/manage-announcements');
    
    // Wait for filter controls
    await expect(page.locator('#announcement-status-filter')).toBeVisible();
    
    // Filter by published
    await page.selectOption('#announcement-status-filter', 'publish');
    await page.waitForTimeout(1000); // Wait for filter to apply
    
    // Verify only published announcements shown
    const statusBadges = await page.locator('.status-badge').allTextContents();
    statusBadges.forEach(status => {
      expect(status.toLowerCase()).toContain('publish');
    });
    
    // Filter by draft
    await page.selectOption('#announcement-status-filter', 'draft');
    await page.waitForTimeout(1000);
    
    // Verify only draft announcements shown (if any)
    const draftBadges = await page.locator('.status-badge').allTextContents();
    if (draftBadges.length > 0) {
      draftBadges.forEach(status => {
        expect(status.toLowerCase()).toContain('draft');
      });
    }
  });

  test('Master trainer can search announcements', async ({ page }) => {
    await navigateToTrainerPage(page, 'master-trainer/manage-announcements');
    
    // Wait for search box
    await expect(page.locator('#announcement-search')).toBeVisible();
    
    // Search for specific term
    await page.fill('#announcement-search', 'training');
    await page.press('#announcement-search', 'Enter');
    
    // Wait for search results
    await page.waitForTimeout(1000);
    
    // Verify search results contain search term (if any results)
    const searchResults = await page.locator('.announcement-item').count();
    if (searchResults > 0) {
      const titles = await page.locator('.announcement-title').allTextContents();
      const contents = await page.locator('.announcement-excerpt').allTextContents();
      
      const allText = [...titles, ...contents].join(' ').toLowerCase();
      expect(allText).toContain('training');
    }
  });
});

test.describe('HVAC Announcements - Regular Trainer Features', () => {
  test.beforeEach(async ({ page }) => {
    await loginAsUser(page, REGULAR_TRAINER.username, REGULAR_TRAINER.password);
  });

  test('Regular trainer can view announcements on resources page', async ({ page }) => {
    // Navigate to resources page
    await navigateToTrainerPage(page, 'resources');
    
    // Verify page loaded
    await expect(page.locator('h1')).toContainText('Training Resources');
    
    // Verify announcements timeline is visible
    await expect(page.locator('.hvac-announcements-timeline')).toBeVisible();
    
    // Verify at least one announcement is displayed (if any published)
    const announcementCount = await page.locator('.timeline-item').count();
    if (announcementCount > 0) {
      // Verify announcement structure
      await expect(page.locator('.timeline-item').first()).toBeVisible();
      await expect(page.locator('.timeline-title').first()).toBeVisible();
      await expect(page.locator('.timeline-date').first()).toBeVisible();
      await expect(page.locator('.timeline-excerpt').first()).toBeVisible();
    }
  });

  test('Regular trainer can click to view announcement details', async ({ page }) => {
    await navigateToTrainerPage(page, 'resources');
    
    // Wait for announcements to load
    const announcements = await page.locator('.announcement-link').count();
    
    if (announcements > 0) {
      // Click first announcement
      await page.locator('.announcement-link').first().click();
      
      // Wait for modal to appear
      await expect(page.locator('#announcement-modal')).toBeVisible();
      await expect(page.locator('.modal-content')).toBeVisible();
      
      // Verify modal content
      await expect(page.locator('.announcement-full')).toBeVisible();
      await expect(page.locator('.announcement-header h2')).toBeVisible();
      await expect(page.locator('.announcement-content')).toBeVisible();
      
      // Close modal
      await page.locator('.modal-close').click();
      await expect(page.locator('#announcement-modal')).not.toBeVisible();
    }
  });

  test('Regular trainer cannot access management page', async ({ page }) => {
    // Try to access master announcements page
    const response = await page.goto(`${BASE_URL}/trainer/master-trainer/manage-announcements/`);
    
    // Should be redirected or show error
    expect(response.status()).not.toBe(200);
    
    // Verify error message or redirect
    const url = page.url();
    expect(url).not.toContain('/manage-announcements');
  });

  test('Regular trainer can use load more functionality', async ({ page }) => {
    await navigateToTrainerPage(page, 'resources');
    
    // Check if load more button exists
    const hasLoadMore = await page.locator('.load-more-announcements').count() > 0;
    
    if (hasLoadMore) {
      // Count initial announcements
      const initialCount = await page.locator('.timeline-item').count();
      
      // Click load more
      await page.click('.load-more-announcements');
      
      // Wait for new announcements to load
      await page.waitForTimeout(2000);
      
      // Verify more announcements loaded
      const newCount = await page.locator('.timeline-item').count();
      expect(newCount).toBeGreaterThan(initialCount);
    }
  });

  test('Regular trainer can view Google Drive resources', async ({ page }) => {
    await navigateToTrainerPage(page, 'resources');
    
    // Check if Google Drive embed exists
    const hasDriveEmbed = await page.locator('.hvac-google-drive-embed').count() > 0;
    
    if (hasDriveEmbed) {
      // Verify iframe is present
      await expect(page.locator('.hvac-google-drive-embed iframe')).toBeVisible();
      
      // Verify iframe has correct attributes
      const iframe = page.locator('.hvac-google-drive-embed iframe');
      await expect(iframe).toHaveAttribute('src', /drive\.google\.com/);
    }
  });
});

test.describe('HVAC Announcements - Security and Permissions', () => {
  test('Unauthenticated user cannot access announcements', async ({ page }) => {
    // Try to access resources page without login
    await page.goto(`${BASE_URL}/trainer/resources/`);
    
    // Should be redirected to login
    await expect(page).toHaveURL(/wp-login\.php/);
  });

  test('Subscriber cannot view announcements', async ({ page }) => {
    // Create or use a subscriber account
    // This would need a subscriber test account to be set up
    // For now, we'll test that non-trainer roles are blocked
    
    // Attempt to access resources page directly
    const response = await page.goto(`${BASE_URL}/trainer/resources/`);
    
    // Should not have access
    if (response.ok()) {
      // If page loads, verify no announcements shown
      const hasPermissionError = await page.locator(':text("You do not have permission")').count() > 0;
      expect(hasPermissionError).toBeTruthy();
    }
  });

  test('XSS prevention in announcement content', async ({ page }) => {
    await loginAsUser(page, MASTER_TRAINER.username, MASTER_TRAINER.password);
    await navigateToTrainerPage(page, 'master-trainer/manage-announcements');
    
    // Create announcement with potential XSS
    await page.click('#new-announcement-btn');
    await page.fill('#announcement-title', 'XSS Test <script>alert("XSS")</script>');
    await page.fill('#announcement-content', '<img src=x onerror="alert(\'XSS\')">Test content');
    await page.fill('#announcement-excerpt', '<script>alert("XSS")</script>Excerpt');
    await page.selectOption('#announcement-status', 'publish');
    await page.click('#save-announcement-btn');
    
    // Wait for save
    await page.waitForTimeout(2000);
    
    // Now view as regular trainer
    await loginAsUser(page, REGULAR_TRAINER.username, REGULAR_TRAINER.password);
    await navigateToTrainerPage(page, 'resources');
    
    // Verify no script execution
    page.on('dialog', dialog => {
      // Fail test if any alert appears
      expect(dialog.message()).not.toContain('XSS');
      dialog.dismiss();
    });
    
    // Check that dangerous content is escaped
    const pageContent = await page.content();
    expect(pageContent).not.toContain('<script>alert');
    expect(pageContent).not.toContain('onerror=');
  });
});

test.describe('HVAC Announcements - Responsive Design', () => {
  [
    { name: 'Mobile', width: 375, height: 667 },
    { name: 'Tablet', width: 768, height: 1024 },
    { name: 'Desktop', width: 1920, height: 1080 }
  ].forEach(({ name, width, height }) => {
    test(`Announcements display correctly on ${name}`, async ({ page }) => {
      // Set viewport
      await page.setViewportSize({ width, height });
      
      await loginAsUser(page, REGULAR_TRAINER.username, REGULAR_TRAINER.password);
      await navigateToTrainerPage(page, 'resources');
      
      // Verify timeline is responsive
      await expect(page.locator('.hvac-announcements-timeline')).toBeVisible();
      
      // Check if elements stack properly on mobile
      if (width < 768) {
        // Mobile layout checks
        const timelineItems = await page.locator('.timeline-item').count();
        if (timelineItems > 0) {
          const item = page.locator('.timeline-item').first();
          const box = await item.boundingBox();
          expect(box.width).toBeLessThanOrEqual(width - 40); // Account for padding
        }
      }
      
      // Test modal on different screen sizes
      const hasAnnouncements = await page.locator('.announcement-link').count() > 0;
      if (hasAnnouncements) {
        await page.locator('.announcement-link').first().click();
        
        // Verify modal is responsive
        const modal = page.locator('.modal-content');
        await expect(modal).toBeVisible();
        
        const modalBox = await modal.boundingBox();
        expect(modalBox.width).toBeLessThanOrEqual(width);
        
        // Close modal
        await page.locator('.modal-close').click();
      }
    });
  });
});

test.describe('HVAC Announcements - Performance', () => {
  test('Announcements page loads within acceptable time', async ({ page }) => {
    const startTime = Date.now();
    
    await loginAsUser(page, REGULAR_TRAINER.username, REGULAR_TRAINER.password);
    await navigateToTrainerPage(page, 'resources');
    
    // Wait for main content to load
    await expect(page.locator('.hvac-announcements-timeline')).toBeVisible();
    
    const loadTime = Date.now() - startTime;
    
    // Page should load within 5 seconds
    expect(loadTime).toBeLessThan(5000);
  });

  test('Pagination loads efficiently', async ({ page }) => {
    await loginAsUser(page, REGULAR_TRAINER.username, REGULAR_TRAINER.password);
    await navigateToTrainerPage(page, 'resources');
    
    const hasLoadMore = await page.locator('.load-more-announcements').count() > 0;
    
    if (hasLoadMore) {
      const startTime = Date.now();
      
      // Click load more
      await page.click('.load-more-announcements');
      
      // Wait for new content
      await page.waitForTimeout(1000);
      
      const loadTime = Date.now() - startTime;
      
      // Additional content should load within 2 seconds
      expect(loadTime).toBeLessThan(2000);
    }
  });
});

test.describe('HVAC Announcements - Accessibility', () => {
  test('Announcements are keyboard navigable', async ({ page }) => {
    await loginAsUser(page, REGULAR_TRAINER.username, REGULAR_TRAINER.password);
    await navigateToTrainerPage(page, 'resources');
    
    // Tab through announcement links
    const announcements = await page.locator('.announcement-link').count();
    
    if (announcements > 0) {
      // Focus first announcement with Tab
      await page.keyboard.press('Tab');
      
      // Keep tabbing until we reach an announcement link
      for (let i = 0; i < 20; i++) {
        const focused = await page.evaluate(() => document.activeElement.className);
        if (focused.includes('announcement-link')) {
          break;
        }
        await page.keyboard.press('Tab');
      }
      
      // Press Enter to open modal
      await page.keyboard.press('Enter');
      
      // Verify modal opened
      await expect(page.locator('#announcement-modal')).toBeVisible();
      
      // Press Escape to close
      await page.keyboard.press('Escape');
      
      // Verify modal closed
      await expect(page.locator('#announcement-modal')).not.toBeVisible();
    }
  });

  test('Announcements have proper ARIA labels', async ({ page }) => {
    await loginAsUser(page, REGULAR_TRAINER.username, REGULAR_TRAINER.password);
    await navigateToTrainerPage(page, 'resources');
    
    // Check for ARIA attributes
    const hasAnnouncements = await page.locator('.timeline-item').count() > 0;
    
    if (hasAnnouncements) {
      // Check article elements have proper roles
      const articles = page.locator('.timeline-item');
      await expect(articles.first()).toHaveAttribute('role', 'article');
      
      // Check links have accessible text
      const link = page.locator('.announcement-link').first();
      const linkText = await link.textContent();
      expect(linkText).not.toBeEmpty();
    }
  });
});