import { useState } from 'react';
import { render, screen, fireEvent } from '@testing-library/react';
import { vi, test, expect, beforeEach, afterEach } from 'vitest';
import SearchBar from '../../src/components/SearchBar';
import { search, type SearchResult } from '../../src/api/client';

function ControlledSearchBar({
  onResults,
  debounceMs,
}: {
  onResults: (results: SearchResult[]) => void;
  debounceMs?: number;
}) {
  const [value, setValue] = useState('');
  return <SearchBar value={value} onQueryChange={setValue} onResults={onResults} debounceMs={debounceMs} />;
}

vi.mock('../../src/api/client');

beforeEach(() => {
  vi.mocked(search).mockReset();
  vi.useFakeTimers();
});

afterEach(() => {
  vi.useRealTimers();
});

test('debounces input for 300ms before calling search', async () => {
  vi.mocked(search).mockResolvedValue({ results: [] });
  const onQueryChange = vi.fn();
  const onResults = vi.fn();

  render(<SearchBar value="" onQueryChange={onQueryChange} onResults={onResults} />);

  const input = screen.getByRole('textbox') as HTMLInputElement;
  fireEvent.change(input, { target: { value: '检索' } });

  expect(onQueryChange).toHaveBeenLastCalledWith('检索');
  expect(search).not.toHaveBeenCalled();

  vi.advanceTimersByTime(300);

  expect(search).toHaveBeenCalledWith('检索');
});

test('clearing the input immediately reports empty results without calling search', async () => {
  vi.mocked(search).mockResolvedValue({ results: [] });
  const onResults = vi.fn();

  render(<ControlledSearchBar onResults={onResults} />);

  const input = screen.getByRole('textbox') as HTMLInputElement;
  fireEvent.change(input, { target: { value: 'x' } });
  vi.advanceTimersByTime(300);
  fireEvent.change(input, { target: { value: '' } });

  expect(onResults).toHaveBeenCalledWith([]);
});

test('reflects the value prop, allowing a parent to control/reset the input', () => {
  const onQueryChange = vi.fn();
  const onResults = vi.fn();

  const { rerender } = render(<SearchBar value="检索" onQueryChange={onQueryChange} onResults={onResults} />);

  const input = screen.getByRole('textbox') as HTMLInputElement;
  expect(input).toHaveValue('检索');

  rerender(<SearchBar value="" onQueryChange={onQueryChange} onResults={onResults} />);

  expect(input).toHaveValue('');
});
