import { test, expect } from '@playwright/test';
import { loginAsAdmin } from './helpers/employee';

/**
 * Employee Lifecycle Tests
 *
 * Tests the employee lifecycle management functionality including:
 * - Probation management (confirm, extend, fail)
 * - Termination process
 * - Suspension and reactivation
 * - Status-based action visibility
 */

// Find the first employee ID from the list to use for testing
async function getFirstEmployeeId(page): Promise<number | null> {
  await page.goto('/employees', { waitUntil: 'networkidle' });
  await page.waitForTimeout(1000);

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

  // Try to find a view link in the table
  const viewLink = page.locator('.datatables-users tbody tr:first-child a[href*="employees/view"]').first();

  if (await viewLink.count() > 0) {
    const href = await viewLink.getAttribute('href');
    if (href) {
      const match = href.match(/employees\/view\/(\d+)/);
      if (match) {
        return parseInt(match[1]);
      }
    }
  }

  return null;
}

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

  test('should display actions dropdown for active employee', async ({ page }) => {
    const employeeId = await getFirstEmployeeId(page);

    if (!employeeId) {
      test.skip();
      return;
    }

    await page.goto(`/employees/view/${employeeId}`, { waitUntil: 'networkidle' });

    // Check for Actions dropdown (available for non-exited employees)
    const actionsBtn = page.locator('button.dropdown-toggle:has-text("Actions")');

    if (await actionsBtn.count() > 0) {
      await actionsBtn.click();
      await page.waitForTimeout(300);

      // Verify dropdown is open and has action items
      const dropdown = page.locator('.dropdown-menu.show');
      await expect(dropdown).toBeVisible();

      // Close dropdown
      await page.click('body');
    }
  });

  test('should display probation alert for employee under probation', async ({ page }) => {
    const employeeId = await getFirstEmployeeId(page);

    if (!employeeId) {
      test.skip();
      return;
    }

    await page.goto(`/employees/view/${employeeId}`, { waitUntil: 'networkidle' });

    // Check if probation alert is visible (for employees under probation)
    const probationAlert = page.locator('.alert:has-text("Probation")');

    if (await probationAlert.count() > 0) {
      await expect(probationAlert).toBeVisible();

      // Probation alert should have action buttons
      await expect(page.locator('button[data-bs-target="#confirmProbationOffcanvas"]').or(
        page.locator('a[data-bs-target="#confirmProbationOffcanvas"]')
      ).first()).toBeVisible();
    }
    // If no probation alert, the employee is not on probation - that's okay
  });

  test('should open confirm probation offcanvas', async ({ page }) => {
    const employeeId = await getFirstEmployeeId(page);

    if (!employeeId) {
      test.skip();
      return;
    }

    await page.goto(`/employees/view/${employeeId}`, { waitUntil: 'networkidle' });

    // Check if confirm probation button exists (either in alert or Actions dropdown)
    const confirmBtn = page.locator('[data-bs-target="#confirmProbationOffcanvas"]').first();

    if (await confirmBtn.count() === 0) {
      // Try via Actions dropdown for probation employees
      const actionsBtn = page.locator('button.dropdown-toggle:has-text("Actions")');
      if (await actionsBtn.count() > 0) {
        await actionsBtn.click();
        await page.waitForTimeout(300);
      }
    }

    const confirmBtnInDropdown = page.locator('[data-bs-target="#confirmProbationOffcanvas"]').first();

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

      // Verify offcanvas is visible
      await expect(page.locator('#confirmProbationOffcanvas')).toBeVisible();

      // Close it
      await page.click('#confirmProbationOffcanvas button[data-bs-dismiss="offcanvas"]');
      await page.waitForTimeout(500);
    }
  });

  test('should open extend probation offcanvas', async ({ page }) => {
    const employeeId = await getFirstEmployeeId(page);

    if (!employeeId) {
      test.skip();
      return;
    }

    await page.goto(`/employees/view/${employeeId}`, { waitUntil: 'networkidle' });

    // Check for extend probation button
    const extendBtn = page.locator('[data-bs-target="#extendProbationOffcanvas"]').first();

    if (await extendBtn.count() === 0) {
      // Try via Actions dropdown
      const actionsBtn = page.locator('button.dropdown-toggle:has-text("Actions")');
      if (await actionsBtn.count() > 0) {
        await actionsBtn.click();
        await page.waitForTimeout(300);
      }
    }

    const extendBtnInDropdown = page.locator('[data-bs-target="#extendProbationOffcanvas"]').first();

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

      // Verify offcanvas is visible
      await expect(page.locator('#extendProbationOffcanvas')).toBeVisible();

      // Verify required fields
      await expect(page.locator('#newProbationEndDate')).toBeVisible();
      await expect(page.locator('#extendReason')).toBeVisible();

      // Close it
      await page.click('#extendProbationOffcanvas button[data-bs-dismiss="offcanvas"]');
      await page.waitForTimeout(500);
    }
  });

  test('should open fail probation offcanvas', async ({ page }) => {
    const employeeId = await getFirstEmployeeId(page);

    if (!employeeId) {
      test.skip();
      return;
    }

    await page.goto(`/employees/view/${employeeId}`, { waitUntil: 'networkidle' });

    // Check for fail probation button
    const failBtn = page.locator('[data-bs-target="#failProbationOffcanvas"]').first();

    if (await failBtn.count() === 0) {
      // Try via Actions dropdown
      const actionsBtn = page.locator('button.dropdown-toggle:has-text("Actions")');
      if (await actionsBtn.count() > 0) {
        await actionsBtn.click();
        await page.waitForTimeout(300);
      }
    }

    const failBtnInDropdown = page.locator('[data-bs-target="#failProbationOffcanvas"]').first();

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

      // Verify offcanvas is visible
      await expect(page.locator('#failProbationOffcanvas')).toBeVisible();

      // Verify required field
      await expect(page.locator('#failReason')).toBeVisible();

      // Close it
      await page.click('#failProbationOffcanvas button[data-bs-dismiss="offcanvas"]');
      await page.waitForTimeout(500);
    }
  });

  test('should open terminate employee modal', async ({ page }) => {
    const employeeId = await getFirstEmployeeId(page);

    if (!employeeId) {
      test.skip();
      return;
    }

    await page.goto(`/employees/view/${employeeId}`, { waitUntil: 'networkidle' });

    // Check for Actions dropdown
    const actionsBtn = page.locator('button.dropdown-toggle:has-text("Actions")');

    if (await actionsBtn.count() === 0) {
      test.skip(); // No actions available (likely exited employee)
      return;
    }

    await actionsBtn.click();
    await page.waitForTimeout(300);

    // Look for terminate option
    const terminateOption = page.locator('[data-bs-target="#terminateEmployeeModal"]').first();

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

      // Verify modal is visible
      await expect(page.locator('#terminateEmployeeModal')).toBeVisible();

      // Verify form fields
      await expect(page.locator('#terminationType')).toBeVisible();
      await expect(page.locator('#exitDate')).toBeVisible();
      await expect(page.locator('#lastWorkingDay')).toBeVisible();
      await expect(page.locator('#exitReason')).toBeVisible();

      // Close modal
      await page.click('#terminateEmployeeModal button[data-bs-dismiss="modal"]');
      await page.waitForTimeout(500);
    }
  });

  test('should display terminate form fields correctly', async ({ page }) => {
    const employeeId = await getFirstEmployeeId(page);

    if (!employeeId) {
      test.skip();
      return;
    }

    await page.goto(`/employees/view/${employeeId}`, { waitUntil: 'networkidle' });

    const actionsBtn = page.locator('button.dropdown-toggle:has-text("Actions")');

    if (await actionsBtn.count() === 0) {
      test.skip();
      return;
    }

    await actionsBtn.click();
    await page.waitForTimeout(300);

    const terminateOption = page.locator('[data-bs-target="#terminateEmployeeModal"]').first();

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

      // Verify termination type has options
      const terminationTypeSelect = page.locator('#terminationType');
      await expect(terminationTypeSelect).toBeVisible();

      // Verify eligible for rehire checkbox
      await expect(page.locator('#isEligibleForRehire')).toBeVisible();

      // Close modal
      await page.click('#terminateEmployeeModal button[data-bs-dismiss="modal"]');
    }
  });

  test('should show status-based alerts for suspended employee', async ({ page }) => {
    // This test verifies the suspended employee alert displays correctly
    // It will only pass if there's a suspended employee in the system
    const employeeId = await getFirstEmployeeId(page);

    if (!employeeId) {
      test.skip();
      return;
    }

    await page.goto(`/employees/view/${employeeId}`, { waitUntil: 'networkidle' });

    // Check for suspended alert
    const suspendedAlert = page.locator('.alert-danger:has-text("Suspended")');

    if (await suspendedAlert.count() > 0) {
      await expect(suspendedAlert).toBeVisible();

      // Check for reactivate option in actions
      const actionsBtn = page.locator('button.dropdown-toggle:has-text("Actions")');
      if (await actionsBtn.count() > 0) {
        await actionsBtn.click();
        await page.waitForTimeout(300);

        const reactivateOption = page.locator('.dropdown-item:has-text("Reactivate")');
        await expect(reactivateOption).toBeVisible();
      }
    }
  });

  test('should show status-based alerts for terminated employee', async ({ page }) => {
    // This test verifies the terminated employee alert displays correctly
    const employeeId = await getFirstEmployeeId(page);

    if (!employeeId) {
      test.skip();
      return;
    }

    await page.goto(`/employees/view/${employeeId}`, { waitUntil: 'networkidle' });

    // Check for terminated/exited alert
    const terminatedAlert = page.locator('.alert:has-text("Terminated"), .alert:has-text("Relieved"), .alert:has-text("Retired")');

    if (await terminatedAlert.count() > 0) {
      await expect(terminatedAlert.first()).toBeVisible();

      // For terminated employees, check for "Mark as Relieved" button
      const relievedBtn = page.locator('button:has-text("Mark as Relieved")');
      if (await relievedBtn.count() > 0) {
        await expect(relievedBtn).toBeVisible();
      }
    }
  });

  test('should close all lifecycle modals/offcanvas on cancel', async ({ page }) => {
    const employeeId = await getFirstEmployeeId(page);

    if (!employeeId) {
      test.skip();
      return;
    }

    await page.goto(`/employees/view/${employeeId}`, { waitUntil: 'networkidle' });

    // Test confirm probation offcanvas close
    const confirmBtn = page.locator('[data-bs-target="#confirmProbationOffcanvas"]').first();
    if (await confirmBtn.count() > 0) {
      await confirmBtn.click();
      await page.waitForTimeout(500);
      await expect(page.locator('#confirmProbationOffcanvas')).toBeVisible();

      await page.click('#confirmProbationOffcanvas button[data-bs-dismiss="offcanvas"]');
      await page.waitForTimeout(500);
      await expect(page.locator('#confirmProbationOffcanvas')).toBeHidden();
    }

    // Test terminate modal close if available
    const actionsBtn = page.locator('button.dropdown-toggle:has-text("Actions")');
    if (await actionsBtn.count() > 0) {
      await actionsBtn.click();
      await page.waitForTimeout(300);

      const terminateOption = page.locator('[data-bs-target="#terminateEmployeeModal"]').first();
      if (await terminateOption.count() > 0) {
        await terminateOption.click();
        await page.waitForTimeout(500);
        await expect(page.locator('#terminateEmployeeModal')).toBeVisible();

        await page.click('#terminateEmployeeModal button[data-bs-dismiss="modal"]');
        await page.waitForTimeout(500);
        await expect(page.locator('#terminateEmployeeModal')).toBeHidden();
      }
    }
  });
});
