const { chromium } = require('playwright');
const fs = require('fs').promises;
const path = require('path');

// Configuration
const BASE_URL = process.env.UPSKILL_STAGING_URL || 'https://upskill-staging.measurequick.com';
const HEADLESS = process.env.HEADLESS !== 'false';
const TIMEOUT = 30000;

// Test Credentials
const TEST_ACCOUNTS = {
  trainer: {
    username: 'test_trainer',
    password: 'TestTrainer123!',
    email: 'test_trainer@example.com'
  },
  master: {
    username: 'test_master', 
    password: 'TestMaster123!',
    email: 'test_master@example.com'
  },
  joe_master: {
    username: 'JoeMedosch@gmail.com',
    password: 'JoeTrainer2025@',
    email: 'JoeMedosch@gmail.com'
  },
  new_user: {
    username: `test_user_${Date.now()}`,
    email: `test_${Date.now()}@example.com`,
    password: 'Test@Pass123!'
  }
};

// Test Results Tracking
class TestResults {
  constructor() {
    this.results = [];
    this.passed = 0;
    this.failed = 0;
    this.skipped = 0;
    this.startTime = Date.now();
  }

  add(name, status, details = '', screenshot = null) {
    const result = {
      name,
      status,
      details,
      screenshot,
      timestamp: new Date().toISOString()
    };
    this.results.push(result);
    
    if (status === 'PASS') {
      this.passed++;
      console.log(`✅ ${name}`);
    } else if (status === 'FAIL') {
      this.failed++;
      console.log(`❌ ${name}`);
    } else if (status === 'SKIP') {
      this.skipped++;
      console.log(`⏭️  ${name}`);
    }
    
    if (details) {
      console.log(`   ${details}`);
    }
  }

  async generateReport() {
    const duration = Math.round((Date.now() - this.startTime) / 1000);
    const total = this.passed + this.failed + this.skipped;
    const successRate = total > 0 ? Math.round((this.passed / total) * 100) : 0;

    const report = {
      summary: {
        total,
        passed: this.passed,
        failed: this.failed,
        skipped: this.skipped,
        successRate: `${successRate}%`,
        duration: `${duration}s`,
        timestamp: new Date().toISOString()
      },
      results: this.results
    };

    // Save JSON report
    await fs.writeFile(
      `test-results-${Date.now()}.json`,
      JSON.stringify(report, null, 2)
    );

    // Print summary
    console.log('\n' + '='.repeat(60));
    console.log('📊 TEST EXECUTION SUMMARY');
    console.log('='.repeat(60));
    console.log(`Total Tests: ${total}`);
    console.log(`✅ Passed: ${this.passed}`);
    console.log(`❌ Failed: ${this.failed}`);
    console.log(`⏭️  Skipped: ${this.skipped}`);
    console.log(`Success Rate: ${successRate}%`);
    console.log(`Duration: ${duration} seconds`);
    
    if (this.failed > 0) {
      console.log('\n❌ Failed Tests:');
      this.results.filter(r => r.status === 'FAIL').forEach(r => {
        console.log(`  - ${r.name}`);
        if (r.details) console.log(`    ${r.details}`);
      });
    }

    return report;
  }
}

// Test Suite Class
class HVACTestSuite {
  constructor() {
    this.browser = null;
    this.context = null;
    this.page = null;
    this.results = new TestResults();
    this.screenshotDir = 'test-screenshots';
    this.currentUser = null;
  }

  async setup() {
    console.log('🚀 Initializing HVAC E2E Test Suite');
    console.log(`📍 Target: ${BASE_URL}`);
    console.log(`🖥️  Mode: ${HEADLESS ? 'Headless' : 'Headed'}`);
    console.log('='.repeat(60) + '\n');

    // Create screenshot directory
    await fs.mkdir(this.screenshotDir, { recursive: true });

    // Launch browser
    this.browser = await chromium.launch({ 
      headless: HEADLESS,
      timeout: TIMEOUT
    });
    
    this.context = await this.browser.newContext({
      viewport: { width: 1920, height: 1080 },
      userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
    });
    
    this.page = await this.context.newPage();
    this.page.setDefaultTimeout(TIMEOUT);
  }

  async teardown() {
    if (this.browser) {
      await this.browser.close();
    }
    await this.results.generateReport();
  }

  async takeScreenshot(name) {
    const filename = `${this.screenshotDir}/${name}-${Date.now()}.png`;
    try {
      await this.page.screenshot({ 
        path: filename, 
        fullPage: true 
      });
      return filename;
    } catch (error) {
      console.error(`Failed to take screenshot: ${error.message}`);
      return null;
    }
  }

  async waitAndCheck(selector, timeout = 5000) {
    try {
      await this.page.waitForSelector(selector, { timeout });
      return true;
    } catch {
      return false;
    }
  }

