import { describe, expect, it, vi } from 'vitest'
import { render, screen, fireEvent, waitFor } from '@testing-library/react'
import { axe } from 'vitest-axe'
import {
  Select,
  SelectTrigger,
  SelectValue,
  SelectContent,
  SelectItem,
} from './Select'

describe('Select', () => {
  it('exposes combobox role with accessible name and selects via keyboard', async () => {
    const onValueChange = vi.fn()
    render(
      <Select onValueChange={onValueChange}>
        <SelectTrigger aria-label="Fruit">
          <SelectValue placeholder="Pick one" />
        </SelectTrigger>
        <SelectContent>
          <SelectItem value="apple">Apple</SelectItem>
          <SelectItem value="banana">Banana</SelectItem>
        </SelectContent>
      </Select>,
    )
    const trigger = screen.getByRole('combobox', { name: 'Fruit' })
    expect(trigger).toBeTruthy()
    expect(screen.queryByRole('option', { name: 'Apple' })).toBeNull()
    trigger.focus()
    fireEvent.keyDown(trigger, { key: 'ArrowDown' })
    await waitFor(() => {
      expect(screen.getByRole('option', { name: 'Apple' })).toBeTruthy()
    })
    const apple = await screen.findByRole('option', { name: 'Apple' })
    fireEvent.keyDown(apple, { key: 'Enter' })
    await waitFor(() => {
      expect(onValueChange).toHaveBeenCalledWith('apple')
    })
  })

  it('migrates menu shadow and trigger focus states to token vars', async () => {
    const { container } = render(
      <Select>
        <SelectTrigger aria-label="Fruit">
          <SelectValue placeholder="Pick one" />
        </SelectTrigger>
        <SelectContent>
          <SelectItem value="apple">Apple</SelectItem>
        </SelectContent>
      </Select>,
    )
    const trigger = screen.getByRole('combobox', { name: 'Fruit' })
    expect(trigger.className).toContain('focus-visible:outline-[var(--mod-focus-ring-color)]')
    fireEvent.keyDown(trigger, { key: 'ArrowDown' })
    const option = await screen.findByRole('option', { name: 'Apple' })
    expect(option.parentElement?.parentElement?.className ?? '').toContain('shadow-[var(--mod-shadow-md)]')
    await expect(axe(container)).resolves.toHaveNoViolations()
  })
})
