import { useMemo } from 'react';
import { FormProvider, useForm, useWatch } from 'react-hook-form';
import { useMutation } from 'react-query';

import ListItem from '@material-hu/mui/ListItem';
import ListItemText from '@material-hu/mui/ListItemText';
import Stack from '@material-hu/mui/Stack';

import Alert from '@material-hu/components/design-system/Alert';
import Avatar from '@material-hu/components/design-system/Avatar';
import FormAutocomplete from '@material-hu/components/design-system/Inputs/Autocomplete/form';
import FormInputClassic from '@material-hu/components/design-system/Inputs/Classic/form';
import FormSwitcher from '@material-hu/components/design-system/Switcher/form';
import FormUploader from '@material-hu/components/design-system/Uploader/form';

import { QuestionType } from 'src/types/surveys';
import { fileAssetToFileCard, signedUploadV2 } from 'src/utils/filesUtils';
import { useLokaliseTranslation } from 'src/utils/i18n';

import FieldContainer from './components/FieldContainer';
import QuestionOptionsBuilder from './components/QuestionOptionsBuilder';
import {
  defaultChoices,
  getQuestionBuilderFormFieldsConfig,
  getQuestionTypesConfig,
  QUESTION_BUILDER_FORM_ID,
  questionTypesGroupsConfig,
  switcherFields,
} from './constants';
import {
  type QuestionBuilderFormProps,
  type QuestionBuilderFormValues,
  type QuestionTypeAutocompleteOption,
} from './types';
import { formResolver } from './utils';