  // ========== TEST: Find a Trainer ==========
  async testFindTrainer() {
    console.log('\n🗺️  Testing Find a Trainer Feature');
    console.log('-'.repeat(40));

    try {
      await this.page.goto(`${BASE_URL}/find-a-trainer/`);
      await this.page.waitForLoadState('networkidle');

      // Check page title
      const title = await this.page.title();
      this.results.add(
        'Find Trainer - Page Loads',
        title.includes('Find') || title.includes('Trainer') ? 'PASS' : 'FAIL',
        `Page title: ${title}`
      );

      // Check for map container
      const hasMap = await this.waitAndCheck('#mapgeo-map-5872, .mapgeo-map, #map');
      this.results.add(
        'Find Trainer - Map Container',
        hasMap ? 'PASS' : 'FAIL',
        hasMap ? 'Map container found' : 'Map container not found'
      );

      // Check for filter section
      const hasFilters = await this.waitAndCheck('.hvac-trainer-filters, .trainer-filters, .filter-section');
      this.results.add(
        'Find Trainer - Filter Section',
        hasFilters ? 'PASS' : 'FAIL'
      );

      // Check for trainer cards
      const hasTrainerCards = await this.waitAndCheck('.trainer-card, .hvac-trainer-card, .trainer-profile');
      this.results.add(
        'Find Trainer - Trainer Cards',
        hasTrainerCards ? 'PASS' : 'FAIL'
      );

      await this.takeScreenshot('find-trainer');

    } catch (error) {
      this.results.add(
        'Find Trainer - Feature Test',
        'FAIL',
        error.message
      );
    }
  }

  // ========== TEST: Registration ==========
  async testRegistration() {
    console.log('\n📝 Testing Registration Flow');
    console.log('-'.repeat(40));

    try {
      await this.page.goto(`${BASE_URL}/trainer/registration/`);
      await this.page.waitForLoadState('networkidle');

      // Check registration form sections
      const sections = [
        { name: 'Personal Information', selector: 'h3:has-text("Personal Information")' },
        { name: 'Training Organization', selector: 'h3:has-text("Training Organization")' },
        { name: 'Training Venue', selector: 'h3:has-text("Training Venue")' },
        { name: 'Organization Logo', selector: 'label:has-text("Organization Logo")' }
      ];

      for (const section of sections) {
        const exists = await this.waitAndCheck(section.selector);
        this.results.add(
          `Registration - ${section.name}`,
          exists ? 'PASS' : 'FAIL'
        );
      }

      // Test form field interactions
      const testData = TEST_ACCOUNTS.new_user;
      
      // Fill Personal Information
      const filled = await this.fillRegistrationForm(testData);
      this.results.add(
        'Registration - Form Fill',
        filled ? 'PASS' : 'FAIL',
        filled ? 'Form filled successfully' : 'Failed to fill form'
      );

      await this.takeScreenshot('registration-form');

    } catch (error) {
      this.results.add(
        'Registration - Flow Test',
        'FAIL',
        error.message
      );
    }
  }

  async fillRegistrationForm(data) {
    try {
      // Personal Information
      await this.page.fill('#first_name', 'Test');
      await this.page.fill('#last_name', 'User');
      await this.page.fill('#email', data.email);
      await this.page.fill('#phone', '555-123-4567');

      // Training Organization
      await this.page.fill('#business_name', 'Test HVAC Company');
      await this.page.fill('#business_email', data.email);
      
      // Select Business Type
      const businessTypeExists = await this.waitAndCheck('#business_type');
      if (businessTypeExists) {
        await this.page.selectOption('#business_type', 'Training Organization');
      }

      // Organization Headquarters
      const countryExists = await this.waitAndCheck('#hq_country');
      if (countryExists) {
        await this.page.selectOption('#hq_country', 'United States');
        await this.page.waitForTimeout(1000); // Wait for state dropdown to populate
        
        const stateExists = await this.waitAndCheck('#hq_state');
        if (stateExists) {
          await this.page.selectOption('#hq_state', 'TX');
        }
      }

      await this.page.fill('#hq_city', 'Dallas');

      return true;
    } catch (error) {
      console.error('Form fill error:', error.message);
      return false;
    }
  }

