import TooltipLabel from '@/editor/Tooltips/TooltipLabel'
import TooltipSwitch from '@/editor/Tooltips/TooltipSwitch'
import { GENERIC_CONTENT } from '@/editor/assets/generalContent'
import { QUESTIONNAIRE_QUESTION_FORM } from '@/editor/assets/pageContent/injectSpecification'
import {
  addQuestionnaireQuestion,
  updateQuestionnaireQuestion,
} from '@/editor/indexeddb/operations'
import type { ButtonProps } from '@blueprintjs/core'
import {
  Button,
  Dialog,
  DialogBody,
  DialogFooter,
  InputGroup,
} from '@blueprintjs/core'
import { notify } from '@inject/shared/notification/engine'
import type { FC } from 'react'
import { memo, useCallback, useEffect, useState } from 'react'
import type { QuestionnaireQuestion } from '../../indexeddb/types'
import QuestionCustomLabels from './QuestionCustomLabels'
import QuestionRangeLabels from './QuestionRangeLabels'

interface QuestionnaireQuestionFormProps {
  questionnaireQuestion?: QuestionnaireQuestion
  questionnaireId: number
  buttonProps: ButtonProps
}

const QuestionnaireQuestionForm: FC<QuestionnaireQuestionFormProps> = ({
  questionnaireQuestion,
  questionnaireId,
  buttonProps,
}) => {
  const [isOpen, setIsOpen] = useState(false)
  const [isValid, setIsValid] = useState(false)
  const [text, setText] = useState<string>('')
  const [max, setMax] = useState<number>(1)
  const [correct, setCorrect] = useState<number>(0)
  const [customLabels, setCustomLabels] = useState<boolean>(false)
  const [labels, setLabels] = useState<string>('')

  useEffect(() => {
    setText(questionnaireQuestion?.text || '')
    setMax(questionnaireQuestion?.max || 1)
    setCorrect(questionnaireQuestion?.correct || 0)
    setCustomLabels(
      (questionnaireQuestion?.labels !== '' &&
        questionnaireQuestion?.labels !== undefined) ||
        false
    )
    setLabels(questionnaireQuestion?.labels || '')
  }, [questionnaireQuestion, isOpen])

  useEffect(() => {
    setIsValid(
      text !== '' &&
        ((customLabels && labels !== '') || (!customLabels && max > 0))
    )
  }, [text, customLabels, labels, max])

  const clearInput = useCallback(() => {
    setText('')
    setMax(1)
    setCorrect(0)
    setCustomLabels(false)
    setLabels('')
  }, [])

  const handleAddButton = useCallback(
    async (questionnaireQuestion: Omit<QuestionnaireQuestion, 'id'>) => {
      try {
        await addQuestionnaireQuestion(questionnaireQuestion)
        clearInput()
        setIsOpen(false)
      } catch (err) {
        notify(
          `Failed to add questionnaire question '${questionnaireQuestion.text}': ${err}`,
          {
            intent: 'danger',
          }
        )
      }
    },
    [notify]
  )

  const handleUpdateButton = useCallback(
    async (questionnaireQuestion: QuestionnaireQuestion) => {
      try {
        await updateQuestionnaireQuestion(questionnaireQuestion)
        setIsOpen(false)
      } catch (err) {
        notify(
          `Failed to update questionnaire question '${questionnaireQuestion.text}': ${err}`,
          {
            intent: 'danger',
          }
        )
      }
    },
    [notify]
  )

  const onCorrectChange = useCallback(
    (newCorrect: number) => {
      if (correct === newCorrect) {
        setCorrect(0)
      } else {
        setCorrect(newCorrect)
      }
    },
    [correct]
  )

  return (
    <>
      <Button {...buttonProps} onClick={() => setIsOpen(true)} />
      <Dialog
        isOpen={isOpen}
        onClose={() => setIsOpen(false)}
        icon={questionnaireQuestion ? 'edit' : 'plus'}
        title={
          questionnaireQuestion
            ? 'Edit questionnaire question'
            : 'New questionnaire question'
        }
      >
        <DialogBody>
          <TooltipLabel label={QUESTIONNAIRE_QUESTION_FORM.text}>
            <InputGroup
              placeholder='Input text'
              value={text}
              onChange={e => setText(e.target.value)}
            />
          </TooltipLabel>
          <TooltipSwitch
            label={QUESTIONNAIRE_QUESTION_FORM.customLabels}
            switchProps={{
              checked: customLabels,
              onChange: () => setCustomLabels(!customLabels),
            }}
          />
          {customLabels ? (
            <QuestionCustomLabels
              labels={labels}
              correct={correct}
              onLabelsChange={(value: string) => setLabels(value)}
              onCorrectChange={(value: number) => onCorrectChange(value)}
            />
          ) : (
            <QuestionRangeLabels
              max={max}
              correct={correct}
              onMaxChange={(value: number) => setMax(value)}
              onCorrectChange={(value: number) => onCorrectChange(value)}
            />
          )}
        </DialogBody>
        <DialogFooter
          actions={
            questionnaireQuestion ? (
              <Button
                disabled={!isValid}
                onClick={() =>
                  handleUpdateButton({
                    id: questionnaireQuestion.id,
                    questionnaireId,
                    text,
                    max: customLabels ? labels.split(', ').length : max,
                    correct,
                    labels: customLabels ? labels : '',
                  })
                }
                intent='primary'
                icon='edit'
                text={GENERIC_CONTENT.buttons.save}
              />
            ) : (
              <Button
                disabled={!isValid}
                onClick={() =>
                  handleAddButton({
                    questionnaireId,
                    text,
                    max: customLabels ? labels.split(', ').length : max,
                    correct,
                    labels: customLabels ? labels : '',
                  })
                }
                intent='primary'
                icon='plus'
                text={GENERIC_CONTENT.buttons.add}
              />
            )
          }
        />
      </Dialog>
    </>
  )
}

export default memo(QuestionnaireQuestionForm)
