import { test, expect } from '@playwright/test';
import {
  loginAsAdmin,
  generateUniqueName,
  navigateToCustomers,
  navigateToCustomerShow,
  confirmSweetAlert,
  waitForSuccessSweetAlert,
  waitForPageStable,
  closeOffcanvas,
  waitForDataTableReload
} from '../helpers/systemcore';

/**
 * Customer Addresses Management Tests
 *
 * Tests the Customer Addresses functionality including:
 * - Viewing addresses section on customer show page
 * - Opening add address offcanvas
 * - Creating billing and shipping addresses
 * - Setting addresses as primary
 * - Editing existing addresses
 * - Deleting addresses with confirmation
 */

test.describe('Customer Addresses', () => {
  let customerId: number;

  test.beforeEach(async ({ page }) => {
    // Login as admin
    await loginAsAdmin(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 if there are any customers in the table
    const rowCount = await page.locator('#customersTable tbody tr').count();
    const emptyTable = await page.locator('#customersTable tbody tr td.dataTables_empty').count();

    if (rowCount === 0 || emptyTable > 0) {
      // No customers available - tests will be skipped
      return;
    }

    // Get first customer ID from the table
    const firstRow = page.locator('#customersTable tbody tr').first();
    const viewButton = firstRow.locator('a[href*="/systemcore/customers/"]').first();

    // Check if view button exists
    if (await viewButton.count() === 0) {
      return;
    }

    const href = await viewButton.getAttribute('href', { timeout: 5000 });

    if (href) {
      const matches = href.match(/\/systemcore\/customers\/(\d+)/);
      if (matches && matches[1]) {
        customerId = parseInt(matches[1]);
      }
    }

    // Navigate to customer show page
    if (customerId) {
      await navigateToCustomerShow(page, customerId);
      await waitForPageStable(page);
    }
  });

  test('should display addresses section on customer show page', async ({ page }) => {
    // Skip if no customer available
    if (!customerId) {
      test.skip();
      return;
    }

    // Verify addresses card is visible - use filter to avoid ambiguity with multiple cards
    const addressesCard = page.locator('.card').filter({ hasText: 'Addresses' }).first();
    await expect(addressesCard).toBeVisible();

    // Verify Add button exists (either header button or "Add First Address" depending on if addresses exist)
    const addButton = addressesCard.locator('button.btn-sm:has-text("Add"), button:has-text("Add First Address")').first();
    await expect(addButton).toBeVisible();
  });

  test('should open add address offcanvas', async ({ page }) => {
    // Skip if no customer available
    if (!customerId) {
      test.skip();
      return;
    }

    // Find the Addresses card and click its Add button - handle both cases
    const addressesCard = page.locator('.card').filter({ hasText: 'Addresses' }).first();
    await addressesCard.locator('button.btn-sm:has-text("Add"), button:has-text("Add First Address")').first().click();
    await page.waitForTimeout(500);

    // Verify offcanvas opens
    const offcanvas = page.locator('#addressOffcanvas');
    await expect(offcanvas).toBeVisible({ timeout: 5000 });

    // Verify form fields are present
    await expect(page.locator('#address_line_1')).toBeVisible();
    await expect(page.locator('#address_city')).toBeVisible();
    await expect(page.locator('#address_country')).toBeVisible();

    // Close offcanvas
    await closeOffcanvas(page);
  });

  test('should create billing address', async ({ page }) => {
    // Skip if no customer available
    if (!customerId) {
      test.skip();
      return;
    }

    // Find the Addresses card and click its Add button - handle both cases
    const addressesCard = page.locator('.card').filter({ hasText: 'Addresses' }).first();
    await addressesCard.locator('button.btn-sm:has-text("Add"), button:has-text("Add First Address")').first().click();
    await page.waitForTimeout(500);

    // Wait for offcanvas to open
    await expect(page.locator('#addressOffcanvas')).toBeVisible({ timeout: 5000 });

    // Select address type if available
    const addressType = page.locator('#address_type');
    if (await addressType.count() > 0) {
      await addressType.selectOption('billing');
    }

    // Fill address form
    await page.locator('#address_line_1').fill('123 Main Street');
    await page.locator('#address_line_2').fill('Suite 100');
    await page.locator('#address_city').fill('New York');
    await page.locator('#address_state').fill('NY');
    await page.locator('#address_postal_code').fill('10001');
    await page.locator('#address_country').fill('USA');

    // Check is_billing checkbox if available
    const billingCheckbox = page.locator('#address_is_billing');
    if (await billingCheckbox.count() > 0) {
      await billingCheckbox.check();
    }

    // Submit form
    await page.locator('#submitAddressBtn, button[type="submit"]:has-text("Save")').first().click();

    // Wait for success
    await page.waitForTimeout(2000);

    // Verify address appears in the list
    const addressCard = page.locator('.card').filter({ hasText: 'Addresses' }).first();
    await expect(addressCard).toContainText('123 Main Street');
  });

  test('should create shipping address', async ({ page }) => {
    // Skip if no customer available
    if (!customerId) {
      test.skip();
      return;
    }

    // Find the Addresses card and click its Add button - handle both cases
    const addressesCard = page.locator('.card').filter({ hasText: 'Addresses' }).first();
    await addressesCard.locator('button.btn-sm:has-text("Add"), button:has-text("Add First Address")').first().click();
    await page.waitForTimeout(500);

    // Wait for offcanvas to open
    await expect(page.locator('#addressOffcanvas')).toBeVisible({ timeout: 5000 });

    // Select address type if available
    const addressType = page.locator('#address_type');
    if (await addressType.count() > 0) {
      await addressType.selectOption('shipping');
    }

    // Fill address form
    await page.locator('#address_line_1').fill('456 Shipping Lane');
    await page.locator('#address_city').fill('Los Angeles');
    await page.locator('#address_state').fill('CA');
    await page.locator('#address_postal_code').fill('90001');
    await page.locator('#address_country').fill('USA');

    // Check is_shipping checkbox if available
    const shippingCheckbox = page.locator('#address_is_shipping');
    if (await shippingCheckbox.count() > 0) {
      await shippingCheckbox.check();
    }

    // Submit form
    await page.locator('#submitAddressBtn, button[type="submit"]:has-text("Save")').first().click();

    // Wait for success
    await page.waitForTimeout(2000);

    // Verify address appears in the list
    const addressCard = page.locator('.card').filter({ hasText: 'Addresses' }).first();
    await expect(addressCard).toContainText('456 Shipping Lane');
  });

  test('should edit existing address', async ({ page }) => {
    // Skip if no customer available
    if (!customerId) {
      test.skip();
      return;
    }

    // First, check if there are any addresses
    const addressesCard = page.locator('.card').filter({ hasText: 'Addresses' }).first();
    const addressItems = addressesCard.locator('.col-md-6');
    const addressCount = await addressItems.count();

    if (addressCount === 0) {
      // Create an address first - use more specific selector
      await addressesCard.locator('button.btn-sm:has-text("Add"), button:has-text("Add First Address")').first().click();
      await page.waitForTimeout(500);
      await page.locator('#address_line_1').fill('Original Address');
      await page.locator('#address_city').fill('Boston');
      await page.locator('#address_country').fill('USA');
      await page.locator('#submitAddressBtn, button[type="submit"]:has-text("Save")').first().click();
      await page.waitForTimeout(2000);
    }

    // Find and click edit button within the addresses card
    const dropdownToggle = addressesCard.locator('.btn-icon.dropdown-toggle').first();
    if (await dropdownToggle.count() > 0) {
      await dropdownToggle.click();
      await page.waitForTimeout(300);
    }

    const editButton = page.locator('.dropdown-item:has-text("Edit")').first();
    if (await editButton.count() > 0) {
      await editButton.click();
      await page.waitForTimeout(500);

      // Wait for offcanvas to open
      await expect(page.locator('#addressOffcanvas')).toBeVisible({ timeout: 5000 });

      // Modify address line 1
      const addressLine1 = page.locator('#address_line_1');
      await addressLine1.clear();
      await addressLine1.fill('Updated Address Line');

      // Submit form
      await page.locator('#submitAddressBtn, button[type="submit"]:has-text("Save")').first().click();

      // Wait for success
      await page.waitForTimeout(2000);

      // Verify changes appear
      const addressCard = page.locator('.card').filter({ hasText: 'Addresses' }).first();
      await expect(addressCard).toContainText('Updated Address Line');
    }
  });

  test('should delete address with confirmation', async ({ page }) => {
    // Skip if no customer available
    if (!customerId) {
      test.skip();
      return;
    }

    // First, ensure there's at least one address
    const addressesCard = page.locator('.card').filter({ hasText: 'Addresses' }).first();
    const addressItems = addressesCard.locator('.col-md-6');
    let addressCount = await addressItems.count();

    if (addressCount === 0) {
      // Create an address first - use more specific selector
      await addressesCard.locator('button.btn-sm:has-text("Add"), button:has-text("Add First Address")').first().click();
      await page.waitForTimeout(500);
      await page.locator('#address_line_1').fill('Address to Delete');
      await page.locator('#address_city').fill('Seattle');
      await page.locator('#address_country').fill('USA');
      await page.locator('#submitAddressBtn, button[type="submit"]:has-text("Save")').first().click();
      await page.waitForTimeout(2000);
      addressCount = await addressItems.count();
    }

    // Get initial count
    const initialCount = addressCount;

    // Find and click delete button within the addresses card
    const dropdownToggle = addressesCard.locator('.btn-icon.dropdown-toggle').first();
    if (await dropdownToggle.count() > 0) {
      await dropdownToggle.click();
      await page.waitForTimeout(300);
    }

    const deleteButton = page.locator('.dropdown-item.text-danger:has-text("Delete")').first();
    if (await deleteButton.count() > 0) {
      await deleteButton.click();

      // Confirm SweetAlert dialog
      await confirmSweetAlert(page);

      // Wait for deletion to complete
      await page.waitForTimeout(2000);
    }
  });

  test('should cancel address creation and close offcanvas', async ({ page }) => {
    // Skip if no customer available
    if (!customerId) {
      test.skip();
      return;
    }

    // Find the Addresses card and click its Add button - handle both cases
    const addressesCard = page.locator('.card').filter({ hasText: 'Addresses' }).first();
    await addressesCard.locator('button.btn-sm:has-text("Add"), button:has-text("Add First Address")').first().click();
    await page.waitForTimeout(500);

    // Wait for offcanvas to open
    await expect(page.locator('#addressOffcanvas')).toBeVisible({ timeout: 5000 });

    // Fill some data
    await page.locator('#address_line_1').fill('This will be cancelled');

    // Click cancel button
    await page.locator('button:has-text("Cancel")').first().click();
    await page.waitForTimeout(500);

    // Verify offcanvas is closed
    const offcanvas = page.locator('#addressOffcanvas');
    await expect(offcanvas).not.toBeVisible();
  });
});
