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

const list = [
  {
    value: 'mangosteen',
    title: 'Mangosteen',
    desc: 'Thailand, Indonesia, Malaysia, Philippines, Colombia, and Puerto Rico',
    id: 'mangosteen',
  },
  { value: 'lychee', title: 'Lychee', desc: 'China, Taiwan, Vietnam, and other tropical countries.', id: 'lychee' },
  {
    value: 'rambutan',
    title: 'Rambutan',
    desc: 'Thailand, Indonesia, Malaysia, and other humid tropical Southeast Asian countries.',
    id: 'rambutan',
  },
]

const renderOption = ({ title, desc, id }) => (
  <p>
    {title}: {desc}
  </p>
)

describe('<OptionGroup />', () => {
  it('renders 3 options elements, including 3 unchecked radio inputs', () => {
    renderWithContext(<OptionsGroup name="fruits" options={list} renderOption={renderOption} />)

    const notChecked = screen.getAllByRole('radio', { checked: false })

    expect(screen.getAllByRole('radio')).toHaveLength(3)
    expect(screen.getAllByTestId(/^options-group:option-wrapper/)).toHaveLength(3)
    expect(notChecked).toHaveLength(3)
  })

  it('renders options with correct selected value checked', () => {
    renderWithContext(<OptionsGroup name="fruits" options={list} renderOption={renderOption} value="lychee" />)

    const checked = screen.getByRole('radio', { checked: true }) as HTMLInputElement
    const notChecked = screen.getAllByRole('radio', { checked: false })

    expect(checked).toBeInTheDocument()
    expect(checked.value).toBe('lychee')
    expect(notChecked).toHaveLength(2)
  })

  it('handles selecting a new option', async () => {
    const handleSubmit = jest.fn()

    renderWithContext(
      <Formik
        initialValues={{
          fruits: 'lychee',
        }}
        onSubmit={handleSubmit}
      >
        {({ values, setValues }) => (
          <OptionsGroup
            name="fruits"
            options={list}
            renderOption={renderOption}
            value={values.fruits}
            onChange={(e) => setValues({ fruits: e.target.value })}
          />
        )}
      </Formik>
    )

    const oldSelection = screen.getByRole('radio', { checked: true }) as HTMLInputElement

    expect(oldSelection.value).toBe('lychee')

    const newSelection = screen.getByRole('radio', { name: /^Rambutan:/ })

    userEvent.click(newSelection)

    await waitFor(() => {
      expect(oldSelection).not.toBeChecked()
    })
    expect(newSelection).toBeChecked()
  })
})
