import { useState } from 'react';
import { useFormContext, useWatch } from 'react-hook-form';
import { useMatch } from 'react-router-dom';

import CheckBoxOutlined from '@material-hu/icons/material/CheckBoxOutlined';
import RadioButtonCheckedOutlined from '@material-hu/icons/material/RadioButtonCheckedOutlined';
import ShortTextOutlined from '@material-hu/icons/material/ShortTextOutlined';
import Avatar from '@material-hu/mui/Avatar';
import Stack from '@material-hu/mui/Stack';
import Switch from '@material-hu/mui/Switch';
import { useTheme } from '@material-hu/mui/styles';
import Typography from '@material-hu/mui/Typography';

import CardContainer from '@material-hu/components/design-system/CardContainer';
import { type FileCardType } from '@material-hu/components/design-system/FileCard/types';
import FormUploader from '@material-hu/components/design-system/Uploader/form';

import {
  OPTIONS_QUESTION_TYPES,
  QUESTION_EXPLANATION_MAX_LENGTH,
  QUESTION_MAX_LENGTH,
  QUESTION_MIN_CHECKED,
  QUESTION_MIN_LENGTH,
  QUESTION_MIN_OPTIONS,
} from 'src/pages/dashboard/Learning/Courses/New/constants';
import { getQuestionElementId } from 'src/pages/dashboard/Learning/Courses/New/utils';
import { coursesRoutes } from 'src/pages/dashboard/Learning/Courses/routes';
import {
  type QuestionFormValues,
  QuestionSubheaders,
  type Selected,
} from 'src/pages/dashboard/Learning/Courses/types';
import { QuestionType } from 'src/types/surveys';
import { catchError } from 'src/utils/catchError';
import {
  bytesToSize,
  megabytesToBytes,
  signedUploadV2,
} from 'src/utils/filesUtils';
import { useLokaliseTranslation } from 'src/utils/i18n';

import FormOptions from 'src/components/FormInputs/FormOptions';
import {
  FormOptionsTypes,
  type Option,
} from 'src/components/FormInputs/FormOptions/types';
import FormSelect from 'src/components/FormInputs/FormSelect';
import FormSwitch from 'src/components/FormInputs/FormSwitch';
import FormTextField from 'src/components/FormInputs/FormTextField';

import { questionFields } from './forms';

export type CreateQuestionProps = {
  disabled?: boolean;
  selected: Selected;
  index: number;
  getNewOption?: (index: number) => Option;
  showErrors?: boolean;
  editDisabled?: boolean;
};

