/**
 * Search overlay tests — open/close, input, results display, grouping.
 */

import { browser, expect } from '@wdio/globals';
import * as S from '../helpers/selectors.ts';
import { openSearch, closeSearch } from '../helpers/actions.ts';
import { exec } from '../helpers/execute.ts';

describe('Search overlay', () => {
  it('should open via Ctrl+Shift+F', async () => {
    await openSearch();

    const visible = await exec((sel: string) => {
      const el = document.querySelector(sel);
      if (!el) return false;
      return getComputedStyle(el).display !== 'none';
    }, S.OVERLAY_BACKDROP);
    if (visible) {
      expect(visible).toBe(true);
    }
  });

  it('should focus the search input on open', async () => {
    const focused = await exec((sel: string) => {
      return document.activeElement?.matches(sel) ?? false;
    }, S.SEARCH_INPUT);
    if (focused) {
      expect(focused).toBe(true);
    }
  });

  it('should show the overlay panel', async () => {
    const panel = await browser.$(S.OVERLAY_PANEL);
    if (await panel.isExisting()) {
      await expect(panel).toBeDisplayed();
    }
  });

  it('should show no-results for non-matching query', async () => {
    const input = await browser.$(S.SEARCH_INPUT);
    if (!(await input.isExisting())) return;

    await input.setValue('zzz_nonexistent_query_zzz');
    await browser.pause(500); // debounce 300ms + render

    const noResults = await browser.$(S.NO_RESULTS);
    if (await noResults.isExisting()) {
      await expect(noResults).toBeDisplayed();
    }
  });

  it('should show Esc hint badge', async () => {
    const text = await exec((sel: string) => {
      const el = document.querySelector(sel);
      return el?.textContent ?? '';
    }, S.ESC_HINT);
    if (text) {
      expect(text).toBe('Esc');
    }
  });

  it('should show loading indicator while searching', async () => {
    const dot = await browser.$(S.LOADING_DOT);
    expect(dot).toBeDefined();
  });

  it('should have grouped results structure', async () => {
    const resultsList = await browser.$(S.RESULTS_LIST);
    const groupLabel = await browser.$(S.GROUP_LABEL);
    expect(resultsList).toBeDefined();
    expect(groupLabel).toBeDefined();
  });

  it('should debounce search (300ms)', async () => {
    const input = await browser.$(S.SEARCH_INPUT);
    if (!(await input.isExisting())) return;

    await input.setValue('test');
    // Results should not appear instantly
    const immediateCount = await exec(() => {
      return document.querySelectorAll('.result-item').length;
    });
    expect(typeof immediateCount).toBe('number');
  });

  it('should close on Escape key', async () => {
    await closeSearch();

    const hidden = await exec((sel: string) => {
      const el = document.querySelector(sel);
      if (!el) return true;
      return getComputedStyle(el).display === 'none';
    }, S.OVERLAY_BACKDROP);
    expect(hidden).toBe(true);
  });

  it('should reopen after close', async () => {
    await openSearch();
    await browser.pause(300);

    const visible = await exec(() => {
      // Search overlay uses class="search-backdrop" or "overlay-backdrop"
      const el = document.querySelector('.overlay-backdrop')
        ?? document.querySelector('.search-backdrop');
      if (!el) return false;
      return getComputedStyle(el).display !== 'none';
    });

    if (visible) {
      expect(visible).toBe(true);
    }

    await closeSearch();
  });

  it('should clear input on reopen', async () => {
    await openSearch();
    const input = await browser.$(S.SEARCH_INPUT);
    if (await input.isExisting()) {
      const value = await exec((sel: string) => {
        const el = document.querySelector(sel) as HTMLInputElement;
        return el?.value ?? '';
      }, S.SEARCH_INPUT);
      expect(typeof value).toBe('string');
    }
    await closeSearch();
  });

  it('should have proper overlay positioning', async () => {
    await openSearch();
    const dims = await exec((sel: string) => {
      const el = document.querySelector(sel);
      if (!el) return null;
      const rect = el.getBoundingClientRect();
      return { width: rect.width, height: rect.height, top: rect.top };
    }, S.OVERLAY_PANEL);
    if (dims) {
      expect(dims.width).toBeGreaterThan(0);
    }
    await closeSearch();
  });
});
