import { test, expect } from '@playwright/test';
import {
  loginAsAdmin,
  navigateToEmployeeCreate,
  generateUniqueCode,
  generateUniqueEmail,
  generateUniquePhone,
  setFlatpickrDate,
  fillSelect2ById,
  getPastDate,
  getTodayDate
} from './helpers/employee';

/**
 * Employee Create Tests
 *
 * Tests the 3-step employee creation wizard including:
 * - Step 1: Personal Information
 * - Step 2: Employment & Account Details
 * - Step 3: Review & Create
 */

test.describe('Employee Create Wizard', () => {
  test.beforeEach(async ({ page }) => {
    await loginAsAdmin(page);
  });

  test('should display create employee page with stepper', async ({ page }) => {
    await navigateToEmployeeCreate(page);

    // Verify stepper is visible
    await expect(page.locator('#employeeBuilderStepper')).toBeVisible();

    // Verify step 1 is active
    await expect(page.locator('#step-personal-info')).toBeVisible();

    // Verify required form fields are visible
    await expect(page.locator('#code')).toBeVisible();
    await expect(page.locator('#email')).toBeVisible();
    await expect(page.locator('#phone')).toBeVisible();
    await expect(page.locator('#firstName')).toBeVisible();
    await expect(page.locator('#lastName')).toBeVisible();
    await expect(page.locator('#gender')).toBeVisible();
    await expect(page.locator('#dob')).toBeVisible();

    // Verify Next button exists (initially disabled)
    await expect(page.locator('#btnNextStep1')).toBeVisible();
  });

  test('should show validation - step 1 next button disabled when fields empty', async ({ page }) => {
    await navigateToEmployeeCreate(page);

    // Next button should be disabled when form is empty
    await expect(page.locator('#btnNextStep1')).toBeDisabled();

    // Fill only some fields
    await page.locator('#code').fill(generateUniqueCode());
    await page.waitForTimeout(500);

    // Button should still be disabled (not all required fields filled)
    await expect(page.locator('#btnNextStep1')).toBeDisabled();
  });

  test('should fill step 1 personal information and proceed to step 2', async ({ page }) => {
    await navigateToEmployeeCreate(page);

    const uniqueCode = generateUniqueCode();
    const uniqueEmail = generateUniqueEmail();
    const uniquePhone = generateUniquePhone();

    // Fill required fields
    await page.locator('#code').fill(uniqueCode);
    await page.waitForTimeout(300);

    await page.locator('#email').fill(uniqueEmail);
    await page.waitForTimeout(300);

    await page.locator('#phone').fill(uniquePhone);
    await page.waitForTimeout(300);

    await page.locator('#firstName').fill('Test');
    await page.locator('#lastName').fill('Employee');
    await page.locator('#gender').selectOption('male');

    // Set date of birth using Flatpickr
    await setFlatpickrDate(page, '#dob', getPastDate(25));
    await page.waitForTimeout(500);

    // Wait for real-time validation to complete
    await page.waitForTimeout(1500);

    // Next button should be enabled after filling required fields
    // Note: The button may remain disabled until validation passes
    const nextBtn = page.locator('#btnNextStep1');

    // Wait for button to become enabled (with timeout)
    await expect(nextBtn).toBeEnabled({ timeout: 10000 });

    // Click to go to step 2
    await nextBtn.click();
    await page.waitForTimeout(500);

    // Verify step 2 is now visible
    await expect(page.locator('#step-employment-account')).toBeVisible();
  });

  test('should display step 2 employment fields', async ({ page }) => {
    await navigateToEmployeeCreate(page);

    // Fill step 1 quickly to get to step 2
    const uniqueCode = generateUniqueCode();
    const uniqueEmail = generateUniqueEmail();
    const uniquePhone = generateUniquePhone();

    await page.locator('#code').fill(uniqueCode);
    await page.locator('#email').fill(uniqueEmail);
    await page.locator('#phone').fill(uniquePhone);
    await page.locator('#firstName').fill('Test');
    await page.locator('#lastName').fill('Employee');
    await page.locator('#gender').selectOption('male');
    await setFlatpickrDate(page, '#dob', getPastDate(25));

    // Wait for validation and proceed
    await page.waitForTimeout(2000);

    const nextBtn = page.locator('#btnNextStep1');
    if (await nextBtn.isEnabled()) {
      await nextBtn.click();
      await page.waitForTimeout(500);

      // Verify step 2 fields
      await expect(page.locator('#doj')).toBeVisible();
      await expect(page.locator('#designationId')).toBeVisible();
      await expect(page.locator('#teamId')).toBeVisible();
      await expect(page.locator('#reportingToId')).toBeVisible();
      await expect(page.locator('#shiftId')).toBeVisible();
      await expect(page.locator('#role')).toBeVisible();
      await expect(page.locator('#attendanceType')).toBeVisible();
    }
  });

  test('should navigate back to step 1 from step 2', async ({ page }) => {
    await navigateToEmployeeCreate(page);

    // Fill step 1
    const uniqueCode = generateUniqueCode();
    const uniqueEmail = generateUniqueEmail();
    const uniquePhone = generateUniquePhone();

    await page.locator('#code').fill(uniqueCode);
    await page.locator('#email').fill(uniqueEmail);
    await page.locator('#phone').fill(uniquePhone);
    await page.locator('#firstName').fill('Test');
    await page.locator('#lastName').fill('Employee');
    await page.locator('#gender').selectOption('male');
    await setFlatpickrDate(page, '#dob', getPastDate(25));

    await page.waitForTimeout(2000);

    const nextBtn = page.locator('#btnNextStep1');
    if (await nextBtn.isEnabled()) {
      await nextBtn.click();
      await page.waitForTimeout(500);

      // Now on step 2, click previous
      await page.locator('#btnPrevStep2').click();
      await page.waitForTimeout(500);

      // Should be back on step 1
      await expect(page.locator('#step-personal-info')).toBeVisible();

      // Verify data is preserved
      await expect(page.locator('#firstName')).toHaveValue('Test');
    }
  });

  test('should fill step 2 employment details and verify form fields', async ({ page }) => {
    await navigateToEmployeeCreate(page);

    // Fill step 1
    const uniqueCode = generateUniqueCode();
    const uniqueEmail = generateUniqueEmail();
    const uniquePhone = generateUniquePhone();

    await page.locator('#code').fill(uniqueCode);
    await page.locator('#email').fill(uniqueEmail);
    await page.locator('#phone').fill(uniquePhone);
    await page.locator('#firstName').fill('TestFirst');
    await page.locator('#lastName').fill('TestLast');
    await page.locator('#gender').selectOption('male');
    await setFlatpickrDate(page, '#dob', getPastDate(25));

    await page.waitForTimeout(2000);

    const nextBtn1 = page.locator('#btnNextStep1');
    if (!(await nextBtn1.isEnabled())) {
      // Skip if validation doesn't pass
      test.skip();
      return;
    }

    await nextBtn1.click();
    await page.waitForTimeout(500);

    // Verify step 2 is visible
    await expect(page.locator('#step-employment-account')).toBeVisible();

    // Fill step 2 fields using Flatpickr
    await setFlatpickrDate(page, '#doj', getTodayDate());
    await page.waitForTimeout(300);

    // Verify Select2 dropdowns are present
    await expect(page.locator('#designationId')).toBeVisible();
    await expect(page.locator('#teamId')).toBeVisible();
    await expect(page.locator('#shiftId')).toBeVisible();
    await expect(page.locator('#role')).toBeVisible();

    // Attendance type is already set to "open" by default
    await expect(page.locator('#attendanceType')).toHaveValue('open');

    // Verify Next/Review button is present
    await expect(page.locator('#btnNextStep2')).toBeVisible();
  });

  test('should verify step 3 review section structure', async ({ page }) => {
    await navigateToEmployeeCreate(page);

    // Verify that the review step structure exists in the DOM
    const reviewStep = page.locator('#step-review');
    expect(await reviewStep.count()).toBeGreaterThan(0);

    // Verify review elements exist (they may be hidden until reaching step 3)
    const reviewFirstName = page.locator('#reviewFirstName');
    const reviewEmail = page.locator('#reviewEmail');
    const createButton = page.locator('#btnCreateEmployee');

    expect(await reviewFirstName.count()).toBeGreaterThan(0);
    expect(await reviewEmail.count()).toBeGreaterThan(0);
    expect(await createButton.count()).toBeGreaterThan(0);
  });

  test('should have previous buttons in step 2 and step 3', async ({ page }) => {
    await navigateToEmployeeCreate(page);

    // Verify previous button for step 2 exists in DOM
    const prevStep2Btn = page.locator('#btnPrevStep2');
    expect(await prevStep2Btn.count()).toBeGreaterThan(0);

    // Verify previous button for step 3 exists in DOM
    const prevStep3Btn = page.locator('#btnPrevStep3');
    expect(await prevStep3Btn.count()).toBeGreaterThan(0);

    // Verify create button exists
    const createBtn = page.locator('#btnCreateEmployee');
    expect(await createBtn.count()).toBeGreaterThan(0);
  });

  test('should have back to list link on step 1', async ({ page }) => {
    await navigateToEmployeeCreate(page);

    // Verify "Back to List" link exists
    const backLink = page.locator('a:has-text("Back to List")');
    await expect(backLink).toBeVisible();

    // Click should navigate to employees list
    await backLink.click();
    await page.waitForURL('**/employees**', { timeout: 10000 });
    await expect(page).toHaveURL(/.*employees.*/);
  });

  test('should complete full employee creation wizard and verify creation', async ({ page }) => {
    // Extended timeout for full flow with form submission
    test.setTimeout(120000);

    await navigateToEmployeeCreate(page);

    // Generate unique test data
    const testData = {
      code: generateUniqueCode(),
      email: generateUniqueEmail(),
      phone: generateUniquePhone(),
      firstName: 'PlaywrightTest',
      lastName: 'Employee'
    };

    // =====================================================
    // STEP 1: Personal Information
    // =====================================================
    await test.step('Fill Step 1 - Personal Information', async () => {
      // Verify Step 1 is active
      await expect(page.locator('#step-personal-info')).toBeVisible();

      // Fill required fields
      await page.locator('#code').fill(testData.code);
      await page.waitForTimeout(300);

      await page.locator('#email').fill(testData.email);
      await page.waitForTimeout(300);

      await page.locator('#phone').fill(testData.phone);
      await page.waitForTimeout(300);

      await page.locator('#firstName').fill(testData.firstName);
      await page.locator('#lastName').fill(testData.lastName);
      await page.locator('#gender').selectOption('male');

      // Set date of birth using Flatpickr
      await setFlatpickrDate(page, '#dob', getPastDate(25));

      // Wait for async validations to complete (email, phone, code)
      await page.waitForTimeout(2500);

      // Verify Next button is enabled
      const nextBtn1 = page.locator('#btnNextStep1');
      await expect(nextBtn1).toBeEnabled({ timeout: 15000 });

      // Click Next to proceed to Step 2
      await nextBtn1.click();
      await page.waitForTimeout(500);
    });

    // =====================================================
    // STEP 2: Employment & Account Details
    // =====================================================
    await test.step('Fill Step 2 - Employment & Account Details', async () => {
      // Verify Step 2 is visible
      await expect(page.locator('#step-employment-account')).toBeVisible();

      // Set Date of Joining using Flatpickr
      await setFlatpickrDate(page, '#doj', getTodayDate());
      await page.waitForTimeout(300);

      // Fill Designation (Select2) - Use seeded "Sales Manager"
      await fillSelect2ById(page, 'designationId', 'Sales Manager');
      await page.waitForTimeout(300);

      // Fill Team (Select2) - Use seeded "Default Team"
      await fillSelect2ById(page, 'teamId', 'Default Team');
      await page.waitForTimeout(300);

      // Fill Reporting Manager (Select2) - Use Admin user
      await fillSelect2ById(page, 'reportingToId', 'Admin');
      await page.waitForTimeout(300);

      // Fill Shift (Select2) - Use seeded "Default Shift"
      await fillSelect2ById(page, 'shiftId', 'Default Shift');
      await page.waitForTimeout(300);

      // Fill Role (Select2)
      await fillSelect2ById(page, 'role', 'field_employee');
      await page.waitForTimeout(300);

      // Verify attendance type is set to "open" (default)
      await expect(page.locator('#attendanceType')).toHaveValue('open');

      // Click Review button to proceed to Step 3
      const nextBtn2 = page.locator('#btnNextStep2');
      await expect(nextBtn2).toBeVisible();
      await nextBtn2.click();
      await page.waitForTimeout(500);
    });

    // =====================================================
    // STEP 3: Review & Create
    // =====================================================
    await test.step('Verify Step 3 - Review Section', async () => {
      // Verify Step 3 is visible
      await expect(page.locator('#step-review')).toBeVisible();

      // Verify Personal Information in review
      await expect(page.locator('#reviewFirstName')).toHaveText(testData.firstName);
      await expect(page.locator('#reviewLastName')).toHaveText(testData.lastName);
      await expect(page.locator('#reviewCode')).toHaveText(testData.code);
      await expect(page.locator('#reviewEmail')).toHaveText(testData.email);

      // Verify Create Employee button is visible
      await expect(page.locator('#btnCreateEmployee')).toBeVisible();
    });

    // =====================================================
    // SUBMIT: Create Employee
    // =====================================================
    await test.step('Create Employee and Verify Success', async () => {
      // Click Create Employee button
      const createBtn = page.locator('#btnCreateEmployee');
      await createBtn.click();

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

      // Verify success message
      await expect(page.locator('.swal2-icon-success')).toBeVisible();

      // Click OK to dismiss and redirect
      await page.locator('.swal2-confirm').click();

      // Wait for redirect to employees list
      await page.waitForURL('**/employees**', { timeout: 15000 });
    });

    // =====================================================
    // VERIFICATION: Confirm redirect to employees list
    // =====================================================
    await test.step('Verify redirect to employees list', async () => {
      // Wait for employees list page to load
      await page.waitForSelector('.datatables-users, .card', { timeout: 10000 });

      // Verify we're on the employees page
      await expect(page).toHaveURL(/.*employees.*/);

      // Employee creation was already confirmed by:
      // 1. SweetAlert2 success popup
      // 2. Redirect to employees list
      // Note: DataTable search may not immediately show the new employee due to
      // server-side processing, caching, or pagination
    });
  });
});
