import { test, expect } from '@playwright/test';
import {
  loginAsAdmin,
  generateUniqueName,
  generateUniqueEmail,
  generateUniquePhone,
  navigateToCustomers,
  navigateToCustomerCreate,
  confirmSweetAlert,
  waitForPageStable,
  waitForDataTableReload
} from '../helpers/systemcore';

/**
 * Customers CRUD Tests
 *
 * Tests the Customer management functionality including:
 * - Viewing customers list page
 * - Navigating to create customer page
 * - Creating a customer with required fields
 * - Creating a customer with all fields
 * - Validation errors for required fields
 * - Viewing customer details
 * - Editing an existing customer
 * - Deleting a customer with confirmation
 * - Searching customers in DataTable
 */

test.describe('Customers CRUD', () => {
  test.beforeEach(async ({ page }) => {
    await loginAsAdmin(page);
  });

  test('should display customers list page', async ({ page }) => {
    // Navigate to /systemcore/customers
    await navigateToCustomers(page);

    // Verify DataTable (#customersTable) is visible
    await expect(page.locator('#customersTable')).toBeVisible();

    // Verify page has card wrapper (use .first() since there may be multiple cards)
    await expect(page.locator('.card').first()).toBeVisible();

    // Verify Add Customer button exists
    const addButton = page.locator('a[href*="/systemcore/customers/create"]');
    await expect(addButton).toBeVisible();
  });

  test('should navigate to create customer page', async ({ page }) => {
    // Navigate to customers list
    await navigateToCustomers(page);

    // Click "Add Customer" button
    await page.click('a[href*="/systemcore/customers/create"]');

    // Verify form page loads
    await page.waitForURL('**/systemcore/customers/create', { timeout: 10000 });
    await waitForPageStable(page);

    // Verify form is visible
    await expect(page.locator('#customerForm')).toBeVisible();

    // Verify required form fields are present
    await expect(page.locator('#name')).toBeVisible();
    await expect(page.locator('#customer_type')).toBeVisible();
  });

  test('should create customer with required fields', async ({ page }) => {
    // Navigate to create page
    await navigateToCustomerCreate(page);
    await waitForPageStable(page);

    // Fill: name
    const customerName = generateUniqueName('Test Customer');
    await page.locator('#name').fill(customerName);

    // Select customer_type from dropdown
    await page.locator('#customer_type').selectOption('b2b');

    // Submit form
    await page.locator('#customerForm button[type="submit"]').click();

    // Verify redirect to show or list page
    await page.waitForLoadState('networkidle');
    await page.waitForURL(/\/systemcore\/customers(\/.+)?$/, { timeout: 10000 });

    // Verify we're on a valid customer page
    const currentUrl = page.url();
    expect(currentUrl).toMatch(/\/systemcore\/customers/);
  });

  test('should create customer with all fields', async ({ page }) => {
    // Navigate to create page
    await navigateToCustomerCreate(page);
    await waitForPageStable(page);

    // Fill all fields
    const customerName = generateUniqueName('Complete Customer');
    const customerEmail = generateUniqueEmail();
    const customerPhone = generateUniquePhone();

    await page.locator('#name').fill(customerName);
    await page.locator('#company_name').fill('Test Company Ltd');
    await page.locator('#customer_type').selectOption('b2c');
    await page.locator('#email').fill(customerEmail);
    await page.locator('#phone').fill(customerPhone);
    await page.locator('#mobile').fill('+1555' + Date.now().toString().slice(-7));
    await page.locator('#website').fill('https://example.com');
    await page.locator('#tax_id').fill('TAX' + Date.now().toString().slice(-6));
    await page.locator('#vat_number').fill('VAT' + Date.now().toString().slice(-6));
    await page.locator('#credit_limit').fill('50000');
    await page.locator('#notes').fill('Test customer created via E2E test');

    // Submit and verify
    await page.locator('#customerForm button[type="submit"]').click();

    // Wait for response
    await page.waitForLoadState('networkidle');
    await page.waitForURL(/\/systemcore\/customers(\/.+)?$/, { timeout: 10000 });

    // Verify redirect
    const currentUrl = page.url();
    expect(currentUrl).toMatch(/\/systemcore\/customers/);
  });

  test('should show validation error for empty name', async ({ page }) => {
    // Navigate to create page
    await navigateToCustomerCreate(page);
    await waitForPageStable(page);

    // Select customer_type but leave name empty
    await page.locator('#customer_type').selectOption('b2b');

    // Submit form
    await page.locator('#customerForm button[type="submit"]').click();

    // Wait a moment for validation
    await page.waitForTimeout(500);

    // Form should still be visible
    await expect(page.locator('#customerForm')).toBeVisible();

    // Check that we're still on the create page
    const currentUrl = page.url();
    expect(currentUrl).toContain('/create');
  });

  test('should view customer details', async ({ page }) => {
    // Navigate to customers list
    await navigateToCustomers(page);
    await waitForPageStable(page);

    // Wait for DataTable to load
    await waitForDataTableReload(page, '#customersTable');
    await page.waitForTimeout(1000);

    // Wait for at least one row
    await page.waitForSelector('#customersTable tbody tr', { timeout: 10000 });

    // Get the first row
    const firstRow = page.locator('#customersTable tbody tr').first();

    // Click the dropdown toggle to open the actions menu
    const dropdownToggle = firstRow.locator('.btn-icon.dropdown-toggle, button.dropdown-toggle').first();
    const dropdownCount = await dropdownToggle.count();

    if (dropdownCount === 0) {
      test.skip();
      return;
    }

    await dropdownToggle.click();
    await page.waitForTimeout(300);

    // Click the view button from the dropdown menu
    const viewButton = page.locator('.dropdown-item:has-text("View")').first();
    const viewButtonCount = await viewButton.count();

    if (viewButtonCount === 0) {
      test.skip();
      return;
    }

    await viewButton.click();

    // Verify show page displays customer info
    await page.waitForURL(/\/systemcore\/customers\/\d+$/, { timeout: 10000 });
    await waitForPageStable(page);

    // Verify customer information is displayed
    await expect(page.locator('.card').first()).toBeVisible();
  });

  test('should edit existing customer', async ({ page }) => {
    // Navigate to customers list
    await navigateToCustomers(page);
    await waitForPageStable(page);

    // Wait for DataTable to load
    await waitForDataTableReload(page, '#customersTable');
    await page.waitForTimeout(1000);

    // Wait for at least one row
    await page.waitForSelector('#customersTable tbody tr', { timeout: 10000 });

    // Get the first row
    const firstRow = page.locator('#customersTable tbody tr').first();

    // Click the dropdown toggle to open the actions menu
    const dropdownToggle = firstRow.locator('.btn-icon.dropdown-toggle, button.dropdown-toggle').first();
    const dropdownCount = await dropdownToggle.count();

    if (dropdownCount === 0) {
      test.skip();
      return;
    }

    await dropdownToggle.click();
    await page.waitForTimeout(300);

    // Click the edit button from the dropdown menu
    const editButton = page.locator('.dropdown-item:has-text("Edit"), a.dropdown-item[href*="/edit"]').first();
    const editButtonCount = await editButton.count();

    if (editButtonCount === 0) {
      test.skip();
      return;
    }

    await editButton.click();

    // Wait for edit page
    await page.waitForURL('**/edit', { timeout: 10000 });
    await waitForPageStable(page);

    // Verify we're on edit page
    await expect(page.locator('#customerForm')).toBeVisible();

    // Modify fields
    const updatedName = generateUniqueName('Updated Customer');
    await page.locator('#name').fill(updatedName);

    // Save and verify changes
    await page.locator('#customerForm button[type="submit"]').click();

    // Wait for response
    await page.waitForLoadState('networkidle');

    // Verify redirect
    await page.waitForTimeout(1000);
    const currentUrl = page.url();
    expect(currentUrl).toMatch(/\/systemcore\/customers/);
  });

  test('should delete customer with confirmation', async ({ page }) => {
    // Navigate to customers list
    await navigateToCustomers(page);
    await waitForPageStable(page);

    // Wait for DataTable to load
    await waitForDataTableReload(page, '#customersTable');
    await page.waitForTimeout(1000);

    // Wait for at least one row
    await page.waitForSelector('#customersTable tbody tr', { timeout: 10000 });

    // Count initial rows
    const initialRowCount = await page.locator('#customersTable tbody tr').count();

    if (initialRowCount === 0) {
      test.skip();
      return;
    }

    // Get the first row
    const firstRow = page.locator('#customersTable tbody tr').first();

    // Click the dropdown toggle to open the actions menu
    const dropdownToggle = firstRow.locator('.btn-icon.dropdown-toggle, button.dropdown-toggle').first();
    const dropdownCount = await dropdownToggle.count();

    if (dropdownCount === 0) {
      test.skip();
      return;
    }

    await dropdownToggle.click();
    await page.waitForTimeout(300);

    // Find and click delete button from the dropdown menu
    const deleteButton = page.locator('.dropdown-item.text-danger:has-text("Delete"), .dropdown-item[onclick*="delete"]').first();

    if (await deleteButton.count() === 0) {
      test.skip();
      return;
    }

    await deleteButton.click();

    // Confirm SweetAlert dialog
    await confirmSweetAlert(page);

    // Wait for deletion
    await page.waitForTimeout(1000);

    // Verify table is still visible
    await waitForDataTableReload(page, '#customersTable');
    await expect(page.locator('#customersTable')).toBeVisible();
  });

  test('should search customers in DataTable', async ({ page }) => {
    // Navigate to customers list
    await navigateToCustomers(page);
    await waitForPageStable(page);

    // Wait for DataTable to load
    await waitForDataTableReload(page, '#customersTable');
    await page.waitForTimeout(1000);

    // Check for empty table (DataTables shows "No data available" row)
    const rowCount = await page.locator('#customersTable tbody tr').count();
    const emptyTableRow = await page.locator('#customersTable tbody tr td.dataTables_empty').count();

    if (rowCount === 0 || emptyTableRow > 0) {
      test.skip();
      return;
    }

    // Get the first customer name from the table
    const firstRowName = await page.locator('#customersTable tbody tr:first-child td:nth-child(2)').textContent({ timeout: 5000 });

    if (!firstRowName || firstRowName.trim() === '') {
      test.skip();
      return;
    }

    // Type in search box
    const searchBox = page.locator('#customersTable_filter input[type="search"]');
    await searchBox.fill(firstRowName.trim().substring(0, 5));

    // Wait for DataTable to filter
    await page.waitForTimeout(1000);

    // At least one row should be visible after search
    const visibleRows = await page.locator('#customersTable tbody tr').count();
    expect(visibleRows).toBeGreaterThan(0);
  });

  test('should cancel creation and return to list', async ({ page }) => {
    // Navigate to create page
    await navigateToCustomerCreate(page);
    await waitForPageStable(page);

    // Fill some data
    await page.locator('#name').fill('Will be cancelled');
    await page.locator('#customer_type').selectOption('b2b');

    // Click cancel button
    const cancelButton = page.locator('a:has-text("Cancel"), a.btn-label-secondary').first();
    await cancelButton.click();

    // Should navigate back to list
    await page.waitForURL('**/systemcore/customers', { timeout: 10000 });
    await waitForPageStable(page);

    await expect(page.locator('#customersTable')).toBeVisible();
  });

  test('should display all customer types in dropdown', async ({ page }) => {
    // Navigate to create page
    await navigateToCustomerCreate(page);
    await waitForPageStable(page);

    // Verify all customer type options are available
    const customerTypeSelect = page.locator('#customer_type');
    await expect(customerTypeSelect).toBeVisible();

    // Check that all expected options exist
    const options = await customerTypeSelect.locator('option').allTextContents();

    // Should have multiple options
    expect(options.length).toBeGreaterThanOrEqual(5);
  });
});
