import { Page } from '@playwright/test';

/**
 * Employee Test Helper Functions
 *
 * Shared utilities for employee-related Playwright tests
 */

/**
 * Login as admin user
 */
export async function loginAsAdmin(page: 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 employee code
 */
export function generateUniqueCode() {
  return 'EMP' + Date.now().toString().slice(-6);
}

/**
 * Generate unique email address
 */
export function generateUniqueEmail() {
  return `test${Date.now()}@example.com`;
}

/**
 * Generate unique phone number
 */
export function generateUniquePhone() {
  return '+1555' + Date.now().toString().slice(-7);
}

/**
 * Fill a Select2 dropdown by searching and selecting
 */
export async function fillSelect2(page: Page, selector: string, searchText: string) {
  // Click the Select2 container to open dropdown
  const select2Container = page.locator(selector).locator('..').locator('.select2-selection');
  await select2Container.click();
  await page.waitForTimeout(300);

  // Type search text
  await page.keyboard.type(searchText);
  await page.waitForTimeout(500);

  // Wait for results and click first option
  await page.waitForSelector('.select2-results__option', { state: 'visible', timeout: 5000 });
  const firstOption = page.locator('.select2-results__option').first();
  await firstOption.click();
  await page.waitForTimeout(200);
}

/**
 * Fill Select2 using the sibling approach (for hidden select elements)
 * Improved version with better error handling and dropdown management
 */
export async function fillSelect2ById(page: Page, selectId: string, searchText: string) {
  // Close any open dropdowns first
  await page.keyboard.press('Escape');
  await page.waitForTimeout(200);

  // Click on the Select2 container that follows the hidden select
  const select2Container = page.locator(`#${selectId} + .select2-container`);
  await select2Container.click();
  await page.waitForTimeout(300);

  // Wait for dropdown to open
  await page.waitForSelector('.select2-dropdown', { state: 'visible', timeout: 5000 });

  // Type in the search box
  const searchInput = page.locator('.select2-search__field');
  if (await searchInput.isVisible()) {
    await searchInput.fill(searchText);
  } else {
    await page.keyboard.type(searchText);
  }
  await page.waitForTimeout(500);

  // Wait for results to load (not loading state)
  await page.waitForSelector('.select2-results__option:not(.loading-results):not(.select2-results__option--load-more)', { state: 'visible', timeout: 5000 });

  // Click first result that's not a message
  const firstOption = page.locator('.select2-results__option').filter({ hasNotText: 'Searching' }).first();
  await firstOption.click();
  await page.waitForTimeout(200);
}

/**
 * Set a Flatpickr date input value via JavaScript
 */
export async function setFlatpickrDate(page: Page, selector: string, date: string) {
  await page.evaluate(([sel, val]) => {
    const input = document.querySelector(sel) as HTMLInputElement;
    if (input) {
      // Try to use Flatpickr instance if available
      const fp = (input as any)._flatpickr;
      if (fp) {
        fp.setDate(val, true);
      } else {
        input.value = val;
        input.dispatchEvent(new Event('change', { bubbles: true }));
      }
    }
  }, [selector, date]);
  await page.waitForTimeout(200);
}

/**
 * Navigate to employees list page
 */
export async function navigateToEmployees(page: Page) {
  await page.goto('/employees', { waitUntil: 'networkidle' });
  await page.waitForSelector('.datatables-users, .card', { timeout: 10000 });
}

/**
 * Navigate to employee view page
 */
export async function navigateToEmployeeView(page: Page, employeeId: number) {
  await page.goto(`/employees/view/${employeeId}`, { waitUntil: 'networkidle' });
}

/**
 * Navigate to employee create page
 */
export async function navigateToEmployeeCreate(page: Page) {
  await page.goto('/employees/create', { waitUntil: 'networkidle' });
}

/**
 * Get a date string for N months from now
 */
export function getFutureDate(monthsAhead: number = 1): string {
  const date = new Date();
  date.setMonth(date.getMonth() + monthsAhead);
  return date.toISOString().split('T')[0]; // YYYY-MM-DD format
}

/**
 * Get a date string for N years ago (for DOB)
 */
export function getPastDate(yearsAgo: number = 25): string {
  const date = new Date();
  date.setFullYear(date.getFullYear() - yearsAgo);
  return date.toISOString().split('T')[0]; // YYYY-MM-DD format
}

/**
 * Get today's date string
 */
export function getTodayDate(): string {
  return new Date().toISOString().split('T')[0];
}

/**
 * Wait for page to be fully loaded and stable
 */
export async function waitForPageStable(page: Page) {
  await page.waitForLoadState('networkidle');
  await page.waitForTimeout(500);
}

/**
 * Check if an element exists on the page
 */
export async function elementExists(page: Page, selector: string): Promise<boolean> {
  return await page.locator(selector).count() > 0;
}

/**
 * Close any open offcanvas
 */
export async function closeOffcanvas(page: Page) {
  const closeBtn = page.locator('[data-bs-dismiss="offcanvas"]').first();
  if (await closeBtn.isVisible()) {
    await closeBtn.click();
    await page.waitForTimeout(500);
  }
}
