import { describe, it, expect, vi } from 'vitest'

import { renderWithProviders, screen, userEvent } from '../../test/utils'

import { SearchInput } from './index'

describe('SearchInput', () => {
  describe('Rendering', () => {
    it('renders with placeholder', () => {
      renderWithProviders(
        <SearchInput
          searchQuery=""
          setSearchQuery={vi.fn()}
          placeholder="Search messages..."
        />
      )
      expect(
        screen.getByPlaceholderText('Search messages...')
      ).toBeInTheDocument()
    })

    it('displays the current value', () => {
      renderWithProviders(
        <SearchInput
          searchQuery="test query"
          setSearchQuery={vi.fn()}
          placeholder="Search"
        />
      )
      const input = screen.getByRole('textbox')
      expect(input).toHaveValue('test query')
    })
  })

  describe('User Interaction', () => {
    it('calls setSearchQuery when user types', async () => {
      const handleChange = vi.fn()
      const user = userEvent.setup()

      renderWithProviders(
        <SearchInput
          searchQuery=""
          setSearchQuery={handleChange}
          placeholder="Search"
        />
      )

      const input = screen.getByRole('textbox')
      await user.type(input, 'hello')

      expect(handleChange).toHaveBeenCalledTimes(5) // Once per character
    })
  })

  describe('Clear Functionality', () => {
    it('shows clear button when there is a value', () => {
      renderWithProviders(
        <SearchInput
          searchQuery="test"
          setSearchQuery={vi.fn()}
          placeholder="Search"
        />
      )

      const clearButton = screen.getByRole('button', { name: /clear/i })
      expect(clearButton).toBeInTheDocument()
    })

    it('does not show clear button when value is empty', () => {
      renderWithProviders(
        <SearchInput
          searchQuery=""
          setSearchQuery={vi.fn()}
          placeholder="Search"
        />
      )

      const clearButton = screen.queryByLabelText(/clear/i)
      expect(clearButton).not.toBeInTheDocument()
    })

    it('calls setSearchQuery with empty string when clear is clicked', async () => {
      const handleChange = vi.fn()
      const user = userEvent.setup()

      renderWithProviders(
        <SearchInput
          searchQuery="test"
          setSearchQuery={handleChange}
          placeholder="Search"
        />
      )

      const clearButton = screen.getByRole('button', { name: /clear/i })
      await user.click(clearButton)

      expect(handleChange).toHaveBeenCalledWith('')
    })
  })

  describe('Accessibility', () => {
    it('clear button has accessible label', () => {
      renderWithProviders(
        <SearchInput
          searchQuery="test"
          setSearchQuery={vi.fn()}
          placeholder="Search"
        />
      )

      const clearButton = screen.getByRole('button', { name: /clear search/i })
      expect(clearButton).toBeInTheDocument()
    })

    it('is keyboard navigable', async () => {
      const user = userEvent.setup()

      renderWithProviders(
        <SearchInput
          searchQuery=""
          setSearchQuery={vi.fn()}
          placeholder="Search"
        />
      )

      await user.tab()
      const input = screen.getByRole('textbox')
      expect(input).toHaveFocus()
    })
  })
})
