/**
 * Buyer Group Management Test
 * 
 * Tags: @admin @p2 @regression @ui
 * 
 * Comprehensive functional testing of buyer group management:
 * - Buyer group CRUD operations (Create, Read, Update, Delete)
 * - Buyer group store management
 * - GLN validation and checking
 * - Status management and toggling
 * - Data validation and error handling
 */

import { test, expect } from '@playwright/test';
import { printTestCase, printSuccess, printWarning, waitForDataTable, ensureAuthenticated } from '../../helpers/test-helpers';

test.describe('04_Partner_Management - Buyer Group Management', () => {
  // Use authenticated state for all tests in this suite
  test.use({ storageState: 'auth.json' });

  const testBuyerName = `Test Buyer ${Date.now()}`;
  const testBuyerCode = `TB${Date.now()}`;
  const testGln = `123456789012${Date.now().toString().slice(-3)}`;
  
  let createdBuyerId: string | null = null;

  test.beforeEach(async ({ page }) => {
    // Ensure we're authenticated before navigating anywhere
    await ensureAuthenticated(page);
    
    console.log('\n🚀 Navigating to buyer group management page...');
    await page.goto('/buyer-group-management/buyers');
    await page.waitForLoadState('load');
    console.log('✅ Buyer group management page loaded');
  });

  test.afterEach(async ({ page }) => {
    // Cleanup: Delete test buyer if created
    if (createdBuyerId) {
      try {
        await page.goto('/buyer-group-management/buyers');
        await page.waitForLoadState('load');
        await waitForDataTable(page, 'table', 10000);
        
        // Look for test buyer and delete it
        const testBuyerRow = page.locator(`table tr:has-text("${testBuyerName}")`);
        if (await testBuyerRow.count() > 0) {
          const deleteBtn = testBuyerRow.locator('button:has-text("Delete"), button:has-text("Remove")');
          if (await deleteBtn.count() > 0) {
            await deleteBtn.click();
            await page.waitForTimeout(1000);
            
            // Confirm deletion if modal appears
            const confirmBtn = page.locator('.swal2-confirm, button:has-text("Yes"), button:has-text("Confirm")');
            if (await confirmBtn.count() > 0) {
              await confirmBtn.click();
              await page.waitForTimeout(2000);
            }
            console.log(`✅ Cleaned up test buyer: ${testBuyerName}`);
          }
        }
      } catch (e) {
        console.log(`⚠ Could not clean up test buyer: ${e}`);
      }
    }
  });

  test('Test Case 1: Navigate to buyer group management page', async ({ page }) => {
    printTestCase(1, 'Navigate to Buyer Group Management Page');
    
    const currentUrl = page.url();
    expect(currentUrl).toContain('/buyer-group-management/buyers');
    expect(currentUrl).not.toContain('/login');
    printSuccess('Buyer group management page accessible');
    
    const heading = page.locator('h1:has-text("Buying Groups")');
    await expect(heading).toBeVisible();
    printSuccess('Buying Groups heading visible');
    
    // Verify table is present
    const buyersTable = page.locator('table').first();
    await expect(buyersTable).toBeVisible();
    printSuccess('Buyers table visible');
    
    const createBtn = page.locator('a:has-text("Create New Buying Group")');
    await expect(createBtn).toBeVisible();
    printSuccess('Create New Buying Group button visible');
  });

  test('Test Case 2: Test buyers list page elements', async ({ page }) => {
    printTestCase(2, 'Test Buyers List Page Elements');
    
    // Wait for table to load
    try {
      await waitForDataTable(page, 'table', 15000);
    } catch (e) {
      console.log('⚠ Waiting for table with alternative approach');
      await page.waitForTimeout(3000);
    }
    
    const currentUrl = page.url();
    expect(currentUrl).toContain('/buyer-group-management/buyers');
    printSuccess('On buyers list page');
    
    const heading = page.locator('h1:has-text("Buying Groups")');
    await expect(heading).toBeVisible();
    printSuccess('Buying Groups heading visible');
    
    // Look for buyers table
    const buyersTable = page.locator('table').first();
    if (await buyersTable.count() > 0) {
      await expect(buyersTable).toBeVisible();
      printSuccess('Buyers table visible');
    } else {
      printWarning('Buyers table not found - may be using different layout');
    }
    
    // Test search functionality
    const searchInput = page.locator('#searchBuyers');
    if (await searchInput.count() > 0) {
      await expect(searchInput).toBeVisible();
      printSuccess('Search input visible');
    }
    
    // Test export button
    const exportBtn = page.locator('button:has-text("Export to Excel")');
    if (await exportBtn.count() > 0) {
      await expect(exportBtn).toBeVisible();
      printSuccess('Export button visible');
    }
  });

  test('Test Case 3: Test buyers table structure', async ({ page }) => {
    printTestCase(3, 'Test Buyers Table Structure');
    
    await page.goto('/buyer-group-management/buyers');
    await page.waitForLoadState('load');
    
    try {
      await waitForDataTable(page, 'table', 15000);
    } catch (e) {
      await page.waitForTimeout(3000);
    }
    
    const buyersTable = page.locator('table, table').first();
    
    if (await buyersTable.count() > 0) {
      // Verify table headers
      const headers = await buyersTable.locator('thead th, th').allTextContents();
      console.log(`✓ Table headers: ${headers.join(', ')}`);
      
      const expectedColumns = ['name', 'code', 'gln', 'status', 'stores', 'action'];
      let foundCount = 0;
      for (const col of expectedColumns) {
        if (headers.some(h => h.toLowerCase().includes(col))) {
          foundCount++;
          console.log(`  ✓ ${col}`);
        }
      }
      
      expect(foundCount).toBeGreaterThanOrEqual(2);
      printSuccess(`Found ${foundCount} expected buyer columns`);
      
      // Count rows
      const dataRows = await buyersTable.locator('tbody tr, tr').count();
      console.log(`✓ Buyers table has ${dataRows} rows`);
      expect(dataRows).toBeGreaterThanOrEqual(0);
      printSuccess('Buyers table structure verified');
    } else {
      printWarning('Buyers table not found - may be using different layout');
    }
  });

  test('Test Case 4: Test create buyer workflow', async ({ page }) => {
    printTestCase(4, 'Test Create Buyer Workflow');
    
    await page.goto('/buyer-group-management/buyers');
    await page.waitForLoadState('load');
    
    try {
      await waitForDataTable(page, 'table', 15000);
    } catch (e) {
      await page.waitForTimeout(3000);
    }
    
    const buyersTable = page.locator('table, table').first();
    const initialBuyerCount = await buyersTable.locator('tbody tr, tr').count();
    console.log(`✓ Initial buyer count: ${initialBuyerCount}`);
    
    // Navigate to create buyer form
    await page.goto('/buyer-group-management/buyers/create');
    await page.waitForLoadState('load');
    
    const currentUrl = page.url();
    expect(currentUrl).toContain('/buyer-group-management/buyers/create');
    printSuccess('Navigated to create buyer form');
    
    // Fill in REQUIRED buyer information
    const nameInput = page.locator('#inputName');
    const emailInput = page.locator('#inputPrimaryEmail');
    const glnInput = page.locator('#inputGLNNumber');
    const practiceInput = page.locator('#inputPracticeNumber');
    
    await nameInput.fill(testBuyerName);
    printSuccess(`Entered buyer name: ${testBuyerName}`);
    
    await emailInput.fill(`test${Date.now()}@example.com`);
    printSuccess('Entered primary email');
    
    await glnInput.fill(testGln);
    printSuccess(`Entered GLN: ${testGln}`);
    
    await practiceInput.fill(`PRAC${Date.now()}`);
    printSuccess('Entered practice number');
    
    // Submit form
    const submitButton = page.locator('button[type="submit"]:has-text("Create")');
    await submitButton.click();
    printSuccess('Submitted buyer creation form');
    
    // Wait for success message and redirect (form uses 1500ms timeout)
    await page.waitForSelector('.swal2-popup, .alert-success', { state: 'visible', timeout: 5000 }).catch(() => {});
    await page.waitForTimeout(2000); // Wait for redirect
    await page.waitForLoadState('load');
    
    // Should be redirected back to buyers list
    await waitForDataTable(page, '#buyersTable', 15000);
    
    // Look for the new buyer in the table
    const testBuyerRow = page.locator(`#buyersTable tbody tr:has-text("${testBuyerName}")`);
    expect(await testBuyerRow.count()).toBeGreaterThan(0);
    printSuccess(`Test buyer "${testBuyerName}" created successfully`);
    createdBuyerId = testBuyerName; // Mark for cleanup
  });

  test('Test Case 5: Test GLN validation', async ({ page }) => {
    printTestCase(5, 'Test GLN Validation');
    
    await page.goto('/buyer-group-management/buyers/create');
    await page.waitForLoadState('load');
    
    const glnInput = page.locator('#inputGLNNumber');
    await expect(glnInput).toBeVisible({ timeout: 5000 });
    
    // Test invalid GLN (too short) - triggers AJAX validation on blur
    await glnInput.fill('123');
    await glnInput.blur();
    await page.waitForTimeout(1500);
    
    // Look for validation error (AJAX validation displays errors via .text-danger or .invalid-feedback)
    const validationError = page.locator('.text-danger:visible, .invalid-feedback:visible, .error-message:visible, .alert-danger:visible');
    await expect(validationError).toBeVisible({ timeout: 3000 });
    printSuccess('GLN validation works correctly');
    
    // Clear the invalid GLN
    await glnInput.clear();
    await glnInput.blur();
    await page.waitForTimeout(500);
  });

  test('Test Case 6: Test buyer search functionality', async ({ page }) => {
    printTestCase(6, 'Test Buyer Search Functionality');
    
    await page.goto('/buyer-group-management/buyers');
    await page.waitForLoadState('load');
    
    await waitForDataTable(page, '#buyersTable', 15000);
    
    const buyersTable = page.locator('#buyersTable');
    const initialCount = await buyersTable.locator('tbody tr').count();
    console.log(`✓ Initial buyer count: ${initialCount}`);
    
    if (initialCount === 0) {
      printWarning('No buyers to search');
      return;
    }
    
    // Get first buyer's name
    const firstRow = buyersTable.locator('tbody tr').first();
    const firstName = await firstRow.locator('td').first().textContent();
    console.log(`✓ First buyer: ${firstName}`);
    
    // Find search input (custom search input, not DataTables default)
    const searchInput = page.locator('#searchBuyers');
    
    if (await searchInput.count() > 0) {
      // Search for first 3 characters
      const searchTerm = firstName?.substring(0, 3) || 'test';
      await searchInput.fill(searchTerm);
      printSuccess(`Searching for: ${searchTerm}`);
      
      // Wait for DataTable to process the search (it triggers on keyup)
      await page.keyboard.press('Enter');
      await page.waitForFunction(() => {
        const table = document.querySelector('#buyersTable');
        return table && !table.classList.contains('processing');
      }, { timeout: 5000 }).catch(() => {});
      
      const filteredCount = await buyersTable.locator('tbody tr').count();
      console.log(`✓ Filtered count: ${filteredCount}`);
      
      // Verify filtering worked
      expect(filteredCount).toBeLessThanOrEqual(initialCount);
      printSuccess('Search filtering works');
      
      // Clear search
      await searchInput.clear();
      await page.keyboard.press('Enter');
      await page.waitForFunction(() => {
        const table = document.querySelector('#buyersTable');
        return table && !table.classList.contains('processing');
      }, { timeout: 5000 }).catch(() => {});
      printSuccess('Search cleared');
    } else {
      printWarning('Search input not found');
    }
  });

  test('Test Case 7: Test buyer status management', async ({ page }) => {
    printTestCase(7, 'Test Buyer Status Management');
    
    await page.goto('/buyer-group-management/buyers');
    await page.waitForLoadState('load');
    await waitForDataTable(page, '#buyersTable', 15000);
    
    // Wait for AJAX data to load
    await page.waitForFunction(() => {
      const table = document.querySelector('#buyersTable');
      const rows = table?.querySelectorAll('tbody tr');
      return rows && rows.length > 0 && !rows[0].textContent?.includes('Loading');
    }, { timeout: 10000 }).catch(() => {});
    
    const buyersTable = page.locator('#buyersTable');
    const buyerRows = await buyersTable.locator('tbody tr').count();
    
    if (buyerRows === 0) {
      printWarning('No buyers available - skipping status test');
      return;
    }
    
    // Get first buyer
    const firstRow = buyersTable.locator('tbody tr').first();
    const buyerName = await firstRow.locator('td').first().textContent();
    
    // Look for status toggle or status column
    const statusToggle = firstRow.locator('button:has-text("Activate"), button:has-text("Deactivate"), .status-toggle');
    const statusColumn = firstRow.locator('td:has-text("Active"), td:has-text("Inactive"), td:has-text("Enabled"), td:has-text("Disabled")');
    
    if (await statusToggle.count() > 0) {
      const initialText = await statusToggle.textContent();
      console.log(`✓ Initial status: ${initialText}`);
      
      // Toggle status
      await statusToggle.click();
      printSuccess('Clicked status toggle');
      await page.waitForTimeout(1000);
      
      const newText = await statusToggle.textContent();
      console.log(`✓ New status: ${newText}`);
      expect(newText).not.toBe(initialText);
      printSuccess('Status toggle works');
      
      // Toggle back
      await statusToggle.click();
      await page.waitForTimeout(1000);
      printSuccess('Status restored');
    } else if (await statusColumn.count() > 0) {
      const statusText = await statusColumn.textContent();
      console.log(`✓ Buyer status: ${statusText}`);
      printSuccess('Status information displayed');
    } else {
      printWarning('No status management controls found');
    }
  });

  test('Test Case 8: Test buyer store management', async ({ page }) => {
    printTestCase(8, 'Test Buyer Store Management');
    
    await page.goto('/buyer-group-management/buyers');
    await page.waitForLoadState('load');
    await waitForDataTable(page, '#buyersTable', 15000);
    
    // Wait for AJAX data to load
    await page.waitForFunction(() => {
      const table = document.querySelector('#buyersTable');
      const rows = table?.querySelectorAll('tbody tr');
      return rows && rows.length > 0 && !rows[0].textContent?.includes('Loading');
    }, { timeout: 10000 });
    
    const buyersTable = page.locator('#buyersTable');
    const buyerRows = await buyersTable.locator('tbody tr').count();
    expect(buyerRows).toBeGreaterThan(0);
    printSuccess(`Found ${buyerRows} buyers in the table`);
    
    // Wait for DataTable to be fully initialized and row click handlers to be attached
    await page.waitForFunction(() => {
      const tbody = document.querySelector('#buyersTable tbody');
      if (!tbody) return false;
      const events = (window as any).jQuery._data(tbody, 'events');
      return events && events.click;
    }, { timeout: 10000 });
    
    // Get first buyer row and click on it
    const firstRow = buyersTable.locator('tbody tr').first();
    const buyerName = await firstRow.locator('td').first().textContent();
    console.log(`✓ Clicking on buyer: ${buyerName}`);
    
    // Click on the buyer name cell (first td)
    await firstRow.locator('td').first().click();
    
    // Wait for navigation to complete
    await page.waitForURL(/buyer-group-management\/buyers\/details\/\d+/, { timeout: 10000 });
    await page.waitForLoadState('networkidle');
    await page.waitForTimeout(500);
    
    // Verify we're on buyer details page
    const detailsHeading = page.locator('h5:has-text("Buyer Details"), h4:has-text("Buyer Details"), h5:has-text("Buyer Group Details"), h4:has-text("Buyer Group Details")');
    await expect(detailsHeading.first()).toBeVisible({ timeout: 5000 });
    printSuccess('Navigated to buyer details page');
    
    // Verify Stores section exists on buyer details (the card or table)
    const storesSection = page.locator('.buyer-stores-card, .card:has-text("Stores"), table:has-text("Store")');
    await expect(storesSection.first()).toBeVisible({ timeout: 5000 });
    printSuccess('Stores section found on buyer details page');
    
    // Verify "Add New Store" button exists
    const addStoreButton = page.locator('#addStoreBtn, button:has-text("Add Store"), button:has-text("Add New Store"), a:has-text("Add Store")');
    if (await addStoreButton.count() > 0) {
      await expect(addStoreButton.first()).toBeVisible({ timeout: 5000 });
      printSuccess('Add New Store button found');
    } else {
      printWarning('Add Store button not found - may be loaded via AJAX');
    }
  });

  test('Test Case 9: Test buyer details view', async ({ page }) => {
    printTestCase(9, 'Test Buyer Details View');
    
    await page.goto('/buyer-group-management/buyers');
    await page.waitForLoadState('load');
    await waitForDataTable(page, '#buyersTable', 15000);
    
    // Wait for AJAX data to load
    await page.waitForFunction(() => {
      const table = document.querySelector('#buyersTable');
      const rows = table?.querySelectorAll('tbody tr');
      return rows && rows.length > 0 && !rows[0].textContent?.includes('Loading');
    }, { timeout: 10000 });
    
    const buyersTable = page.locator('#buyersTable');
    const buyerRows = await buyersTable.locator('tbody tr').count();
    expect(buyerRows).toBeGreaterThan(0);
    printSuccess(`Found ${buyerRows} buyers in the table`);
    
    // Wait for DataTable to be fully initialized and row click handlers to be attached
    await page.waitForFunction(() => {
      const tbody = document.querySelector('#buyersTable tbody');
      if (!tbody) return false;
      const events = (window as any).jQuery._data(tbody, 'events');
      return events && events.click;
    }, { timeout: 10000 });
    
    // Get first buyer row and click on it
    const firstRow = buyersTable.locator('tbody tr').first();
    const buyerName = await firstRow.locator('td').first().textContent();
    console.log(`✓ Clicking on buyer: ${buyerName}`);
    
    // Click on the buyer name cell (first td)
    await firstRow.locator('td').first().click();
    
    // Wait for navigation to complete
    await page.waitForURL(/buyer-group-management\/buyers\/details\/\d+/, { timeout: 10000 });
    await page.waitForLoadState('networkidle');
    await page.waitForTimeout(500);
    
    // Verify we're on buyer details page
    const detailsHeading = page.locator('h5:has-text("Buyer Details"), h4:has-text("Buyer Details"), h5:has-text("Buyer Group Details"), h4:has-text("Buyer Group Details")');
    await expect(detailsHeading.first()).toBeVisible({ timeout: 5000 });
    printSuccess('Successfully navigated to buyer details page');
    
    // Verify buyer information is displayed
    const buyerCard = page.locator('.card, .buyer-details');
    await expect(buyerCard.first()).toBeVisible();
    printSuccess('Buyer details information displayed');
  });

  test('Test Case 10: Test responsive design', async ({ page }) => {
    printTestCase(10, 'Test Responsive Design');
    
    await page.goto('/buyer-group-management/buyers');
    await page.waitForLoadState('load');
    
    try {
      await waitForDataTable(page, 'table', 15000);
    } catch (e) {
      await page.waitForTimeout(3000);
    }
    
    const viewports = [
      { width: 1280, height: 720, name: 'Desktop' },
      { width: 768, height: 1024, name: 'Tablet' },
      { width: 375, height: 667, name: 'Mobile' }
    ];
    
    for (const viewport of viewports) {
      await page.setViewportSize({ width: viewport.width, height: viewport.height });
      console.log(`\n📱 Testing ${viewport.name} (${viewport.width}x${viewport.height})`);
      await page.waitForTimeout(500);
      
      const buyersTable = page.locator('table, table').first();
      if (await buyersTable.count() > 0) {
        await expect(buyersTable).toBeVisible();
        console.log(`  ✓ Buyers table visible`);
      }
      
      const createButton = page.locator('button:has-text("Create"), button:has-text("Add")').first();
      if (await createButton.count() > 0) {
        await expect(createButton).toBeVisible();
        console.log(`  ✓ Create button accessible`);
      }
    }
    
    // Reset viewport
    await page.setViewportSize({ width: 1280, height: 720 });
    printSuccess('All viewports tested successfully');
  });
});
