import { render, screen, fireEvent, waitFor } from '@testing-library/react';
import { describe, it, expect, vi } from 'vitest';
import { Search } from './search';
import React from 'react';

describe('Search', () => {
  it('renders correctly with default props', () => {
    render(<Search placeholder="Search items..." />);
    const input = screen.getByPlaceholderText('Search items...');
    expect(input).toBeInTheDocument();
    expect(input).toHaveClass('h-10'); // md size
  });

  it('renders correctly with different sizes', () => {
    const { rerender } = render(<Search size="sm" placeholder="Small" />);
    expect(screen.getByPlaceholderText('Small')).toHaveClass('h-8');

    rerender(<Search size="md" placeholder="Medium" />);
    expect(screen.getByPlaceholderText('Medium')).toHaveClass('h-10');

    rerender(<Search size="lg" placeholder="Large" />);
    expect(screen.getByPlaceholderText('Large')).toHaveClass('h-12');
  });

  it('updates value and calls onSearch on change', () => {
    const onSearch = vi.fn();
    render(<Search onSearch={onSearch} />);
    const input = screen.getByRole('textbox');

    fireEvent.change(input, { target: { value: 'query' } });

    expect(input).toHaveValue('query');
    expect(onSearch).toHaveBeenCalledWith('query');
  });

  it('clears input when clear button is clicked', async () => {
    const onClear = vi.fn();
    render(<Search onClear={onClear} />);
    const input = screen.getByRole('textbox');

    // Type something first
    fireEvent.change(input, { target: { value: 'to clear' } });
    expect(input).toHaveValue('to clear');

    const clearButton = screen.getByLabelText('Clear search');
    fireEvent.click(clearButton);

    await waitFor(() => {
      expect(input).toHaveValue('');
    });
    expect(onClear).toHaveBeenCalled();
  });

  it('clears input when Escape key is pressed', async () => {
    render(<Search />);
    const input = screen.getByRole('textbox');

    fireEvent.change(input, { target: { value: 'escape me' } });
    expect(input).toHaveValue('escape me');

    fireEvent.keyDown(input, { key: 'Escape' });

    await waitFor(() => {
      expect(input).toHaveValue('');
    });
  });
});
