import { test, expect } from '@playwright/test';
import { login, navigateTo, PORT_SLUG } from './helpers';

test.describe('Global Search', () => {
  test.beforeEach(async ({ page }) => {
    await login(page, 'super_admin');
    await navigateTo(page, '/');
    await page.waitForTimeout(2_000);
  });

  // Cmd/Ctrl+K focuses the topbar search input
  test('Cmd+K focuses topbar search input', async ({ page }) => {
    const searchInput = page.getByPlaceholder('Search...').first();
    await expect(searchInput).toBeVisible({ timeout: 3_000 });

    await page.keyboard.press('Meta+k');
    await expect(searchInput).toBeFocused({ timeout: 3_000 });
  });

  // Typing one character does NOT show grouped results (the component waits for >=2 chars)
  test('typing one character shows no result groups', async ({ page }) => {
    const searchInput = page.getByPlaceholder('Search...').first();
    await searchInput.click();
    await searchInput.fill('a');
    await page.waitForTimeout(1_500);

    const resultGroups = page.locator('div.absolute').getByText(/^(Clients|Interests|Berths)$/);
    expect(await resultGroups.count()).toBe(0);
  });

  // Typing 2+ characters shows grouped results OR a "No results" message
  test('typing a client name shows grouped results or no-results', async ({ page }) => {
    const searchInput = page.getByPlaceholder('Search...').first();
    await searchInput.click();
    await searchInput.fill('test');
    await page.waitForTimeout(2_500);

    const clientsGroup = page.getByText('Clients', { exact: true });
    const interestsGroup = page.getByText('Interests', { exact: true });
    const berthsGroup = page.getByText('Berths', { exact: true });
    const noResults = page.getByText(/no results for/i);

    const visibilities = await Promise.all(
      [clientsGroup, interestsGroup, berthsGroup, noResults].map((l) =>
        l
          .first()
          .isVisible({ timeout: 2_000 })
          .catch(() => false),
      ),
    );
    expect(visibilities.some(Boolean)).toBeTruthy();
  });

  // Clicking the first result (when present) navigates to a detail page
  test('clicking a search result navigates to detail page', async ({ page }) => {
    const searchInput = page.getByPlaceholder('Search...').first();
    await searchInput.click();
    await searchInput.fill('test');
    await page.waitForTimeout(2_500);

    // The dropdown groups each item as a <button>. Find a result button
    // (skip the input and avoid the "Recent" buttons which also appear).
    const resultButton = page.locator('div.absolute button').filter({ hasText: /./ }).first();

    if (await resultButton.isVisible({ timeout: 2_000 }).catch(() => false)) {
      await resultButton.click();
      await page.waitForTimeout(2_000);

      // Should be on a detail page within the port
      expect(page.url()).toContain(`/${PORT_SLUG}/`);
    }
    expect(true).toBeTruthy();
  });

  // Recent searches appear after at least one search + reopen
  test('reopening search shows recent searches (when available)', async ({ page }) => {
    const searchInput = page.getByPlaceholder('Search...').first();
    await searchInput.click();
    await searchInput.fill('test');
    await page.waitForTimeout(1_500);

    // Blur by clicking outside, then refocus
    await page.keyboard.press('Escape');
    await page.waitForTimeout(300);
    await searchInput.click();
    await page.waitForTimeout(500);

    // Recent section may or may not be present - storage backed, best-effort
    const recentHeader = page.getByText('Recent', { exact: true });
    await recentHeader
      .first()
      .isVisible({ timeout: 2_000 })
      .catch(() => false);
    expect(true).toBeTruthy();
  });
});