const QuestionBuilderForm = ({
  onSubmit,
  defaultValues,
  disableSubmit = false,
  previewFields = false,
  typeOptions,
  hasComments = true,
  sections,
}: QuestionBuilderFormProps) => {
  const { t } = useLokaliseTranslation(['people_experience', 'surveys']);

  const form = useForm<QuestionBuilderFormValues>({
    defaultValues: defaultValues?.type?.value
      ? defaultValues
      : {
          id: new Date().getTime().toString(),
          type: typeOptions[0],
          choices: defaultChoices,
        },
    resolver: formResolver,
  });

  const { handleSubmit } = form;

  const questionTypesConfig = getQuestionTypesConfig(t);
  const questionBuilderFormFieldsConfig = getQuestionBuilderFormFieldsConfig(t);

  const uploadFileMutation = useMutation({
    mutationFn: async (file: File) => {
      const uploadedFile = await signedUploadV2(file);
      const fileCardData = fileAssetToFileCard(uploadedFile);
      return fileCardData;
    },
  });

  const formQuestionType = useWatch({
    name: questionBuilderFormFieldsConfig.type.name,
    control: form.control,
  });

  const getQuestionTypeHelperText = (type: QuestionType) => {
    switch (type) {
      case QuestionType.MULTIPLE_CHOICE:
        return t('question.single_choice_helper');
      case QuestionType.CHECKBOX:
        return t('question.multiple_choice_helper');
      default:
        return '';
    }
  };

  const filteredSwitcherFields = useMemo(
    () =>
      switcherFields.filter(field => {
        if (field === 'allowComments') {
          return !(formQuestionType?.value === QuestionType.TEXT);
        }

        if (field === 'required') {
          return !(
            formQuestionType?.value === QuestionType.INFO ||
            formQuestionType?.value === QuestionType.AUTOCOMPLETE
          );
        }

        return true;
      }),
    [formQuestionType?.value],
  );

  const handleSubmitForm = (data: QuestionBuilderFormValues) => {
    if (disableSubmit) {
      return;
    }
    onSubmit?.(data);
  };

  return (
    <FormProvider {...form}>
      <Stack
        component="form"
        id={QUESTION_BUILDER_FORM_ID}
        onSubmit={handleSubmit(handleSubmitForm)}
        sx={{ flex: 1, flexShrink: 0, gap: 2, pb: 2 }}
      >
        {previewFields && (
          <Alert
            title={t('question.question_bank_edit_alert')}
            severity="info"
          />
        )}
        <FieldContainer>
          <FormAutocomplete
            name={questionBuilderFormFieldsConfig.type.name}
            options={typeOptions}
            autocompleteProps={{
              label: questionBuilderFormFieldsConfig.type.label,
              disabled: previewFields,
              isServerFiltered: false,
              slotProps: {
                paper: {
                  sx: {
                    '.MuiAutocomplete-listbox': {
                      maxHeight: '500px',
                    },
                  },
                },
              },
              groupBy: option => {
                const matchingConfig =
                  questionTypesConfig[option.value as QuestionType];
                if (!matchingConfig) {
                  console.error(`No matching config found for ${option.value}`);
                  return '';
                }

                return t(
                  `surveys:question_type_groups.${matchingConfig.typeGroup.toLowerCase()}.label`,
                );
              },
              renderOption: (
                liProps,
                option: QuestionTypeAutocompleteOption,
              ) => {
                const matchingConfig = questionTypesConfig[option.value];
                if (!matchingConfig) {
                  console.error(`No matching config found for ${option.value}`);
                  return null;
                }

                const matchingGroupConfig =
                  questionTypesGroupsConfig[matchingConfig?.typeGroup];
                if (!matchingGroupConfig) {
                  console.error(
                    `No matching group config found for ${matchingConfig?.typeGroup}`,
                  );
                  return null;
                }
                return (
                  <ListItem
                    {...liProps}
                    key={option.value}
                    sx={{
                      gap: 1,
                    }}
                  >
                    <Avatar
                      Icon={matchingConfig.icon}
                      color={matchingGroupConfig.colorScope}
                    />
                    <ListItemText>{option.label}</ListItemText>
                  </ListItem>
                );
              },
              helperText: formQuestionType
                ? getQuestionTypeHelperText(formQuestionType.value)
                : '',
            }}
          />
        </FieldContainer>

        <FieldContainer>
          {/* TODO-SQGZ: Add topic back when integrating with People Experience */}
          {/* {hasTopic && (
              <FormTopicAutocomplete
                name="topic"
                autocompleteProps={{
                  disabled: previewFields,
                }}
              />
            )} */}
          <FormInputClassic
            name={questionBuilderFormFieldsConfig.title.name}
            inputProps={{
              label: questionBuilderFormFieldsConfig.title.label,
              disabled: previewFields,
              multiline: true,
              maxLength: 250,
            }}
          />

          <FormUploader
            name={questionBuilderFormFieldsConfig.attachments.name}
            uploaderProps={{
              label: questionBuilderFormFieldsConfig.attachments.label,
              disabled: previewFields,
              triggerOnChangeWhenUploading: true,
              slotProps: {
                root: {
                  sx: {
                    '& .MuiStack-root .MuiStack-root': {
                      backgroundColor: theme =>
                        theme.palette.new.background.layout.tertiary,
                    },
                  },
                },
              },
              uploadFunction: (file: File) =>
                uploadFileMutation.mutateAsync(file),
            }}
          />
        </FieldContainer>

        <QuestionOptionsBuilder
          questionType={formQuestionType?.value}
          sections={sections}
        />

        {filteredSwitcherFields.map(
          field =>
            ((field === 'allowComments' && hasComments) ||
              field === 'required') && (
              <FieldContainer key={field}>
                <FormSwitcher
                  name={questionBuilderFormFieldsConfig[field].name}
                  switcherProps={{
                    title: questionBuilderFormFieldsConfig[field].label,
                    disabled: previewFields,
                    titleProps: {
                      sx: {
                        color: theme => theme.palette.textColors?.neutralText,
                      },
                    },
                  }}
                />
              </FieldContainer>
            ),
        )}
      </Stack>
    </FormProvider>
  );
};

QuestionBuilderForm.id = QUESTION_BUILDER_FORM_ID;

export default QuestionBuilderForm;
