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

/**
 * Shifts CRUD Tests
 *
 * Tests the Shifts management functionality including:
 * - Viewing shifts list
 * - Creating a new shift
 * - Editing an existing shift
 * - Deleting a shift
 */

// 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 'TST' + Date.now().toString().slice(-6);
}

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

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

    // Verify page elements
    await expect(page.locator('.card')).toBeVisible();
    await expect(page.locator('#shiftsTable')).toBeVisible();

    // Verify Add New button exists
    await expect(page.locator('button[data-bs-target="#offcanvasAddOrUpdateShift"]')).toBeVisible();
  });

  test('should open add shift offcanvas', async ({ page }) => {
    await page.goto('/shifts', { waitUntil: 'networkidle' });

    // Click Add New Shift button
    await page.locator('button[data-bs-target="#offcanvasAddOrUpdateShift"]').click();

    // Wait for offcanvas to open
    await expect(page.locator('#offcanvasAddOrUpdateShift')).toBeVisible();

    // Verify form fields are visible
    await expect(page.locator('#shiftName')).toBeVisible();
    await expect(page.locator('#shiftCode')).toBeVisible();
    await expect(page.locator('#startTime')).toBeVisible();
    await expect(page.locator('#endTime')).toBeVisible();
  });

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

    // Open add shift offcanvas
    await page.locator('button[data-bs-target="#offcanvasAddOrUpdateShift"]').click();
    await expect(page.locator('#offcanvasAddOrUpdateShift')).toBeVisible();

    // Fill form fields
    const uniqueCode = generateUniqueCode();
    await page.locator('#shiftName').fill('Test Morning Shift');
    await page.locator('#shiftCode').fill(uniqueCode);

    // Flatpickr inputs are readonly, use JavaScript to set values
    await page.evaluate(() => {
      const startInput = document.querySelector('#startTime') as HTMLInputElement;
      const endInput = document.querySelector('#endTime') as HTMLInputElement;
      if (startInput) {
        startInput.value = '09:00';
        startInput.dispatchEvent(new Event('change', { bubbles: true }));
      }
      if (endInput) {
        endInput.value = '17:00';
        endInput.dispatchEvent(new Event('change', { bubbles: true }));
      }
    });

    // Ensure at least one working day is selected (Monday is default)
    const mondayCheckbox = page.locator('#mondayToggle');
    if (!(await mondayCheckbox.isChecked())) {
      await mondayCheckbox.check();
    }

    // Submit the form
    await page.locator('#submitShiftBtn').click();

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

    // Verify success - offcanvas should close or success message shown
    // Check that DataTable reloads with new data
    await page.waitForTimeout(1000); // Allow DataTable to reload
    await expect(page.locator('#shiftsTable')).toBeVisible();
  });

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

    // Open add shift offcanvas
    await page.locator('button[data-bs-target="#offcanvasAddOrUpdateShift"]').click();
    await expect(page.locator('#offcanvasAddOrUpdateShift')).toBeVisible();

    // Try to submit empty form
    await page.locator('#submitShiftBtn').click();

    // Form should remain open (validation failed)
    await page.waitForTimeout(500);
    await expect(page.locator('#offcanvasAddOrUpdateShift')).toBeVisible();
    // Check that the offcanvas is still showing (form didn't submit successfully)
    await expect(page.locator('#shiftForm')).toBeVisible();
  });

  test('should close offcanvas on cancel', async ({ page }) => {
    await page.goto('/shifts', { waitUntil: 'networkidle' });

    // Open add shift offcanvas
    await page.locator('button[data-bs-target="#offcanvasAddOrUpdateShift"]').click();
    await expect(page.locator('#offcanvasAddOrUpdateShift')).toBeVisible();

    // Click cancel/close button
    await page.locator('#offcanvasAddOrUpdateShift button[data-bs-dismiss="offcanvas"]').first().click();

    // Verify offcanvas is hidden
    await expect(page.locator('#offcanvasAddOrUpdateShift')).toBeHidden({ timeout: 5000 });
  });

  test('should open edit shift offcanvas', async ({ page }) => {
    await page.goto('/shifts', { waitUntil: 'networkidle' });

    // Wait for DataTable to load
    await page.waitForSelector('#shiftsTable tbody tr', { timeout: 10000 });

    // Find the edit button (onclick="editShift(id)" pattern)
    const editButton = page.locator('#shiftsTable tbody tr button[onclick*="editShift"]').first();

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

      // Verify offcanvas opens
      await expect(page.locator('#offcanvasAddOrUpdateShift')).toBeVisible();

      // Verify the form has pre-filled data
      const nameField = page.locator('#shiftName');
      await page.waitForTimeout(500);
      const nameValue = await nameField.inputValue();
      expect(nameValue.length).toBeGreaterThan(0);

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

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

    // Wait for DataTable to load
    await page.waitForSelector('#shiftsTable tbody tr', { timeout: 10000 });

    // Find the delete button (onclick="deleteShift(id)" pattern)
    const deleteButton = page.locator('#shiftsTable tbody tr button[onclick*="deleteShift"]').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 is shown
      await expect(page.locator('.swal2-popup')).toBeVisible();

      // 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();
    }
  });
});
