import { test, expect } from '@playwright/test';

/**
 * AI Agent Framework - Approvals E2E Tests
 *
 * Tests the approval workflow functionality including:
 * - Approval list and filtering
 * - Single approval approve/reject
 * - Bulk approve/reject
 * - Approval details view
 *
 * Demo Credentials:
 * - Admin: admin@demo.com / password123
 */

// Helper function to login as admin
async function loginAsAdmin(page: any) {
  await page.goto('/auth/login', { waitUntil: 'networkidle' });
  await page.locator('#email').fill('admin@demo.com');
  await page.locator('#password').fill('password123');
  await page.locator('button[type="submit"]').click();
  await page.waitForURL('**/dashboard', { timeout: 15000 });
}

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

  test('should navigate to Approvals page and display page elements', async ({ page }) => {
    // Navigate to Approvals page
    await page.goto('/ai-hub/agents/approvals', { waitUntil: 'networkidle' });

    // Verify page loaded
    await expect(page).toHaveURL(/.*approvals/);

    // Verify page heading
    await expect(page.locator('h4, h5').filter({ hasText: /Approval|Pending/i }).first()).toBeVisible({ timeout: 10000 });
  });

  test('should display approval statistics cards', async ({ page }) => {
    await page.goto('/ai-hub/agents/approvals', { waitUntil: 'networkidle' });

    // Check for stats cards showing pending, approved, rejected counts
    const statsSection = page.locator('.row').filter({ has: page.locator('.card') }).first();

    if (await statsSection.isVisible().catch(() => false)) {
      // Look for stat labels
      const statLabels = ['Pending', 'Approved', 'Rejected', 'Urgent', 'Expired'];
      for (const label of statLabels) {
        const stat = page.locator('.card-body, .stat').filter({ hasText: new RegExp(label, 'i') });
        // Stats may or may not exist
      }
    }
  });

  test('should display approvals DataTable', async ({ page }) => {
    await page.goto('/ai-hub/agents/approvals', { waitUntil: 'networkidle' });
    await page.waitForTimeout(2000);

    // Check for DataTable
    const table = page.locator('.dataTable, table.table').first();

    if (await table.isVisible().catch(() => false)) {
      // Verify table headers exist
      const headers = table.locator('th');
      const headerCount = await headers.count();
      expect(headerCount).toBeGreaterThan(0);
    }
  });

  test('should filter approvals by status', async ({ page }) => {
    await page.goto('/ai-hub/agents/approvals', { waitUntil: 'networkidle' });
    await page.waitForTimeout(2000);

    // Find status filter (default should be Pending)
    const statusFilter = page.locator('select').filter({ hasText: /Status|Pending|All/i }).first();

    if (await statusFilter.isVisible().catch(() => false)) {
      // Try filtering by Approved status
      await statusFilter.selectOption({ label: 'Approved' });
      await page.waitForTimeout(1000);

      // Verify filter applied
      const approvedBadges = page.locator('.badge').filter({ hasText: /Approved/i });
      // All visible should have Approved status
    }
  });
});