const CreateQuestion = ({
  disabled = false,
  selected,
  index,
  getNewOption = () => ({
    value: '',
    label: '',
    checked: false,
  }),
  showErrors = false,
  editDisabled = false,
}: CreateQuestionProps) => {
  const theme = useTheme();
  const { t } = useLokaliseTranslation([
    'learning',
    'attachments',
    'material_hu_only',
  ]);
  const { setValue, getValues, control } = useFormContext<QuestionFormValues>();
  const isEdit = !!useMatch(coursesRoutes.editCourse());

  const [type, hasExplanation, attachments] = useWatch({
    name: ['type', 'hasExplanation', 'attachments'],
    control,
  });
  const hasAttachments = Boolean(attachments && attachments.length > 0);

  const [showUploader, setShowUploader] = useState(hasAttachments);

  const hasImage = hasAttachments || showUploader;

  const typeOptions = [
    {
      value: QuestionSubheaders.GENERAL,
      label: t('common.generals'),
      subheader: true,
    },
    {
      value: QuestionType.TEXT,
      label: t('common.text'),
      icon: (
        <Avatar sx={{ bgcolor: '#CFF9FE' }}>
          <ShortTextOutlined
            fontSize="small"
            sx={{ color: '#164C63' }}
          />
        </Avatar>
      ),
    },
    {
      value: QuestionSubheaders.SELECTION,
      label: t('common.selection'),
      subheader: true,
    },
    {
      value: QuestionType.MULTIPLE_CHOICE,
      label: t('common.unique_choice'),
      icon: (
        <Avatar sx={{ bgcolor: '#F4EBFF' }}>
          <RadioButtonCheckedOutlined
            fontSize="small"
            sx={{ color: '#6941C6' }}
          />
        </Avatar>
      ),
    },
    {
      value: QuestionType.CHECKBOX,
      label: t('common.multiple_choice'),
      icon: (
        <Avatar sx={{ bgcolor: '#F4EBFF' }}>
          <CheckBoxOutlined
            fontSize="small"
            sx={{ color: '#6941C6' }}
          />
        </Avatar>
      ),
    },
  ];

  const handleChangeType = (event: React.ChangeEvent<HTMLInputElement>) => {
    const newType = event.target.value as QuestionType;

    let newChoices = getValues('choices') || [];

    if (newChoices.length < (QUESTION_MIN_OPTIONS[newType] || 0)) {
      newChoices = [...newChoices, getNewOption(newChoices.length)];
    }

    setValue('points', newType === QuestionType.TEXT ? 0 : 1);
    setValue(
      'choices',
      newChoices.map(choice => ({ ...choice, checked: false })),
    );
  };

  const handleUploadFile = async (file: File): Promise<FileCardType> => {
    const [error, fileAsset] = await catchError(signedUploadV2(file));
    if (error) return { status: 'error', file: file };
    return { status: 'success', file, fileAsset };
  };

  const handleChangeUploaderSwitch = (
    event: React.ChangeEvent<HTMLInputElement>,
  ) => {
    const isSwitchChecked = event.target.checked;

    if (!isSwitchChecked) {
      setValue(questionFields.attachments(), []);
    }

    setShowUploader(isSwitchChecked);
  };

  return (
    <Stack
      id={getQuestionElementId(selected.module, selected.task, index)}
      sx={{
        gap: 2,
        width: '100%',
        '& .MuiOutlinedInput-root': {
          backgroundColor: theme.palette.background.paper,
        },
      }}
    >
      <Stack
        sx={{
          p: 2,
          gap: 1.5,
          width: '100%',
          borderRadius: theme.spacing(1),
          backgroundColor: '#F8F9FA',
        }}
      >
        <FormSelect
          name={questionFields.type()}
          label={t('common.type_of_question')}
          options={typeOptions}
          onChange={handleChangeType}
          disabled={editDisabled}
          variant="spaced"
        />
        <FormTextField
          id="question-title-input"
          label={t('general:question')}
          name={questionFields.title()}
          required={isEdit}
          maxLength={QUESTION_MAX_LENGTH}
          minLength={QUESTION_MIN_LENGTH}
          disabled={disabled}
          fullWidth
          multiline
          minRows={2}
          maxRows={2}
        />
        {OPTIONS_QUESTION_TYPES.includes(type) && (
          <FormOptions
            name={questionFields.choices.all()}
            label={t('common.select_answers')}
            optionLabel={t('general:correct_one')}
            addLabel={t('common.add_answer')}
            checkSide="right"
            getNewOption={getNewOption}
            min={
              QUESTION_MIN_OPTIONS[type as keyof typeof QUESTION_MIN_OPTIONS]
            }
            minChecked={QUESTION_MIN_CHECKED}
            disabledCheck={editDisabled}
            showAdd={!editDisabled}
            removeDisplay={editDisabled ? 'never' : 'hover'}
            showErrors={showErrors}
            color="success"
            formTextFieldProps={{
              maxLength: QUESTION_MAX_LENGTH,
              required: true,
            }}
            type={
              type === QuestionType.MULTIPLE_CHOICE
                ? FormOptionsTypes.RADIO
                : FormOptionsTypes.CHECKBOX
            }
          />
        )}
        {QuestionType.TEXT === type && (
          <FormTextField
            name={questionFields.text()}
            InputProps={{ readOnly: true }}
            placeholder={t('common.colaborator_answer_placeholder')}
          />
        )}
      </Stack>

      <CardContainer
        fullWidth
        color="grey"
      >
        <Stack sx={{ flexDirection: 'row', alignItems: 'center' }}>
          <Switch
            disabled={disabled}
            checked={hasImage}
            onChange={handleChangeUploaderSwitch}
            sx={{ ml: -1, mr: 1.5 }}
          />
          <Typography variant="subtitle2">
            {t('attachments:attach_image')}
          </Typography>
        </Stack>
        {hasImage && (
          <FormUploader
            name={questionFields.attachments()}
            uploaderProps={{
              disabled,
              maxFiles: 1,
              showUploadButtonOnMaxFiles: false,
              fileSizeLimit: megabytesToBytes(10),
              acceptedTypes: ['image'],
              triggerOnChangeWhenUploading: true,
              uploadFunction: handleUploadFile,
              slotProps: { fileCard: { showRemoveUploadingButton: false } },
              sx: {
                width: '100%',
                '& [role="presentation"]': {
                  backgroundColor: theme.palette.background.paper,
                },
              },
            }}
          />
        )}
      </CardContainer>
      <CardContainer
        color="grey"
        fullWidth
      >
        <Stack sx={{ flexDirection: 'row', alignItems: 'center' }}>
          <FormSwitch
            id="question-has-explanation-input"
            name={questionFields.hasExplanation()}
            aria-labelledby="question-has-explanation-label"
            disabled={disabled}
            sx={{ m: 0 }}
          />
          <Typography
            id="question-has-explanation-label"
            variant="subtitle2"
          >
            {t('course.lesson.answer_explanation')}
          </Typography>
        </Stack>
        {hasExplanation && (
          <FormTextField
            id="question-explanation-input"
            name={questionFields.explanation()}
            placeholder={t('course.lesson.answer_explanation_placeholder')}
            label={t('course.lesson.answer_explanation')}
            maxLength={QUESTION_EXPLANATION_MAX_LENGTH}
            fullWidth
            multiline
            minRows={4}
            maxRows={4}
            disabled={disabled}
            required
            sx={{ mt: 2 }}
          />
        )}
      </CardContainer>
    </Stack>
  );
};

export default CreateQuestion;
