import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest'
import { fireEvent, render, screen, act } from '@testing-library/react'
import { Provider } from '../../provider/widget-provider'
import { clearAllWidgetStores, getWidgetStore } from '../../stores'
import { Searcher } from './searcher'
import { SearcherToggle } from './searcher-toggle'

beforeEach(() => clearAllWidgetStores())
afterEach(() => clearAllWidgetStores())

const DATA = [
  [
    { name: 'apple', value: 1 },
    { name: 'banana', value: 2 },
    { name: 'cherry', value: 3 },
  ],
]

describe('<Searcher> + <SearcherToggle>', () => {
  it('toggle defaults off — aria-pressed=false and input hidden', () => {
    render(
      <Provider id='sr1' data={DATA}>
        <SearcherToggle />
        <Searcher />
      </Provider>,
    )
    const btn = screen.getByRole('button', { name: 'Search' })
    expect(btn.getAttribute('aria-pressed')).toBe('false')
    expect(screen.queryByPlaceholderText('Search…')).toBeNull()
  })

  it('initialEnabled=true opts into the legacy "search-first" behavior', () => {
    render(
      <Provider id='sr1b' data={DATA}>
        <SearcherToggle initialEnabled />
        <Searcher />
      </Provider>,
    )
    const btn = screen.getByRole('button', { name: 'Search' })
    expect(btn.getAttribute('aria-pressed')).toBe('true')
    expect(screen.getByPlaceholderText('Search…')).toBeTruthy()
  })

  it('clicking the toggle reveals the input and flips aria-pressed', () => {
    render(
      <Provider id='sr2' data={DATA}>
        <SearcherToggle />
        <Searcher />
      </Provider>,
    )
    fireEvent.click(screen.getByRole('button', { name: 'Search' }))
    expect(screen.getByPlaceholderText('Search…')).toBeTruthy()
    expect(
      screen
        .getByRole('button', { name: 'Search' })
        .getAttribute('aria-pressed'),
    ).toBe('true')
  })

  it('debounces input changes; after the timer fires the searchText is committed and the data is filtered', () => {
    vi.useFakeTimers({ shouldAdvanceTime: true })
    try {
      render(
        <Provider id='sr3' data={DATA}>
          <SearcherToggle initialEnabled />
          <Searcher debounceMs={100} />
        </Provider>,
      )
      // `initialEnabled` opens the input straight away — no click needed.
      const input = screen.getByPlaceholderText('Search…')
      fireEvent.change(input, { target: { value: 'app' } })
      // Pre-debounce: store still has no committed searchText.
      expect(
        getWidgetStore('sr3').getState().transformStates.searcher?.searchText,
      ).toBeUndefined()

      act(() => {
        vi.advanceTimersByTime(120)
      })

      expect(
        getWidgetStore('sr3').getState().transformStates.searcher?.searchText,
      ).toBe('app')
      const filtered = getWidgetStore('sr3').getState().data as {
        name: string
      }[][]
      expect(filtered.flat().map((r) => r.name)).toEqual(['apple'])
    } finally {
      vi.useRealTimers()
    }
  })
})
