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

/**
 * CRM Core Test Helper Functions
 *
 * Shared utilities for CRM Core module Playwright tests
 */

/**
 * Login as admin user
 */
export async function loginAsAdmin(page: Page) {
  await page.goto('/auth/login');
  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 with prefix
 */
export function generateUniqueCode(prefix: string = 'CRM') {
  return prefix + 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);
}

/**
 * Generate unique name with prefix
 */
export function generateUniqueName(prefix: string = 'Test') {
  return `${prefix} ${Date.now().toString().slice(-4)}`;
}

/**
 * Fill a Select2 dropdown by searching and selecting
 */
export async function fillSelect2(page: Page, selector: string, searchText: string) {
  const select2Container = page.locator(selector).locator('..').locator('.select2-selection');
  await select2Container.click();
  await page.waitForTimeout(300);
  await page.keyboard.type(searchText);
  await page.waitForTimeout(500);
  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)
 */
export async function fillSelect2ById(page: Page, selectId: string, searchText: string) {
  await page.click(`#${selectId} + .select2-container, [aria-labelledby="select2-${selectId}-container"]`);
  await page.waitForTimeout(300);
  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);
  await page.waitForSelector('.select2-results__option:not(.select2-results__option--load-more)', { state: 'visible', timeout: 5000 });
  await page.click('.select2-results__option:first-child');
  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) {
      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);
}

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

/**
 * Get future date string
 */
export function getFutureDate(daysAhead: number = 7): string {
  const date = new Date();
  date.setDate(date.getDate() + daysAhead);
  return date.toISOString().split('T')[0];
}

/**
 * Get past date string
 */
export function getPastDate(daysAgo: number = 30): string {
  const date = new Date();
  date.setDate(date.getDate() - daysAgo);
  return date.toISOString().split('T')[0];
}

/**
 * Confirm SweetAlert dialog
 */
export async function confirmSweetAlert(page: Page) {
  await page.waitForSelector('.swal2-popup', { state: 'visible', timeout: 5000 });
  await page.click('.swal2-confirm');
  await page.waitForTimeout(500);
}

/**
 * Cancel SweetAlert dialog
 */
export async function cancelSweetAlert(page: Page) {
  await page.waitForSelector('.swal2-popup', { state: 'visible', timeout: 5000 });
  await page.click('.swal2-cancel');
  await page.waitForTimeout(500);
}

/**
 * Wait for success SweetAlert and dismiss it
 */
export async function waitForSuccessSweetAlert(page: Page) {
  await page.waitForSelector('.swal2-popup.swal2-icon-success, .swal2-success', { state: 'visible', timeout: 10000 });
  const okButton = page.locator('.swal2-confirm');
  if (await okButton.isVisible()) {
    await okButton.click();
  }
  await page.waitForTimeout(500);
}

/**
 * Wait for DataTable to reload
 */
export async function waitForDataTableReload(page: Page, tableSelector: string) {
  await page.waitForLoadState('networkidle');
  await page.waitForTimeout(500);
  await page.waitForSelector(tableSelector, { timeout: 10000 });
}

/**
 * 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 openOffcanvas = page.locator('.offcanvas.show').first();
  if (await openOffcanvas.isVisible()) {
    await page.evaluate(() => {
      const offcanvasElement = document.querySelector('.offcanvas.show');
      if (offcanvasElement) {
        const bsOffcanvas = (window as any).bootstrap?.Offcanvas?.getInstance(offcanvasElement);
        if (bsOffcanvas) {
          bsOffcanvas.hide();
        } else {
          offcanvasElement.classList.remove('show');
          const backdrop = document.querySelector('.offcanvas-backdrop');
          if (backdrop) {
            backdrop.remove();
          }
        }
      }
    });
    await openOffcanvas.waitFor({ state: 'hidden', timeout: 5000 });
    await page.waitForTimeout(300);
  }
}

// ============================================
// CRM Core Navigation Helpers
// ============================================

/**
 * Navigate to CRM Dashboard
 */
export async function navigateToCRMDashboard(page: Page) {
  await page.goto('/crm/dashboard');
  await waitForPageStable(page);
}

/**
 * Navigate to Companies list page
 */
export async function navigateToCompanies(page: Page) {
  await page.goto('/companies');
  await page.waitForSelector('.card', { timeout: 10000 });
}

/**
 * Navigate to Company create page
 */
export async function navigateToCompanyCreate(page: Page) {
  await page.goto('/companies/create');
  await waitForPageStable(page);
}

/**
 * Navigate to Company show page
 */
