import {vi} from 'vitest'
import React from 'react'
import {render, screen} from '@testing-library/react'
import userEvent from '@testing-library/user-event'

import TrueFalseEdit from '../index'

import {
  verifyAtLeastOneRichContentEditorExists,
  verifyNoRichContentEditorsExist,
} from '../../../../../tests/util/enableRichContentEditorChecks'
import {verifyItemChangesAreValidated} from '../../../../../tests/util/shouldValidateItemChanges'
import runAxeCheck from '@instructure/ui-axe-check'

function createProps(changeItemStateStub, setOneQuestionAtATimeStub) {
  return {
    calculatorType: 'basic',
    itemBody: 'STEM',
    itemId: '12',
    interactionData: {
      trueChoice: 'True',
      falseChoice: 'False',
    },
    scoringData: {
      value: true,
    },
    openImportModal: Function.prototype,
    changeItemState: changeItemStateStub,
    setOneQuestionAtATime: setOneQuestionAtATimeStub,
    isSurvey: false,
  }
}

describe('***** old tests *****', () => {
  const changeItemStateStub = vi.fn()
  const oldProps = createProps(changeItemStateStub, vi.fn())

  afterEach(() => {
    changeItemStateStub.mockClear()
  })

  describe('overrideEditableForRegrading', () => {
    it('disables the question stem', () => {
      const {container} = render(<TrueFalseEdit {...oldProps} overrideEditableForRegrading />)

      // QuestionContainer passes readOnly to the RCE when disabled is true
      // Verify the RCE area is not editable
      const questionStem = container.querySelector('[data-automation="sdk-question-stem"]')
      expect(questionStem).toBeInTheDocument()

      // The calculator options should also be disabled
      const calculatorCheckbox = screen.getByRole('checkbox', {
        name: /show on-screen calculator/i,
      })
      expect(calculatorCheckbox.disabled).toBe(true)
    })
  })
})

describe('True False Item Edit', () => {
  let changeItemStateStub, setOneQuestionAtATimeStub, props
  beforeEach(() => {
    changeItemStateStub = vi.fn()
    setOneQuestionAtATimeStub = vi.fn()
    props = createProps(changeItemStateStub, setOneQuestionAtATimeStub)
  })

  it('renders a rich content editor by default', async () => {
    await verifyAtLeastOneRichContentEditorExists(TrueFalseEdit, props)
  })

  it('does not render a rich content editor when it is turned off', async () => {
    await verifyNoRichContentEditorsExist(TrueFalseEdit, {...props, enableRichContentEditor: false})
  })

  it('includes validation errors in changeItemState', async () => {
    await verifyItemChangesAreValidated(TrueFalseEdit, {...props, itemBody: ''})
  })

  describe('QuestionConfigContainer', () => {
    it('renders an QuestionSettingsContainer', () => {
      render(<TrueFalseEdit {...props} />)
      const questionSettingsContainers = screen.getAllByTestId('question-settings-container')
      expect(questionSettingsContainers).toHaveLength(1)
    })
  })

  describe('#onSelectionUpdate', () => {
    it('calls changeItemState with the correct arguments', () => {
      render(<TrueFalseEdit {...props} />)

      const radioInput = screen.getByRole('radio', {
        name: new RegExp(`Answer: ${props.interactionData.falseChoice}`),
      })
      userEvent.click(radioInput)

      expect(changeItemStateStub).toHaveBeenCalledWith(
        expect.objectContaining({scoringData: {value: false}}),
      )
    })
  })

  describe('#selectedValue', () => {
    it('selects the correct input from scoredData', () => {
      render(<TrueFalseEdit {...props} />)

      const trueInput = screen.getByRole('radio', {
        name: new RegExp(`Answer: ${props.interactionData.trueChoice}`),
      })
      expect(trueInput.checked).toBe(true)

      const falseInput = screen.getByRole('radio', {
        name: new RegExp(`Answer: ${props.interactionData.falseChoice}`),
      })
      expect(falseInput.checked).toBe(false)
    })

    it('selects the correct input from scoredData when false', () => {
      const falseProps = Object.assign({}, props, {
        scoringData: {
          value: false,
        },
      })
      render(<TrueFalseEdit {...falseProps} />)

      const trueInput = screen.getByRole('radio', {
        name: new RegExp(`Answer: ${props.interactionData.trueChoice}`),
      })
      expect(trueInput.checked).toBe(false)

      const falseInput = screen.getByRole('radio', {
        name: new RegExp(`Answer: ${props.interactionData.falseChoice}`),
      })
      expect(falseInput.checked).toBe(true)
    })
  })

  describe('overrideEditableForRegrading', () => {
    it('disables the calculator option', () => {
      render(<TrueFalseEdit {...props} overrideEditableForRegrading />)

      const calculatorCheckbox = screen.getByRole('checkbox', {name: /show on-screen calculator/i})
      const calculatorBasicRadioInput = screen.getByRole('radio', {name: /basic calculator/i})
      const calculatorScientificRadioInput = screen.getByRole('radio', {
        name: /scientific calculator/i,
      })

      expect(calculatorCheckbox.disabled).toBe(true)
      expect(calculatorBasicRadioInput.disabled).toBe(true)
      expect(calculatorScientificRadioInput.disabled).toBe(true)
    })
  })

  describe('a11y tests', () => {
    it('should meet a11y standards', async () => {
      render(
        <main>
          <TrueFalseEdit {...props} />
        </main>,
      )

      expect(
        await runAxeCheck(document.body, {
          ignores: ['scrollable-region-focusable'],
        }),
      ).toBe(true)
    })
  })

  describe('calculator per question option', () => {
    it('does not render the options if showCalculatorOption is false', () => {
      render(<TrueFalseEdit {...props} showCalculatorOption={false} />)
      expect(screen.queryByRole('button', {name: /options/i})).toBeNull()
    })

    it('renders the calculator per question option', () => {
      render(<TrueFalseEdit {...props} />)

      const calculatorCheckboxes = screen.queryAllByRole('checkbox', {
        name: /show on-screen calculator/i,
      })
      expect(calculatorCheckboxes).toHaveLength(1)
    })

    it('calls the correct callback function with the correct data when the calculator type is changed', () => {
      render(<TrueFalseEdit {...props} />)

      const scientificOption = screen.getByRole('radio', {name: /scientific calculator/i})
      userEvent.click(scientificOption)

      expect(changeItemStateStub).toHaveBeenCalledWith(
        expect.objectContaining({calculatorType: 'scientific'}),
      )
    })

    it('calls the correct callback function when OQAAT is changed', () => {
      render(<TrueFalseEdit {...props} />)

      const toggle = screen.getByRole('checkbox', {name: /enable one question at a time/i})
      userEvent.click(toggle)

      expect(setOneQuestionAtATimeStub).toHaveBeenCalledTimes(1)
    })
  })
})
