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

/**
 * Holidays CRUD Tests
 *
 * Tests the Holidays management functionality including:
 * - Viewing holidays list
 * - Creating a new holiday
 * - Editing an existing holiday
 * - Deleting a holiday
 */

// Helper function to login as admin
async function loginAsAdmin(page) {
  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 });
}

// Generate unique code for tests
function generateUniqueCode() {
  return 'HOL' + Date.now().toString().slice(-5);
}

// Generate future date for holiday
function getFutureDate() {
  const date = new Date();
  date.setMonth(date.getMonth() + 1);
  return date.toISOString().split('T')[0]; // YYYY-MM-DD format
}

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

  test('should display holidays list page', async ({ page }) => {
    // Navigate to holidays page
    await page.goto('/holidays', { waitUntil: 'networkidle' });

    // Verify page elements
    await expect(page.locator('.card')).toBeVisible();
    await expect(page.locator('.datatables-holidays, #holidaysTable, table').first()).toBeVisible();

    // Verify Add New button exists
    await expect(page.locator('#btnAddHoliday, .add-new-holiday, button[data-bs-target*="holiday"], a[href*="holidays/create"]').first()).toBeVisible();
  });

  test('should open add holiday form', async ({ page }) => {
    await page.goto('/holidays', { waitUntil: 'networkidle' });

    // Click Add Holiday button (could be offcanvas or link to create page)
    const addButton = page.locator('#btnAddHoliday, .add-new-holiday, a[href*="holidays/create"], button[data-bs-target*="holiday"]').first();
    await addButton.click();

    // Wait for form to be visible (either offcanvas or new page)
    await page.waitForLoadState('networkidle');

    // Check for form fields (on current page or offcanvas)
    const nameField = page.locator('#name');
    await expect(nameField).toBeVisible({ timeout: 5000 });
  });

  test('should create a new holiday', async ({ page }) => {
    await page.goto('/holidays', { waitUntil: 'networkidle' });

    // Click Add Holiday button
    const addButton = page.locator('#btnAddHoliday, .add-new-holiday, a[href*="holidays/create"], button[data-bs-target*="holiday"]').first();
    await addButton.click();
    await page.waitForLoadState('networkidle');

    // Fill form fields
    const uniqueCode = generateUniqueCode();
    const futureDate = getFutureDate();

    await page.locator('#name').fill('Test Holiday');
    await page.locator('#code').fill(uniqueCode);
    await page.locator('#date').fill(futureDate);

    // Select type if dropdown exists
    const typeSelect = page.locator('#type');
    if (await typeSelect.isVisible()) {
      await typeSelect.selectOption('public');
    }

    // Select applicable_for if exists
    const applicableSelect = page.locator('#applicable_for');
    if (await applicableSelect.isVisible()) {
      await applicableSelect.selectOption('all');
    }

    // Submit the form
    await page.locator('button[type="submit"], .data-submit, #submitHolidayBtn').first().click();

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

    // Should redirect back to list or show success
    await page.waitForTimeout(1000);
  });

  test('should show validation error for empty required fields', async ({ page }) => {
    await page.goto('/holidays', { waitUntil: 'networkidle' });

    // Click Add Holiday button
    const addButton = page.locator('#btnAddHoliday, .add-new-holiday, a[href*="holidays/create"], button[data-bs-target*="holiday"]').first();
    await addButton.click();
    await page.waitForLoadState('networkidle');

    // Try to submit empty form
    await page.locator('button[type="submit"], .data-submit, #submitHolidayBtn').first().click();

    // Should show validation error or form should remain visible
    await page.waitForTimeout(500);
    const nameField = page.locator('#name');
    await expect(nameField).toBeVisible();
  });

  test('should close offcanvas when using holidays form on index page', async ({ page }) => {
    await page.goto('/holidays', { waitUntil: 'networkidle' });

    // If holidays uses offcanvas form, test closing it
    const offcanvas = page.locator('#holidayFormOffcanvas, [id*="offcanvas"][id*="holiday" i]').first();
    const addButton = page.locator('#btnAddHoliday, .add-new-holiday, button[data-bs-target*="holiday"]').first();

    // Check if add button opens an offcanvas (not a new page)
    if (await addButton.count() > 0) {
      await addButton.click();
      await page.waitForTimeout(500);

      // If offcanvas is visible, test closing it
      if (await offcanvas.isVisible()) {
        const closeBtn = page.locator('[data-bs-dismiss="offcanvas"]').first();
        if (await closeBtn.isVisible()) {
          await closeBtn.click();
          await page.waitForTimeout(500);
        }
      }
    }

    // Should still be on holidays page
    await expect(page).toHaveURL(/.*holidays.*/);
  });

  test('should open edit holiday form', async ({ page }) => {
    await page.goto('/holidays', { waitUntil: 'networkidle' });

    // Wait for DataTable to load
    await page.waitForSelector('.datatables-holidays tbody tr, table tbody tr', { timeout: 10000 }).catch(() => null);

    // Find and click the first edit button (may be .edit-record or in action column)
    const editButton = page.locator('.datatables-holidays tbody tr .edit-record, table tbody tr .edit-record').first();

    if (await editButton.count() > 0) {
      await editButton.click();
      await page.waitForTimeout(500);

      // Verify offcanvas/modal opens
      const offcanvas = page.locator('#offcanvasAddOrUpdateHoliday, [id*="offcanvas"][id*="holiday" i]').first();
      if (await offcanvas.isVisible()) {
        // Verify the form has pre-filled data
        const nameField = page.locator('#name').first();
        await page.waitForTimeout(500);
        const nameValue = await nameField.inputValue();
        expect(nameValue.length).toBeGreaterThan(0);

        // Close offcanvas
        await page.locator('[data-bs-dismiss="offcanvas"]').first().click();
      }
    }
  });

  test('should delete holiday with confirmation', async ({ page }) => {
    await page.goto('/holidays', { waitUntil: 'networkidle' });

    // Wait for DataTable to load
    await page.waitForSelector('.datatables-holidays tbody tr, table tbody tr', { timeout: 10000 }).catch(() => null);

    // Find the delete button
    const deleteButton = page.locator('.datatables-holidays tbody tr .delete-record, table tbody tr .delete-record').first();

    if (await deleteButton.count() > 0) {
      await deleteButton.click();

      // Wait for SweetAlert2 confirmation dialog
      await page.waitForSelector('.swal2-popup', { state: 'visible', timeout: 5000 });

      // Verify SweetAlert2 dialog content
      await expect(page.locator('.swal2-title')).toContainText('Are you sure');

      // Click Cancel to dismiss without deleting
      await page.locator('.swal2-cancel').click();
      await page.waitForTimeout(500);

      // Verify SweetAlert2 is closed
      await expect(page.locator('.swal2-popup')).toBeHidden();
    }
  });
});
