/**
 * Store Management Test
 * 
 * Tags: @admin @p2 @regression @ui
 * 
 * Comprehensive functional testing of store management:
 * - Store CRUD operations (Create, Read, Update, Delete)
 * - Store user management and role assignments
 * - Seller group linking and management
 * - Account number validation
 * - Head office designation
 */

import { test, expect } from '@playwright/test';
import { printTestCase, printSuccess, printWarning, waitForDataTable, ensureAuthenticated } from '../../helpers/test-helpers';

test.describe('04_Partner_Management - Store Management', () => {
  // Use authenticated state for all tests in this suite
  test.use({ storageState: 'auth.json' });

  const testStoreName = `Test Store ${Date.now()}`;
  const testStoreCode = `TST${Date.now()}`;
  const testAccountNumber = `ACC${Date.now().toString().slice(-8)}`;
  
  let createdStoreId: string | null = null;

  test.beforeEach(async ({ page }) => {
    // Ensure we're authenticated before navigating anywhere
    await ensureAuthenticated(page);
    
    console.log('\n🚀 Navigating to store management page...');
    await page.goto('/store-management/stores');
    await page.waitForLoadState('load');
    console.log('✅ Store management page loaded');
  });

  test.afterEach(async ({ page }) => {
    // Cleanup: Delete test store if created
    if (createdStoreId) {
      try {
        await page.goto('/store-management/stores');
        await page.waitForLoadState('load');
        await waitForDataTable(page, '#storesTable', 10000);
        
        // Look for test store and delete it
        const testStoreRow = page.locator(`#storesTable tr:has-text("${testStoreName}")`);
        if (await testStoreRow.count() > 0) {
          const deleteBtn = testStoreRow.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 store: ${testStoreName}`);
          }
        }
      } catch (e) {
        console.log(`⚠ Could not clean up test store: ${e}`);
      }
    }
  });

  test('Test Case 1: Navigate to store management page', async ({ page }) => {
    printTestCase(1, 'Navigate to Store Management Page');
    
    const currentUrl = page.url();
    expect(currentUrl).toContain('/store-management/stores');
    expect(currentUrl).not.toContain('/login');
    printSuccess('Store management page accessible');
    
    const heading = page.locator('h1:has-text("Store Management")');
    await expect(heading).toBeVisible();
    printSuccess('Store Management heading visible');
    
    // Verify table is present
    const storesTable = page.locator('#storesTable');
    await expect(storesTable).toBeVisible();
    printSuccess('Stores table visible');
    
    const createBtn = page.locator('a:has-text("Create"), button:has-text("Create")');
    await expect(createBtn.first()).toBeVisible();
    printSuccess('Create button visible');
  });

  test('Test Case 2: Test stores table structure', async ({ page }) => {
    printTestCase(2, 'Test Stores Table Structure');
    
    await page.goto('/store-management/stores');
    await page.waitForLoadState('load');
    await waitForDataTable(page, '#storesTable', 15000);
    
    // Wait for AJAX data to load
    await page.waitForFunction(() => {
      const table = document.querySelector('#storesTable');
      const rows = table?.querySelectorAll('tbody tr');
      return rows && rows.length > 0 && !rows[0].textContent?.includes('Loading');
    }, { timeout: 10000 }).catch(() => {});
    
    const storesTable = page.locator('#storesTable');
    
    // Verify table headers
    const headers = await storesTable.locator('thead th').allTextContents();
    console.log(`✓ Table headers: ${headers.join(', ')}`);
    
    // Check for expected columns based on actual table: Buyer, Store Name, GLN Number, Status, etc.
    const expectedColumns = ['buyer', 'store', 'name', 'status'];
    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 store columns`);
    
    // Count rows
    const dataRows = await storesTable.locator('tbody tr').count();
    console.log(`✓ Stores table has ${dataRows} rows`);
    expect(dataRows).toBeGreaterThan(0);
    printSuccess('Stores table structure verified');
  });

  test('Test Case 3: Test create store workflow', async ({ page }) => {
    printTestCase(3, 'Test Create Store Workflow');
    
    await page.goto('/store-management/stores');
    await page.waitForLoadState('load');
    await waitForDataTable(page, '#storesTable', 15000);
    
    const initialStoreCount = await page.locator('#storesTable tbody tr').count();
    console.log(`✓ Initial store count: ${initialStoreCount}`);
    
    // Navigate to create store form
    await page.goto('/store-management/stores/create');
    await page.waitForLoadState('load');
    
    const currentUrl = page.url();
    expect(currentUrl).toContain('/store-management/stores/create');
    printSuccess('Navigated to create store form');
    
    // Fill in REQUIRED store information
    const buyerSelect = page.locator('#inputBuyerId');
    const nameInput = page.locator('#inputName');
    const glnInput = page.locator('#inputGlnNumber');
    const emailInput = page.locator('#inputPrimaryEmail');
    const practiceInput = page.locator('#inputPracticeNumber');
    const headOfficeCheckbox = page.locator('#inputHeadOffice');
    
    // Select first buyer from dropdown
    await buyerSelect.selectOption({ index: 1 }); // Index 0 is "Select a buyer", so use index 1
    printSuccess('Selected buyer from dropdown');
    
    await nameInput.fill(testStoreName);
    printSuccess(`Entered store name: ${testStoreName}`);
    
    await glnInput.fill(`GLN${Date.now()}`);
    printSuccess('Entered GLN number');
    
    await emailInput.fill(`store${Date.now()}@example.com`);
    printSuccess('Entered primary email');
    
    await practiceInput.fill(`PRAC${Date.now()}`);
    printSuccess('Entered practice number');
    
    // DO NOT check head office - this would demote ALL other head office stores to branches!
    // The database only allows ONE head office per buyer, so checking this would break JAB Orders tests
    // await headOfficeCheckbox.check();
    // printSuccess('Checked head office status');
    printSuccess('Leaving as branch store (not head office) to avoid breaking JAB Orders');
    
    // Close any validation modals that might be blocking the submit button
    const modal = page.locator('.swal2-container.swal2-backdrop-show');
    if (await modal.isVisible({ timeout: 1000 }).catch(() => false)) {
      const confirmButton = modal.locator('button.swal2-confirm, button:has-text("OK"), button:has-text("Close")').first();
      if (await confirmButton.isVisible({ timeout: 500 }).catch(() => false)) {
        await confirmButton.click();
        await page.waitForTimeout(500);
      }
    }
    
    // Submit form
    const submitButton = page.locator('button[type="submit"]:has-text("Create")');
    await submitButton.click();
    printSuccess('Submitted store creation form');
    
    // Wait for success message and redirect
    await page.waitForTimeout(2000);
    await page.waitForLoadState('load');
    
    // Should be redirected back to stores list
    await waitForDataTable(page, '#storesTable', 15000);
    
    // Look for the new store in the table
    const testStoreRow = page.locator(`#storesTable tbody tr:has-text("${testStoreName}")`);
    expect(await testStoreRow.count()).toBeGreaterThan(0);
    printSuccess(`Test store "${testStoreName}" created successfully`);
    createdStoreId = testStoreName; // Mark for cleanup
  });

  test('Test Case 4: Test account number validation', async ({ page }) => {
    printTestCase(4, 'Test Account Number Validation');
    
    // Account numbers are on the seller group linking interface, not create form
    await page.goto('/store-management/stores');
    await page.waitForLoadState('load');
    await waitForDataTable(page, '#storesTable', 15000);
    
    // Click on first store to go to details
    const firstRow = page.locator('#storesTable tbody tr').first();
    await firstRow.click();
    await page.waitForLoadState('load');
    
    // Look for seller groups section
    const sellerGroupsCard = page.locator('.seller-groups-card, [class*="seller-group"], #sellerGroupsCard').first();
    if (await sellerGroupsCard.isVisible({ timeout: 2000 }).catch(() => false)) {
      printSuccess('Seller groups section visible');
      
      // Try to find link button or manage button
      const linkButton = page.locator('button:has-text("Link"), button:has-text("Add"), button:has-text("Manage")').first();
      if (await linkButton.isVisible({ timeout: 2000 }).catch(() => false)) {
        await linkButton.click();
        await page.waitForTimeout(1000);
        
        // Account number inputs should appear in modal or table
        const accountNumberInput = page.locator('input.account-number-input, input[placeholder*="Account"], input[name*="account"]').first();
        if (await accountNumberInput.isVisible({ timeout: 3000 }).catch(() => false)) {
          printSuccess('Account number input field found');
        } else {
          printWarning('Account number input not immediately visible - may require seller group selection');
        }
      } else {
        printWarning('Link/Manage button not found - checking if account numbers shown inline');
      }
    } else {
      printWarning('Seller groups section not visible on this store');
    }
  });

  test('Test Case 5: Test store user management', async ({ page }) => {
    printTestCase(5, 'Test Store User Management');
    
    // User management is on store details page, not table list
    await page.goto('/store-management/stores');
    await page.waitForLoadState('load');
    await waitForDataTable(page, '#storesTable', 15000);
    
    const storeRows = await page.locator('#storesTable tbody tr').count();
    expect(storeRows).toBeGreaterThan(0);
    printSuccess(`Found ${storeRows} stores`);
    
    // Click first store to go to details
    const firstRow = page.locator('#storesTable tbody tr').first();
    await firstRow.click();
    await page.waitForLoadState('load');
    await page.waitForTimeout(1000);
    
    // Look for "Add User to Store" button on details page
    const addUserButton = page.locator('button#addUserBtn, button:has-text("Add User")').first();
    await expect(addUserButton).toBeVisible({ timeout: 5000 });
    printSuccess('User management button found on store details page');
    
    // Verify store users section exists
    const storeUsersCard = page.locator('.store-users-card, #storeUsersCard').first();
    await expect(storeUsersCard).toBeVisible();
    printSuccess('Store users section visible');
  });

  test('Test Case 6: Test seller group linking', async ({ page }) => {
    printTestCase(6, 'Test Seller Group Linking');
    
    // Seller group linking is on store details page, not table list
    await page.goto('/store-management/stores');
    await page.waitForLoadState('load');
    await waitForDataTable(page, '#storesTable', 15000);
    
    const storeRows = await page.locator('#storesTable tbody tr').count();
    expect(storeRows).toBeGreaterThan(0);
    printSuccess(`Found ${storeRows} stores`);
    
    // Click first store to go to details
    const firstRow = page.locator('#storesTable tbody tr').first();
    await firstRow.click();
    await page.waitForLoadState('load');
    await page.waitForTimeout(1000);
    
    // Look for "Link Seller Groups" button on details page
    const linkSellerGroupBtn = page.locator('button#linkSellerGroupBtn, button:has-text("Link Seller Groups")').first();
    await expect(linkSellerGroupBtn).toBeVisible({ timeout: 5000 });
    printSuccess('Seller group linking button found on store details page');
    
    // Verify seller groups section exists
    const sellerGroupsCard = page.locator('.seller-groups-card, #sellerGroupsCard').first();
    await expect(sellerGroupsCard).toBeVisible();
    printSuccess('Seller groups section visible');
  });

  test('Test Case 7: Test store search functionality', async ({ page }) => {
    printTestCase(7, 'Test Store Search Functionality');
    
    await page.goto('/store-management/stores');
    await page.waitForLoadState('load');
    await waitForDataTable(page, '#storesTable', 15000);
    
    const initialCount = await page.locator('#storesTable tbody tr:visible').count();
    console.log(`✓ Initial store count: ${initialCount}`);
    
    if (initialCount === 0) {
      printWarning('No stores to search');
      return;
    }
    
    // Get first store's name
    const firstRow = page.locator('#storesTable tbody tr:visible').first();
    const firstName = await firstRow.locator('td').first().textContent();
    console.log(`✓ First store: ${firstName}`);
    
    // Find search input (custom search input, not DataTables default)
    const searchInput = page.locator('#searchStores');
    
    if (await searchInput.count() === 0) {
      printWarning('Search input not found');
      return;
    }
    
    // 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('#storesTable');
      return table && !table.classList.contains('processing');
    }, { timeout: 5000 }).catch(() => {});
    
    const filteredCount = await page.locator('#storesTable tbody tr:visible').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('#storesTable');
      return table && !table.classList.contains('processing');
    }, { timeout: 5000 }).catch(() => {});
    printSuccess('Search cleared');
  });

  test('Test Case 8: Test store status management', async ({ page }) => {
    printTestCase(8, 'Test Store Status Management');
    
    await page.goto('/store-management/stores');
    await page.waitForLoadState('load');
    await waitForDataTable(page, '#storesTable', 15000);
    
    const storeRows = await page.locator('#storesTable tbody tr').count();
    
    if (storeRows === 0) {
      printWarning('No stores available - skipping status test');
      return;
    }
    
    // Get first store
    const firstRow = page.locator('#storesTable tbody tr').first();
    const storeName = 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(`✓ Store status: ${statusText}`);
      printSuccess('Status information displayed');
    } else {
      printWarning('No status management controls found');
    }
  });

  test('Test Case 9: Test head office designation', async ({ page }) => {
    printTestCase(9, 'Test Head Office Designation');
    
    await page.goto('/store-management/stores');
    await page.waitForLoadState('load');
    await waitForDataTable(page, '#storesTable', 15000);
    
    const storeRows = await page.locator('#storesTable tbody tr').count();
    
    if (storeRows === 0) {
      printWarning('No stores available - skipping head office test');
      return;
    }
    
    // Get first store
    const firstRow = page.locator('#storesTable tbody tr').first();
    const storeName = await firstRow.locator('td').first().textContent();
    
    // Look for head office column or indicator
    const headOfficeColumn = firstRow.locator('td:has-text("Head Office"), td:has-text("Yes"), td:has-text("No")');
    
    if (await headOfficeColumn.count() > 0) {
      const headOfficeText = await headOfficeColumn.textContent();
      console.log(`✓ Head office status: ${headOfficeText}`);
      printSuccess('Head office information displayed');
    } else {
      printWarning('No head office information found');
    }
  });

  test('Test Case 10: Test responsive design', async ({ page }) => {
    printTestCase(10, 'Test Responsive Design');
    
    await page.goto('/store-management/stores');
    await page.waitForLoadState('load');
    await waitForDataTable(page, '#storesTable', 15000);
    
    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 storesTable = page.locator('#storesTable');
      await expect(storesTable).toBeVisible();
      console.log(`  ✓ Stores table visible`);
      
      // Check for create button (it's a link, not a button)
      const createButton = page.locator('a:has-text("Create New Store")');
      const isVisible = await createButton.isVisible().catch(() => false);
      if (isVisible) {
        console.log(`  ✓ Create button accessible`);
      } else {
        console.log(`  ⚠ Create button may be in collapsed menu on ${viewport.name}`);
      }
    }
    
    // Reset viewport
    await page.setViewportSize({ width: 1280, height: 720 });
    printSuccess('All viewports tested successfully');
  });
});