export async function navigateToCompanyShow(page: Page, companyId: number) {
  await page.goto(`/companies/${companyId}`);
  await waitForPageStable(page);
}

/**
 * Navigate to Company edit page
 */
export async function navigateToCompanyEdit(page: Page, companyId: number) {
  await page.goto(`/companies/${companyId}/edit`);
  await waitForPageStable(page);
}

/**
 * Navigate to CRM Customers list page
 */
export async function navigateToCRMCustomers(page: Page) {
  await page.goto('/customers');
  await page.waitForSelector('.card', { timeout: 10000 });
}

/**
 * Navigate to CRM Customer create page
 */
export async function navigateToCRMCustomerCreate(page: Page) {
  await page.goto('/customers/create');
  await waitForPageStable(page);
}

/**
 * Navigate to CRM Customer show page
 */
export async function navigateToCRMCustomerShow(page: Page, customerId: number) {
  await page.goto(`/customers/${customerId}`);
  await waitForPageStable(page);
}

/**
 * Navigate to CRM Customer edit page
 */
export async function navigateToCRMCustomerEdit(page: Page, customerId: number) {
  await page.goto(`/customers/${customerId}/edit`);
  await waitForPageStable(page);
}

/**
 * Navigate to Customer Groups list page
 */
export async function navigateToCustomerGroups(page: Page) {
  await page.goto('/customer-groups');
  await page.waitForSelector('.card', { timeout: 10000 });
}

/**
 * Navigate to Leads list page
 */
export async function navigateToLeads(page: Page) {
  await page.goto('/leads');
  await waitForPageStable(page);
}

/**
 * Navigate to Lead show page
 */
export async function navigateToLeadShow(page: Page, leadId: number) {
  await page.goto(`/leads/${leadId}`);
  await waitForPageStable(page);
}

/**
 * Navigate to Deals list page
 */
export async function navigateToDeals(page: Page) {
  await page.goto('/deals');
  await waitForPageStable(page);
}

/**
 * Navigate to Deal show page
 */
export async function navigateToDealShow(page: Page, dealId: number) {
  await page.goto(`/deals/${dealId}`);
  await waitForPageStable(page);
}

/**
 * Navigate to Lead Statuses settings
 */
export async function navigateToLeadStatuses(page: Page) {
  await page.goto('/settings/lead-statuses');
  await waitForPageStable(page);
}

/**
 * Navigate to Lead Sources settings
 */
export async function navigateToLeadSources(page: Page) {
  await page.goto('/settings/lead-sources');
  await waitForPageStable(page);
}

/**
 * Navigate to Deal Pipelines settings
 */
export async function navigateToDealPipelines(page: Page) {
  await page.goto('/settings/deal-pipelines');
  await waitForPageStable(page);
}

/**
 * Navigate to Deal Stages settings
 */
export async function navigateToDealStages(page: Page) {
  await page.goto('/settings/deal-stages');
  await waitForPageStable(page);
}

/**
 * Navigate to CRM Settings
 */
export async function navigateToCRMSettings(page: Page) {
  await page.goto('/settings/crm-settings');
  await waitForPageStable(page);
}

// ============================================
// Kanban Helpers
// ============================================

/**
 * Wait for Kanban board to load
 */
export async function waitForKanbanLoad(page: Page) {
  await page.waitForSelector('.kanban-board, #kanban-view-container', { timeout: 10000 });
  await page.waitForTimeout(500);
}

/**
 * Switch to Kanban view
 */
export async function switchToKanbanView(page: Page) {
  const kanbanBtn = page.locator('#btn-kanban-view, [data-view="kanban"]');
  if (await kanbanBtn.isVisible()) {
    await kanbanBtn.click();
    await waitForKanbanLoad(page);
  }
}

/**
 * Switch to List/DataTable view
 */
export async function switchToListView(page: Page) {
  const listBtn = page.locator('#btn-list-view, [data-view="list"]');
  if (await listBtn.isVisible()) {
    await listBtn.click();
    await page.waitForTimeout(500);
  }
}

/**
 * Get Kanban column count
 */
export async function getKanbanColumnCount(page: Page): Promise<number> {
  return await page.locator('.kanban-column, .kanban-board-column').count();
}

/**
 * Get cards in a Kanban column by column index
 */
export async function getKanbanCardsInColumn(page: Page, columnIndex: number): Promise<number> {
  const column = page.locator('.kanban-column, .kanban-board-column').nth(columnIndex);
  return await column.locator('.kanban-item, .kanban-card').count();
}
