import { renderWithContext } from '../tests/with-app-context.js'
import { screen, waitFor } from '@testing-library/react'
import { Formik } from 'formik'
import userEvent from '@testing-library/user-event'

import { StateSelect } from './state-select'

describe('<StateSelect />', () => {
  const handleSubmit = jest.fn()

  it('renders <select> list of states and territories in long format by default', () => {
    renderWithContext(
      <Formik initialValues={{ state: '' }} onSubmit={handleSubmit}>
        <StateSelect />
      </Formik>
    )

    const selectInput = screen.getByRole('combobox', {
      name: 'State',
    })
    expect(selectInput).toBeInTheDocument()
    expect(selectInput).toHaveValue('')

    const options = screen.getAllByRole('option')
    expect(options.length).toEqual(59)

    expect(screen.getByRole('option', { name: 'Alabama' })).toBeInTheDocument()
    expect(screen.queryByRole('option', { name: 'AL' })).not.toBeInTheDocument()
  })
  it('renders <select> list with only 50 states, in short format', () => {
    renderWithContext(
      <Formik initialValues={{ state: '' }} onSubmit={handleSubmit}>
        <StateSelect withTerritories={false} format="short" />
      </Formik>
    )

    const options = screen.getAllByRole('option')
    expect(options.length).toEqual(50)

    expect(screen.getByRole('option', { name: 'AL' })).toBeInTheDocument()
    expect(screen.queryByRole('option', { name: 'Alabama' })).not.toBeInTheDocument()
  })
  it('renders <select> list that can be changed', async () => {
    renderWithContext(
      <Formik initialValues={{ state: 'NY' }} onSubmit={handleSubmit}>
        <StateSelect />
      </Formik>
    )

    const oldOption = screen.getByRole('option', { name: 'New York' }) as HTMLOptionElement
    expect(oldOption.selected).toBe(true)

    const notSelected = screen.getByRole('option', { name: 'Alabama' }) as HTMLOptionElement
    expect(notSelected.selected).toBe(false)

    userEvent.selectOptions(screen.getByRole('combobox'), 'AL')

    await waitFor(() => {
      expect(notSelected.selected).toBe(true)
    })
  })
})