  // ========== TEST: Login ==========
  async testLogin() {
    console.log('\n🔐 Testing Login Functionality');
    console.log('-'.repeat(40));

    try {
      await this.page.goto(`${BASE_URL}/training-login/`);
      await this.page.waitForLoadState('networkidle');

      // Check login form
      const hasLoginForm = await this.waitAndCheck('#loginform, .login-form');
      this.results.add(
        'Login - Form Present',
        hasLoginForm ? 'PASS' : 'FAIL'
      );

      // Perform login
      await this.page.fill('#user_login', TEST_ACCOUNTS.trainer.username);
      await this.page.fill('#user_pass', TEST_ACCOUNTS.trainer.password);
      
      await this.takeScreenshot('login-form');
      
      await this.page.click('#wp-submit');
      await this.page.waitForLoadState('networkidle');
      await this.page.waitForTimeout(2000);

      // Check if redirected to dashboard
      const url = this.page.url();
      const loginSuccess = url.includes('/trainer/') || url.includes('dashboard');
      
      this.results.add(
        'Login - Authentication',
        loginSuccess ? 'PASS' : 'FAIL',
        `Redirected to: ${url}`
      );

      if (loginSuccess) {
        this.currentUser = TEST_ACCOUNTS.trainer;
        await this.takeScreenshot('dashboard-after-login');
      }

    } catch (error) {
      this.results.add(
        'Login - Test',
        'FAIL',
        error.message
      );
    }
  }

  // ========== TEST: Event Creation ==========
  async testEventCreation() {
    console.log('\n🎯 Testing Event Creation');
    console.log('-'.repeat(40));

    // Ensure logged in
    if (!this.currentUser) {
      await this.ensureLoggedIn(TEST_ACCOUNTS.trainer);
    }

    try {
      await this.page.goto(`${BASE_URL}/trainer/event/manage/`);
      await this.page.waitForLoadState('networkidle');

      // Check for event management page
      const hasEventPage = await this.waitAndCheck('.tribe-community-events, .hvac-event-manage, #tribe-events-community-form');
      this.results.add(
        'Event Creation - Management Page',
        hasEventPage ? 'PASS' : 'FAIL'
      );

      // Look for create event button/link
      const createEventLink = await this.page.$('a:has-text("Create Event"), a:has-text("Add Event"), button:has-text("New Event")');
      if (createEventLink) {
        await createEventLink.click();
        await this.page.waitForLoadState('networkidle');
      }

      // Check for event form fields
      const eventFields = [
        { name: 'Event Title', selector: 'input[name*="title"], #EventTitle, input[name="post_title"]' },
        { name: 'Event Description', selector: 'textarea[name*="description"], #EventDescription, .wp-editor-area' },
        { name: 'Event Date', selector: 'input[name*="EventStartDate"], input[type="date"], .tribe-datepicker' },
        { name: 'Event Venue', selector: 'select[name*="venue"], #saved_tribe_venue, input[name*="Venue"]' }
      ];

      for (const field of eventFields) {
        const exists = await this.waitAndCheck(field.selector, 3000);
        this.results.add(
          `Event Creation - ${field.name}`,
          exists ? 'PASS' : 'FAIL'
        );
      }

      await this.takeScreenshot('event-creation-form');

      // Try to fill basic event data
      const titleField = await this.page.$('input[name*="title"], #EventTitle, input[name="post_title"]');
      if (titleField) {
        await titleField.fill(`Test Event ${Date.now()}`);
        this.results.add(
          'Event Creation - Fill Title',
          'PASS'
        );
      }

    } catch (error) {
      this.results.add(
        'Event Creation - Test',
        'FAIL',
        error.message
      );
    }
  }

  // ========== TEST: Event Editing ==========
  async testEventEditing() {
    console.log('\n✏️  Testing Event Editing');
    console.log('-'.repeat(40));

    if (!this.currentUser) {
      await this.ensureLoggedIn(TEST_ACCOUNTS.trainer);
    }

    try {
      // Navigate to event list/manage page
      await this.page.goto(`${BASE_URL}/trainer/event/manage/`);
      await this.page.waitForLoadState('networkidle');

      // Look for edit links
      const editLink = await this.page.$('a:has-text("Edit"), .edit-event, a[href*="edit"]');
      
      if (editLink) {
        await editLink.click();
        await this.page.waitForLoadState('networkidle');
        
        const hasEditForm = await this.waitAndCheck('form, .edit-event-form, #tribe-events-community-form');
        this.results.add(
          'Event Edit - Form Access',
          hasEditForm ? 'PASS' : 'FAIL'
        );

        await this.takeScreenshot('event-edit-form');
      } else {
        this.results.add(
          'Event Edit - No Events',
          'SKIP',
          'No events available to edit'
        );
      }

    } catch (error) {
      this.results.add(
        'Event Edit - Test',
        'FAIL',
        error.message
      );
    }
  }

