import { test, expect } from '@playwright/test';
import {
  loginAsAdmin,
  generateUniqueCode,
  navigateToPurchaseOrders,
  navigateToPurchaseOrderCreate,
  fillSelect2ById,
  setFlatpickrDate,
  getTodayDate,
  getFutureDate,
  confirmSweetAlert,
  waitForPageStable,
  waitForDataTableReload
} from '../helpers/systemcore';

/**
 * Purchase Orders CRUD Tests
 *
 * Tests the Purchase Order management functionality including:
 * - Viewing purchase orders list page
 * - Creating a purchase order with supplier and line items
 * - Adding and removing line items
 * - Viewing purchase order details
 * - Editing an existing purchase order
 * - Deleting a purchase order with confirmation
 */

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

  test('should display purchase orders list page', async ({ page }) => {
    // Navigate to /systemcore/purchase-orders
    await navigateToPurchaseOrders(page);

    // Verify page has card wrapper (use .first() for multiple cards)
    await expect(page.locator('.card').first()).toBeVisible();

    // Verify Add Purchase Order button exists
    const addButton = page.locator('a[href*="/systemcore/purchase-orders/create"]');
    await expect(addButton).toBeVisible();
  });

  test('should navigate to create purchase order page', async ({ page }) => {
    // Navigate to purchase orders list
    await navigateToPurchaseOrders(page);

    // Click "Add Purchase Order" button
    await page.click('a[href*="/systemcore/purchase-orders/create"]');

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

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

    // Verify supplier select exists
    await expect(page.locator('#supplier_id')).toBeVisible();
  });

  test('should display supplier selection dropdown', async ({ page }) => {
    // Navigate to create page
    await navigateToPurchaseOrderCreate(page);
    await waitForPageStable(page);

    // Verify supplier select is visible
    const supplierSelect = page.locator('#supplier_id');
    await expect(supplierSelect).toBeVisible();

    // Verify it has options (Select Supplier placeholder + actual suppliers)
    const optionCount = await supplierSelect.locator('option').count();
    expect(optionCount).toBeGreaterThanOrEqual(1);
  });

  test('should set order date with Flatpickr', async ({ page }) => {
    // Navigate to create page
    await navigateToPurchaseOrderCreate(page);
    await waitForPageStable(page);

    // Find order date field
    const orderDateField = page.locator('#order_date, input[name="order_date"]');
    if (await orderDateField.count() > 0) {
      // Set date using Flatpickr helper
      await setFlatpickrDate(page, '#order_date, input[name="order_date"]', getTodayDate());

      // Verify date is set
      const dateValue = await orderDateField.inputValue();
      expect(dateValue).not.toBe('');
    }
  });

  test('should add line item to order', async ({ page }) => {
    // Navigate to create page
    await navigateToPurchaseOrderCreate(page);
    await waitForPageStable(page);

    // Wait for page scripts to fully load
    await page.waitForLoadState('domcontentloaded');
    await page.waitForTimeout(3000);

    // Scroll down to see the line items section
    await page.evaluate(() => window.scrollTo(0, document.body.scrollHeight));
    await page.waitForTimeout(500);

    // Find the add line item button (ID is #addLineItem based on the view)
    const addLineButton = page.locator('#addLineItem');

    // Scroll the button into view
    await addLineButton.scrollIntoViewIfNeeded();
    await page.waitForTimeout(500);

    await expect(addLineButton).toBeVisible();

    // Check if JavaScript has initialized by looking for line items or Select2
    // If JavaScript loaded, there should be at least one line item row or Select2 container
    const hasJsInitialized = await page.evaluate(() => {
      // Check if line items exist OR Select2 is present
      const lineItems = document.querySelectorAll('#lineItemsContainer tr');
      const select2Containers = document.querySelectorAll('.select2-container');
      return lineItems.length > 0 || select2Containers.length > 0;
    });

    if (!hasJsInitialized) {
      // JavaScript didn't initialize - skip the test
      test.skip();
      return;
    }

    // Count initial line items in tbody
    const lineItemSelector = '#lineItemsContainer tr';
    const initialCount = await page.locator(lineItemSelector).count();

    // Click add button to add another line item
    await addLineButton.click();

    // Wait for the new row to be added
    await page.waitForTimeout(1000);

    // Verify line item was added
    const newCount = await page.locator(lineItemSelector).count();
    expect(newCount).toBeGreaterThan(initialCount);
  });

  test('should create purchase order with line items', async ({ page }) => {
    // Navigate to create page
    await navigateToPurchaseOrderCreate(page);
    await waitForPageStable(page);

    // Select supplier using Select2
    try {
      await fillSelect2ById(page, 'supplier_id', 'Supplier');
    } catch {
      // If Select2 fails, try direct selection
      const supplierSelect = page.locator('#supplier_id');
      const options = await supplierSelect.locator('option').count();
      if (options > 1) {
        await supplierSelect.selectOption({ index: 1 });
      }
    }

    // Set order date if available
    const orderDateField = page.locator('#order_date, input[name="order_date"]');
    if (await orderDateField.count() > 0) {
      await setFlatpickrDate(page, '#order_date', getTodayDate());
    }

    // Set expected delivery date if available
    const deliveryDateField = page.locator('#expected_delivery_date, input[name="expected_delivery_date"]');
    if (await deliveryDateField.count() > 0) {
      await setFlatpickrDate(page, '#expected_delivery_date', getFutureDate(14));
    }

    // Select payment terms if available
    const paymentTerms = page.locator('#payment_term_id');
    if (await paymentTerms.count() > 0) {
      const options = await paymentTerms.locator('option').count();
      if (options > 1) {
        await paymentTerms.selectOption({ index: 1 });
      }
    }

    // Wait for default line item to be added by JavaScript
    await page.waitForTimeout(1000);

    // Get the first line item (JavaScript adds one by default)
    const firstRow = page.locator('#lineItemsContainer tr.line-item').first();
    if (await firstRow.count() > 0) {
      // Fill line item details
      const lastRow = firstRow;

      // Try to select product
      const productSelect = lastRow.locator('[name*="product_id"], select[name*="product"]').first();
      if (await productSelect.count() > 0) {
        const options = await productSelect.locator('option').count();
        if (options > 1) {
          await productSelect.selectOption({ index: 1 });
        }
      }

      // Fill quantity
      const quantityInput = lastRow.locator('[name*="quantity"]').first();
      if (await quantityInput.count() > 0) {
        await quantityInput.fill('10');
      }

      // Fill unit price (cost price for purchase orders)
      const unitPriceInput = lastRow.locator('[name*="unit_price"]').first();
      if (await unitPriceInput.count() > 0) {
        await unitPriceInput.fill('80');
      }
    }

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

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

    // Should redirect to list or show page
    await page.waitForTimeout(2000);
    const currentUrl = page.url();
    expect(currentUrl).toMatch(/\/systemcore\/purchase-orders/);
  });

  test('should view purchase order details', async ({ page }) => {
    // Navigate to purchase orders list
    await navigateToPurchaseOrders(page);
    await waitForPageStable(page);

    // Wait for DataTable to load
    await page.waitForTimeout(2000);

    // Check if there are any rows in the table (excluding the "No data available" row)
    const rowCount = await page.locator('#purchaseOrdersTable tbody tr').count();
    const emptyTableRow = await page.locator('#purchaseOrdersTable tbody tr td.dataTables_empty').count();
    if (rowCount === 0 || emptyTableRow > 0) {
      test.skip();
      return;
    }

    // Click the first action dropdown button
    const firstActionButton = page.locator('button.dropdown-toggle').first();
    await firstActionButton.click();

    // Wait for dropdown menu to be visible (Bootstrap adds .show class)
    await page.waitForSelector('ul.dropdown-menu.show', { timeout: 5000 });

    // Click the "View" option in the dropdown
    const viewLink = page.locator('ul.dropdown-menu.show a.dropdown-item:has-text("View")').first();
    await viewLink.click();

    // Verify show page loads
    await page.waitForURL(/\/systemcore\/purchase-orders\/\d+$/, { timeout: 10000 });
    await waitForPageStable(page);

    // Verify order information is displayed (use .first() for multiple cards)
    await expect(page.locator('.card').first()).toBeVisible();
  });

  test('should edit existing purchase order', async ({ page }) => {
    // Navigate to purchase orders list
    await navigateToPurchaseOrders(page);
    await waitForPageStable(page);

    // Wait for DataTable to load
    await page.waitForTimeout(2000);

    // Check if there are any rows in the table (excluding the "No data available" row)
    const rowCount = await page.locator('#purchaseOrdersTable tbody tr').count();
    const emptyTableRow = await page.locator('#purchaseOrdersTable tbody tr td.dataTables_empty').count();
    if (rowCount === 0 || emptyTableRow > 0) {
      test.skip();
      return;
    }

    // Click the first action dropdown button
    const firstActionButton = page.locator('button.dropdown-toggle').first();
    await firstActionButton.click();

    // Wait for dropdown menu to be visible (Bootstrap adds .show class)
    await page.waitForSelector('ul.dropdown-menu.show', { timeout: 5000 });

    // Click the "Edit" option in the dropdown
    const editLink = page.locator('ul.dropdown-menu.show a.dropdown-item:has-text("Edit")').first();
    await editLink.click();

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

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

    // Modify notes if available
    const notesField = page.locator('#notes');
    await notesField.fill('Updated via E2E test');

    // Save changes
    await page.locator('button[type="submit"]').first().click();

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

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

  test('should delete purchase order with confirmation', async ({ page }) => {
    // Navigate to purchase orders list
    await navigateToPurchaseOrders(page);
    await waitForPageStable(page);

    // Wait for DataTable to load
    await page.waitForTimeout(2000);

    // Check if there are any rows in the table (excluding the "No data available" row)
    const rowCount = await page.locator('#purchaseOrdersTable tbody tr').count();
    const emptyTableRow = await page.locator('#purchaseOrdersTable tbody tr td.dataTables_empty').count();
    if (rowCount === 0 || emptyTableRow > 0) {
      test.skip();
      return;
    }

    // Click the first action dropdown button
    const firstActionButton = page.locator('button.dropdown-toggle').first();
    await firstActionButton.click();

    // Wait for dropdown menu to be visible (Bootstrap adds .show class)
    await page.waitForSelector('ul.dropdown-menu.show', { timeout: 5000 });

    // Click the "Delete" option in the dropdown
    const deleteLink = page.locator('ul.dropdown-menu.show a.dropdown-item:has-text("Delete")').first();
    await deleteLink.click();

    // Confirm SweetAlert
    await confirmSweetAlert(page);

    // Wait for deletion and DataTable reload
    await page.waitForTimeout(2000);

    // Verify we're still on the list page (use .first() for multiple cards)
    await expect(page.locator('.card').first()).toBeVisible();
  });

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

    // Click cancel button (looking for the Cancel link with btn-label-secondary class)
    const cancelButton = page.locator('a.btn-label-secondary:has-text("Cancel")').first();
    await cancelButton.click();

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

    // Verify we're back on the list page (use .first() for multiple cards)
    await expect(page.locator('.card').first()).toBeVisible();
  });
});