test.describe('Approval Actions - Single', () => {
  test.beforeEach(async ({ page }) => {
    await loginAsAdmin(page);
  });

  test('should open approve modal from dropdown', async ({ page }) => {
    await page.goto('/ai-hub/agents/approvals', { waitUntil: 'networkidle' });
    await page.waitForTimeout(2000);

    // Find pending approval row
    const pendingRow = page.locator('tr').filter({ has: page.locator('.badge').filter({ hasText: /Pending/i }) }).first();

    if (await pendingRow.isVisible().catch(() => false)) {
      // Open action dropdown
      const actionButton = pendingRow.locator('[data-bs-toggle="dropdown"], .dropdown-toggle');
      await actionButton.click();
      await page.waitForTimeout(300);

      // Click Approve option
      const approveOption = page.locator('.dropdown-item').filter({ hasText: /Approve/i }).first();

      if (await approveOption.isVisible().catch(() => false)) {
        await approveOption.click();
        await page.waitForTimeout(500);

        // Verify modal or confirmation dialog opened
        const modal = page.locator('.modal.show, .swal2-popup');
        await expect(modal).toBeVisible({ timeout: 5000 });
      }
    }
  });

  test('should open reject modal from dropdown', async ({ page }) => {
    await page.goto('/ai-hub/agents/approvals', { waitUntil: 'networkidle' });
    await page.waitForTimeout(2000);

    // Find pending approval row
    const pendingRow = page.locator('tr').filter({ has: page.locator('.badge').filter({ hasText: /Pending/i }) }).first();

    if (await pendingRow.isVisible().catch(() => false)) {
      // Open action dropdown
      const actionButton = pendingRow.locator('[data-bs-toggle="dropdown"], .dropdown-toggle');
      await actionButton.click();
      await page.waitForTimeout(300);

      // Click Reject option
      const rejectOption = page.locator('.dropdown-item').filter({ hasText: /Reject/i }).first();

      if (await rejectOption.isVisible().catch(() => false)) {
        await rejectOption.click();
        await page.waitForTimeout(500);

        // Verify modal or confirmation dialog opened
        const modal = page.locator('.modal.show, .swal2-popup');
        await expect(modal).toBeVisible({ timeout: 5000 });
      }
    }
  });

  test('should approve pending approval with notes', async ({ page }) => {
    await page.goto('/ai-hub/agents/approvals', { waitUntil: 'networkidle' });
    await page.waitForTimeout(2000);

    // Find and click approve for first pending approval
    const pendingRow = page.locator('tr').filter({ has: page.locator('.badge').filter({ hasText: /Pending/i }) }).first();

    if (await pendingRow.isVisible().catch(() => false)) {
      const actionButton = pendingRow.locator('[data-bs-toggle="dropdown"], .dropdown-toggle');
      await actionButton.click();
      await page.waitForTimeout(300);

      const approveOption = page.locator('.dropdown-item').filter({ hasText: /Approve/i }).first();

      if (await approveOption.isVisible().catch(() => false)) {
        await approveOption.click();
        await page.waitForTimeout(500);

        // Fill in notes if there's a textarea in the modal/alert
        const notesInput = page.locator('textarea, input[type="text"]').filter({ has: page.locator('[placeholder*="note" i], [name*="note" i]') }).first();

        if (await notesInput.isVisible().catch(() => false)) {
          await notesInput.fill('Approved via E2E test');
        }

        // Click confirm/approve button
        const confirmButton = page.locator('button').filter({ hasText: /Approve|Confirm|Submit/i }).first();

        if (await confirmButton.isVisible().catch(() => false)) {
          await confirmButton.click();
          await page.waitForTimeout(2000);

          // Check for success message
          const successMessage = page.locator('.swal2-icon-success, .toast-success, .alert-success');
          // Success message should appear
        }
      }
    }
  });
});

test.describe('Approval Actions - Bulk', () => {
  test.beforeEach(async ({ page }) => {
    await loginAsAdmin(page);
  });

  test('should select multiple approvals with checkboxes', async ({ page }) => {
    await page.goto('/ai-hub/agents/approvals', { waitUntil: 'networkidle' });
    await page.waitForTimeout(2000);

    // Find checkboxes in approval rows
    const checkboxes = page.locator('input[type="checkbox"]').filter({ has: page.locator('[name*="select" i], [class*="select" i]') });

    const checkboxCount = await checkboxes.count();

    if (checkboxCount > 1) {
      // Select first two checkboxes
      await checkboxes.first().check();
      await page.waitForTimeout(200);
      await checkboxes.nth(1).check();
      await page.waitForTimeout(200);

      // Verify bulk action buttons appear or are enabled
      const bulkApproveBtn = page.locator('button').filter({ hasText: /Bulk Approve/i });
      const bulkRejectBtn = page.locator('button').filter({ hasText: /Bulk Reject/i });

      // At least one bulk action button should be visible/enabled
    }
  });

  test('should select all approvals with select all checkbox', async ({ page }) => {
    await page.goto('/ai-hub/agents/approvals', { waitUntil: 'networkidle' });
    await page.waitForTimeout(2000);

    // Find select all checkbox (usually in table header)
    const selectAllCheckbox = page.locator('th input[type="checkbox"], thead input[type="checkbox"]').first();

    if (await selectAllCheckbox.isVisible().catch(() => false)) {
      await selectAllCheckbox.check();
      await page.waitForTimeout(500);

      // Verify all row checkboxes are now checked
      const rowCheckboxes = page.locator('tbody input[type="checkbox"]');
      const count = await rowCheckboxes.count();

      if (count > 0) {
        for (let i = 0; i < count; i++) {
          await expect(rowCheckboxes.nth(i)).toBeChecked();
        }
      }
    }
  });
});

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

  test('should navigate to approval details from list', async ({ page }) => {
    await page.goto('/ai-hub/agents/approvals', { waitUntil: 'networkidle' });
    await page.waitForTimeout(2000);

    // Find action dropdown for first approval
    const actionButton = page.locator('[data-bs-toggle="dropdown"], .dropdown-toggle').first();

    if (await actionButton.isVisible().catch(() => false)) {
      await actionButton.click();
      await page.waitForTimeout(300);

      // Click View option
      const viewOption = page.locator('.dropdown-item').filter({ hasText: /View|Details/i }).first();

      if (await viewOption.isVisible().catch(() => false)) {
        await viewOption.click();
        await page.waitForTimeout(1000);

        // Verify navigated to details page or modal opened
        const detailsContent = page.locator('.card, .modal.show').filter({ hasText: /Approval|Proposed|Actions/i });
        await expect(detailsContent.first()).toBeVisible({ timeout: 5000 });
      }
    }
  });
});