  // ========== TEST: Certificate Generation ==========
  async testCertificateGeneration() {
    console.log('\n📜 Testing Certificate Generation');
    console.log('-'.repeat(40));

    if (!this.currentUser) {
      await this.ensureLoggedIn(TEST_ACCOUNTS.trainer);
    }

    try {
      await this.page.goto(`${BASE_URL}/trainer/generate-certificates/`);
      await this.page.waitForLoadState('networkidle');

      // Check certificate page
      const hasCertPage = await this.waitAndCheck('.hvac-generate-certificates, .certificate-generator, #certificate-form');
      this.results.add(
        'Certificates - Page Access',
        hasCertPage ? 'PASS' : 'FAIL'
      );

      // Check for event selection
      const hasEventSelect = await this.waitAndCheck('select[name*="event"], #event_id, .event-select');
      this.results.add(
        'Certificates - Event Selection',
        hasEventSelect ? 'PASS' : 'FAIL'
      );

      // Check for generate button
      const hasGenerateBtn = await this.waitAndCheck('button:has-text("Generate"), input[type="submit"], .generate-certificates-btn');
      this.results.add(
        'Certificates - Generate Button',
        hasGenerateBtn ? 'PASS' : 'FAIL'
      );

      await this.takeScreenshot('certificate-generation');

      // Also check certificate reports
      await this.page.goto(`${BASE_URL}/trainer/certificate-reports/`);
      await this.page.waitForLoadState('networkidle');

      const hasReports = await this.waitAndCheck('.hvac-certificate-reports, .certificate-reports, table');
      this.results.add(
        'Certificates - Reports Page',
        hasReports ? 'PASS' : 'FAIL'
      );

    } catch (error) {
      this.results.add(
        'Certificates - Test',
        'FAIL',
        error.message
      );
    }
  }

  // ========== TEST: Master Trainer Features ==========
  async testMasterTrainerFeatures() {
    console.log('\n👑 Testing Master Trainer Features');
    console.log('-'.repeat(40));

    // Login as master trainer
    await this.logout();
    await this.ensureLoggedIn(TEST_ACCOUNTS.master);

    try {
      // Test master dashboard
      await this.page.goto(`${BASE_URL}/master-trainer/master-dashboard/`);
      await this.page.waitForLoadState('networkidle');

      const hasMasterDash = await this.waitAndCheck('.hvac-master-dashboard, .master-dashboard-content');
      this.results.add(
        'Master - Dashboard Access',
        hasMasterDash ? 'PASS' : 'FAIL'
      );

      // Test master pages
      const masterPages = [
        { name: 'Events Overview', url: '/master-trainer/events/' },
        { name: 'Pending Approvals', url: '/master-trainer/pending-approvals/' },
        { name: 'Import/Export', url: '/master-trainer/import-export/' }
      ];

      for (const page of masterPages) {
        await this.page.goto(`${BASE_URL}${page.url}`);
        await this.page.waitForLoadState('networkidle');
        
        const isAccessible = !this.page.url().includes('login');
        this.results.add(
          `Master - ${page.name}`,
          isAccessible ? 'PASS' : 'FAIL'
        );
      }

      await this.takeScreenshot('master-dashboard');

    } catch (error) {
      this.results.add(
        'Master Features - Test',
        'FAIL',
        error.message
      );
    }
  }

  // ========== Helper Methods ==========
  async ensureLoggedIn(account) {
    try {
      // Check if already logged in
      await this.page.goto(`${BASE_URL}/trainer/dashboard/`, { waitUntil: 'networkidle' });
      
      if (this.page.url().includes('login')) {
        // Not logged in, perform login
        await this.page.fill('#user_login', account.username);
        await this.page.fill('#user_pass', account.password);
        await this.page.click('#wp-submit');
        await this.page.waitForLoadState('networkidle');
        await this.page.waitForTimeout(2000);
      }
      
      this.currentUser = account;
    } catch (error) {
      console.error('Login error:', error.message);
    }
  }

  async logout() {
    try {
      await this.page.goto(`${BASE_URL}/wp-login.php?action=logout`, { waitUntil: 'networkidle' });
      const logoutLink = await this.page.$('a:has-text("log out"), a:has-text("Log out")');
      if (logoutLink) {
        await logoutLink.click();
      }
      this.currentUser = null;
    } catch (error) {
      console.error('Logout error:', error.message);
    }
  }

  // ========== Main Test Runner ==========
  async runAllTests() {
    await this.setup();

    try {
      // Public Features
      await this.testFindTrainer();
      await this.testRegistration();

      // Trainer Features
      await this.testLogin();
      await this.testEventCreation();
      await this.testEventEditing();
      await this.testCertificateGeneration();

      // Master Trainer Features
      await this.testMasterTrainerFeatures();

    } catch (error) {
      console.error('Test suite error:', error);
    } finally {
      await this.teardown();
    }
  }
}

// Execute Tests
async function main() {
  console.log('\n🏁 HVAC Community Events - Comprehensive E2E Test Suite\n');
  
  const suite = new HVACTestSuite();
  await suite.runAllTests();
  
  process.exit(suite.results.failed > 0 ? 1 : 0);
}

main().catch(console.error);