import type { OptionProps } from '@blueprintjs/core'
import {
  Colors,
  Divider,
  NonIdealState,
  Radio,
  RadioGroup,
  Spinner,
} from '@blueprintjs/core'
import { css } from '@emotion/css'
import type { Question } from '@inject/graphql/fragments/Question.generated'
import type { QuestionnaireDetails } from '@inject/graphql/fragments/QuestionnaireDetails.generated'
import type { AnswerInput } from '@inject/graphql/types'
import useTeamQuestionnaireStateSubscription from '@inject/graphql/utils/useTeamQuestionnaireStateSubscription'
import ErrorMessage from '@inject/shared/components/ErrorMessage'
import type { FC } from 'react'
import { Fragment, useEffect, useState } from 'react'
import { INVALID_CHOICE, questionNumber } from './TraineeQuestionnaireContent'

const spinner = css`
  /* causes ever-changing overflows without the padding */
  padding: 1rem;
`

const wrapper = css`
  height: 100%;
  width: 100%;
  overflow-y: auto;
  display: grid;
  grid-template-columns: auto auto 1fr;
  row-gap: 0.5rem;
`

const radio = (correct: boolean) => css`
  padding-bottom: 0.2rem;
  border-bottom: 0.2rem solid ${correct ? Colors.GREEN5 : 'transparent'};
`

interface InstructorQuestionnaireContentProps {
  details: QuestionnaireDetails
  teamId: string
}

const InstructorQuestionnaireContent: FC<
  InstructorQuestionnaireContentProps
> = ({ details, teamId }) => {
  const [answers, setAnswers] = useState<AnswerInput[]>(
    details.questions.map(question => ({
      questionId: question.id,
      choice: INVALID_CHOICE,
    }))
  )

  const { data, loading, error } = useTeamQuestionnaireStateSubscription(
    teamId,
    details.id
  )
  useEffect(() => {
    if (!data || !data.questionnaireState) {
      return
    }
    const teamAnswers = data.questionnaireState.answers
    setAnswers(prev =>
      prev.map(answer => ({
        ...answer,
        choice:
          teamAnswers.find(
            teamAnswer => teamAnswer.question.id === answer.questionId
          )?.choice || answer.choice,
      }))
    )
  }, [data, details.questions])
  if (loading) {
    return <Spinner className={spinner} />
  }
  if (error) {
    return (
      <ErrorMessage>
        <h1>Error occurred!</h1>
        <p>{error.message}</p>
      </ErrorMessage>
    )
  }
  if (!data || !data.questionnaireState) {
    return (
      <NonIdealState
        icon='low-voltage-pole'
        title='No data'
        description='Please wait for the data to come in'
      />
    )
  }

  const getOptions = (
    question: Question
  ): readonly OptionProps<string | number>[] | undefined =>
    question.labels
      ? question.labels
          .split(',')
          .map(label => label.trim())
          .map((label, labelIndex) => ({
            label: label,
            value: labelIndex + 1,
          }))
      : [...Array(question.max).keys()].map(index => ({
          label: (index + 1).toString(),
          value: index + 1,
        }))

  return (
    <div className={wrapper}>
      {details.questions.map((question, questionIndex) => (
        <Fragment key={question.id}>
          {details.questions.length > 1 && (
            <>
              <div className={questionNumber}>{`${questionIndex + 1}.`}</div>
              <Divider />
            </>
          )}
          <RadioGroup
            disabled
            inline
            label={
              <div
                dangerouslySetInnerHTML={{
                  __html: question.content.rendered,
                }}
              />
            }
            selectedValue={
              answers[questionIndex].choice === INVALID_CHOICE
                ? undefined
                : answers[questionIndex].choice
            }
            onChange={() => {}}
          >
            {getOptions(question)?.map((option, index) => (
              <Radio
                className={radio(question.correct === option.value)}
                key={index}
                value={option.value}
                label={option.label}
              />
            ))}
          </RadioGroup>
        </Fragment>
      ))}
    </div>
  )
}

export default InstructorQuestionnaireContent
