import { fireEvent, render, screen } from '@testing-library/react'
import { describe, expect, it, vi } from 'vitest'
import { TextField } from './TextField'

describe('TextField', () => {
  it('labels the control and reports raw values', () => {
    const onValueChange = vi.fn()
    render(<TextField label="Title" value="" onValueChange={onValueChange} />)

    fireEvent.change(screen.getByLabelText('Title'), { target: { value: 'disk full' } })
    expect(onValueChange).toHaveBeenCalledWith('disk full')
  })

  it('keeps a hidden label reachable by accessible name', () => {
    render(<TextField label="Engine default value" labelMode="hidden" value="x" onValueChange={vi.fn()} />)
    expect(screen.getByRole('textbox', { name: 'Engine default value' })).toBeInTheDocument()
  })

  it('links hint and error text through aria-describedby and marks the field invalid', () => {
    render(
      <TextField label="Title" value="" onValueChange={vi.fn()} hint="1–160 characters" error="Title is required." />,
    )
    const input = screen.getByLabelText('Title')

    expect(input).toHaveAttribute('aria-invalid', 'true')
    const described = (input.getAttribute('aria-describedby') ?? '').split(' ')
    expect(described).toHaveLength(2)
    const texts = described.map((id) => document.getElementById(id)?.textContent)
    expect(texts).toContain('1–160 characters')
    expect(texts).toContain('Title is required.')
  })

  it('omits aria-describedby and aria-invalid when there is nothing to describe', () => {
    render(<TextField label="Title" value="" onValueChange={vi.fn()} />)
    const input = screen.getByLabelText('Title')
    expect(input).not.toHaveAttribute('aria-describedby')
    expect(input).not.toHaveAttribute('aria-invalid')
  })

  it('renders a trailing affordance beside the control', () => {
    render(
      <TextField
        label="Filter"
        value="x"
        onValueChange={vi.fn()}
        trailing={<button type="button">Clear</button>}
      />,
    )
    expect(screen.getByRole('button', { name: 'Clear' })).toBeInTheDocument()
  })
})
