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

describe('FormField', () => {
  it('renders label and children', () => {
    render(
      <FormField label="Username" htmlFor="username">
        <input id="username" type="text" />
      </FormField>,
    )
    expect(screen.getByText('Username')).toBeInTheDocument()
    expect(screen.getByRole('textbox')).toBeInTheDocument()
  })

  it('renders hint text when no error', () => {
    render(
      <FormField label="Email" hint="We will never share your email" htmlFor="email">
        <input id="email" type="email" />
      </FormField>,
    )
    expect(screen.getByText('We will never share your email')).toBeInTheDocument()
  })

  it('renders error instead of hint when error is provided', () => {
    render(
      <FormField
        label="Email"
        hint="We will never share your email"
        error="Invalid email address"
        htmlFor="email"
      >
        <input id="email" type="email" />
      </FormField>,
    )
    expect(screen.getByText('Invalid email address')).toBeInTheDocument()
    expect(screen.queryByText('We will never share your email')).not.toBeInTheDocument()
  })

  it('shows required asterisk via Label when required is true', () => {
    render(
      <FormField label="Password" required htmlFor="password">
        <input id="password" type="password" />
      </FormField>,
    )
    expect(screen.getByText('*')).toBeInTheDocument()
  })

  it('adds error class to wrapper when error is present', () => {
    const { container } = render(
      <FormField label="Name" error="Name is required" htmlFor="name">
        <input id="name" type="text" />
      </FormField>,
    )
    const wrapper = container.firstChild as HTMLElement
    expect(wrapper.className).toMatch(/error/)
  })

  it('does not add error class when no error', () => {
    const { container } = render(
      <FormField label="Name" htmlFor="name">
        <input id="name" type="text" />
      </FormField>,
    )
    const wrapper = container.firstChild as HTMLElement
    expect(wrapper.className).not.toMatch(/error/)
  })

  it('renders children without label when label prop is omitted', () => {
    render(
      <FormField>
        <input type="text" aria-label="standalone input" />
      </FormField>,
    )
    expect(screen.getByRole('textbox')).toBeInTheDocument()
    expect(screen.queryByRole('label')).not.toBeInTheDocument()
  })

  it('associates label with input via htmlFor', () => {
    render(
      <FormField label="Search" htmlFor="search-input">
        <input id="search-input" type="text" />
      </FormField>,
    )
    const label = screen.getByText('Search').closest('label')
    expect(label).toHaveAttribute('for', 'search-input')
  })
})
