import { test, expect } from '@playwright/test';
import {
  loginAsAdmin,
  generateUniqueName,
  navigateToDeals,
  waitForPageStable,
  waitForKanbanLoad,
  confirmSweetAlert
} from '../helpers/crmcore';

/**
 * Deals CRUD Tests
 *
 * Tests the Deal management functionality including:
 * - Viewing deals pipeline page (Kanban view)
 * - Creating a deal via offcanvas form
 * - Viewing deal details
 * - Editing an existing deal
 * - Deleting a deal with confirmation
 * - Pipeline stage management
 * - Deal filtering by pipeline
 */

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

  test('should display deals pipeline page', async ({ page }) => {
    await navigateToDeals(page);

    // Verify page title
    await expect(page.locator('h4, h5').filter({ hasText: /pipeline|deals/i }).first()).toBeVisible();

    // Verify pipeline selector is visible
    const pipelineSelector = page.locator('[class*="select2"], select:has(option)').first();
    await expect(pipelineSelector).toBeVisible();

    // Verify Add Deal button exists
    const addButton = page.locator('button:has-text("Add New Deal"), #add-new-deal-btn').first();
    await expect(addButton).toBeVisible();
  });

  test('should display Kanban board with pipeline stages', async ({ page }) => {
    await navigateToDeals(page);
    await waitForKanbanLoad(page);

    // Verify stage columns are visible (Qualification, Needs Analysis, etc.)
    const qualificationColumn = page.locator('h6:has-text("Qualification")').first();
    await expect(qualificationColumn).toBeVisible();

    // Verify other stages
    const needsAnalysisColumn = page.locator('h6:has-text("Needs Analysis")').first();
    await expect(needsAnalysisColumn).toBeVisible();
  });

  test('should open deal creation form', async ({ page }) => {
    await navigateToDeals(page);
    await waitForPageStable(page);

    // Click Add New Deal button
    const addButton = page.locator('button:has-text("Add New Deal"), #add-new-deal-btn').first();
    await addButton.click();

    // Wait for offcanvas/dialog to open
    await page.waitForSelector('.offcanvas.show, dialog[open], #offcanvasDealForm.show', { timeout: 5000 });

    // Verify form fields are visible
    await expect(page.locator('#title, #name, input[name="title"], input[name="name"]').first()).toBeVisible();
  });

  test('should create deal with required fields', async ({ page }) => {
    await navigateToDeals(page);
    await waitForPageStable(page);

    // Click Add New Deal button
    const addButton = page.locator('button:has-text("Add New Deal"), #add-new-deal-btn').first();
    await addButton.click();

    // Wait for form
    await page.waitForSelector('.offcanvas.show, dialog[open]', { timeout: 5000 });
    await page.waitForTimeout(500);

    // Fill required fields
    const dealTitle = generateUniqueName('Test Deal');
    const titleField = page.locator('#title, #name, input[name="title"], input[name="name"]').first();
    await titleField.fill(dealTitle);

    // Select stage (required)
    const stageSelect = page.locator('.select2-container:has-text("Stage"), [id*="stage"]').first();
    if (await stageSelect.isVisible()) {
      await stageSelect.click();
      await page.waitForTimeout(300);
      const firstOption = page.locator('.select2-results__option').first();
      if (await firstOption.isVisible()) {
        await firstOption.click();
      }
    }

    // Submit form
    const saveButton = page.locator('button:has-text("Save Deal"), #saveDealBtn').first();
    await saveButton.click();

    // Wait for response
    await page.waitForTimeout(2000);
  });

  test('should create deal with all fields', async ({ page }) => {
    await navigateToDeals(page);
    await waitForPageStable(page);

    // Click Add New Deal button
    const addButton = page.locator('button:has-text("Add New Deal"), #add-new-deal-btn').first();
    await addButton.click();

    // Wait for form
    await page.waitForSelector('.offcanvas.show, dialog[open]', { timeout: 5000 });
    await page.waitForTimeout(500);

    // Fill all fields
    const dealTitle = generateUniqueName('Complete Deal');
    const titleField = page.locator('#title, #name, input[name="title"], input[name="name"]').first();
    await titleField.fill(dealTitle);

    // Value
    const valueField = page.locator('#value, input[name="value"]').first();
    if (await valueField.isVisible()) {
      await valueField.fill('100000');
    }

    // Probability
    const probabilityField = page.locator('#probability, input[name="probability"]').first();
    if (await probabilityField.isVisible()) {
      await probabilityField.fill('75');
    }

    // Select stage
    const stageSelect = page.locator('.select2-container:has-text("Stage"), [id*="stage"]').first();
    if (await stageSelect.isVisible()) {
      await stageSelect.click();
      await page.waitForTimeout(300);
      const firstOption = page.locator('.select2-results__option').first();
      if (await firstOption.isVisible()) {
        await firstOption.click();
      }
    }

    // Description
    const descField = page.locator('#description, textarea[name="description"]').first();
    if (await descField.isVisible()) {
      await descField.fill('Test deal with all fields filled');
    }

    // Submit form
    const saveButton = page.locator('button:has-text("Save Deal"), #saveDealBtn').first();
    await saveButton.click();

    // Wait for response
    await page.waitForTimeout(2000);
  });

  test('should view deal details', async ({ page }) => {
    await navigateToDeals(page);
    await waitForKanbanLoad(page);

    // Look for deal cards in Kanban
    const dealCards = page.locator('.kanban-item, .kanban-card, [class*="kanban"] .card h6').first();

    if (await dealCards.isVisible()) {
      // Find action dropdown on the card
      const cardDropdown = page.locator('.kanban-item .dropdown-toggle, .kanban-card .btn-icon').first();

      if (await cardDropdown.isVisible()) {
        await cardDropdown.click();
        await page.waitForTimeout(300);

        const viewButton = page.locator('.dropdown-item:has-text("View")').first();
        if (await viewButton.isVisible()) {
          await viewButton.click();
          await page.waitForURL(/\/deals\/\d+$/, { timeout: 10000 });
          await expect(page.locator('.card').first()).toBeVisible();
        }
      }
    } else {
      test.skip();
    }
  });

  test('should edit existing deal', async ({ page }) => {
    await navigateToDeals(page);
    await waitForKanbanLoad(page);

    // Look for deal cards in Kanban
    const dealCards = page.locator('.kanban-item, .kanban-card, [class*="kanban"] .card h6').first();

    if (await dealCards.isVisible()) {
      // Find action dropdown on the card
      const cardDropdown = page.locator('.kanban-item .dropdown-toggle, .kanban-card .btn-icon').first();

      if (await cardDropdown.isVisible()) {
        await cardDropdown.click();
        await page.waitForTimeout(300);

        const editButton = page.locator('.dropdown-item:has-text("Edit")').first();
        if (await editButton.isVisible()) {
          await editButton.click();

          // Wait for edit form
          await page.waitForTimeout(1000);

          // Modify title if form is visible
          const titleField = page.locator('#title, #name, input[name="title"], input[name="name"]').first();
          if (await titleField.isVisible()) {
            const updatedTitle = generateUniqueName('Updated Deal');
            await titleField.fill(updatedTitle);

            // Save
            const saveButton = page.locator('button:has-text("Save"), button:has-text("Update")').first();
            await saveButton.click();
            await page.waitForTimeout(2000);
          }
        }
      }
    } else {
      test.skip();
    }
  });

  test('should delete deal with confirmation', async ({ page }) => {
    await navigateToDeals(page);
    await waitForKanbanLoad(page);

    // Look for deal cards in Kanban
    const dealCards = page.locator('.kanban-item, .kanban-card, [class*="kanban"] .card h6').first();

    if (await dealCards.isVisible()) {
      // Find action dropdown on the card
      const cardDropdown = page.locator('.kanban-item .dropdown-toggle, .kanban-card .btn-icon').first();

      if (await cardDropdown.isVisible()) {
        await cardDropdown.click();
        await page.waitForTimeout(300);

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

          // Confirm deletion
          await confirmSweetAlert(page);
          await page.waitForTimeout(1000);

          // Page should still be functional
          await expect(page.locator('.kanban-board, [class*="kanban"]').first()).toBeVisible();
        }
      }
    } else {
      test.skip();
    }
  });

  test('should display deal value in Kanban card', async ({ page }) => {
    await navigateToDeals(page);
    await waitForKanbanLoad(page);

    // Check for deal cards with value display
    const dealCards = page.locator('.kanban-item, .kanban-card');
    const cardCount = await dealCards.count();

    if (cardCount > 0) {
      // Verify card structure includes value
      const firstCard = dealCards.first();
      await expect(firstCard).toBeVisible();

      // Look for currency/value display
      const valueDisplay = firstCard.locator(':has-text("$")').first();
      // Value might or might not be present depending on deal
    }

    // Verify Kanban structure is always present
    await expect(page.locator('.kanban-board, [class*="kanban"]').first()).toBeVisible();
  });

  test('should show stage totals in column headers', async ({ page }) => {
    await navigateToDeals(page);
    await waitForKanbanLoad(page);

    // Verify column headers show deal counts
    const columnHeaders = page.locator('h6:has-text("Qualification"), h6:has-text("Needs Analysis")');
    const headerCount = await columnHeaders.count();

    expect(headerCount).toBeGreaterThan(0);

    // Each column should have a count indicator
    const countIndicator = page.locator(':has-text("Deals"), :has-text("(0)")').first();
    await expect(countIndicator).toBeVisible();
  });

  test('should filter deals by pipeline', async ({ page }) => {
    await navigateToDeals(page);
    await waitForPageStable(page);

    // Find pipeline filter dropdown
    const pipelineFilter = page.locator('.select2-container:has-text("Pipeline"), select:has(option:has-text("Pipeline"))').first();

    if (await pipelineFilter.isVisible()) {
      await pipelineFilter.click();
      await page.waitForTimeout(300);

      // Check if there are options
      const options = page.locator('.select2-results__option');
      const optionCount = await options.count();

      if (optionCount > 0) {
        // Select first pipeline
        await options.first().click();
        await page.waitForTimeout(1000);

        // Kanban should reload
        await expect(page.locator('.kanban-board, [class*="kanban"]').first()).toBeVisible();
      }
    }
  });
});
