import { type FC } from 'react';
import { useFormContext } from 'react-hook-form';

import { useTheme } from '@material-hu/mui/index';
import Stack from '@material-hu/mui/Stack';

import HuRadioButton from '@material-hu/components/design-system/RadioButton/RadioButton';
import HuTooltip from '@material-hu/components/design-system/Tooltip';

import { type SectionComponent } from 'src/pages/dashboard/serviceManagement/types';

import { usePdfCompletion } from '../../contexts/PdfFormCompletionProvider';
import { OPTION_GAP, OPTION_PADDING } from '../utils/constants';
import { getOptionSize } from '../utils/utils';

import useFieldErrorMessages from './useFieldErrorMessages';

type Props = {
  field: SectionComponent;
  dimensions: {
    width: number;
    height: number;
  };
};

const MultipleChoiceField: FC<Props> = ({ field, dimensions }) => {
  const {
    nameId: name,
    content: { choices = [], required },
  } = field;

  const theme = useTheme();
  const { showErrors } = usePdfCompletion();
  const { watch, setValue } = useFormContext();
  const answer = watch(name);

  const { hasErrors, getTooltipProps } = useFieldErrorMessages({
    showErrors,
    field,
    answer,
  });

  // Normalize current answer to an index for backward compatibility (strings -> index)
  let selectedIndex: number;
  if (typeof answer === 'number') {
    selectedIndex = answer;
  } else if (typeof answer === 'string') {
    selectedIndex = choices.indexOf(answer);
  } else {
    selectedIndex = -1;
  }

  const handleChange = (optionIndex: number) => {
    // Multiple choice field has single-value selection
    if (selectedIndex === optionIndex) {
      setValue(name, '', { shouldDirty: true, shouldValidate: true });
    } else {
      setValue(name, optionIndex, { shouldDirty: true, shouldValidate: true });
    }
  };

  const radioButtonSize = getOptionSize(
    choices.length,
    dimensions,
    OPTION_PADDING,
    OPTION_GAP,
  );

  const mainBgColor = required
    ? theme.palette.new.background.layout.brand
    : 'transparent';

  return (
    <HuTooltip
      {...getTooltipProps()}
      disableTooltip={!hasErrors}
    >
      <Stack
        sx={{
          backgroundColor: ({ palette }) =>
            hasErrors ? palette.new.background.feedback.error : mainBgColor,
          borderRadius: ({ shape }) => shape.borderRadiusM,
          cursor: 'pointer',
          gap: 1,
          p: 1,
          justifyContent: 'center',
          alignItems: 'center',
          '& .MuiButtonBase-root': {
            backgroundColor: ({ palette }) =>
              palette.new.background.layout.tertiary,
            '&:hover': {
              backgroundColor: hasErrors
                ? ({ palette }) => palette.new.background.feedback.error
                : undefined,
            },
          },
          '& .MuiSvgIcon-root': {
            fontSize: radioButtonSize,
            color: hasErrors
              ? ({ palette }) => palette.new.text.feedback.error
              : undefined,
          },
          '& svg': {
            width: radioButtonSize,
            height: radioButtonSize,
          },
        }}
      >
        {choices.map((option, index) => {
          return (
            <HuTooltip
              delay={300}
              key={index}
              description={option}
              disableTooltip={hasErrors}
            >
              <span
                style={{
                  width: radioButtonSize,
                  height: radioButtonSize,
                }}
              >
                <HuRadioButton
                  key={index}
                  label={''}
                  value={index}
                  isActive={selectedIndex === index}
                  checked={selectedIndex === index}
                  // We use onClick instead of onChange to allow for deselection functionality
                  onClick={() => handleChange(index)}
                  sx={{
                    backgroundColor: ({ palette }) =>
                      palette.new.background.layout.tertiary,
                  }}
                />
              </span>
            </HuTooltip>
          );
        })}
      </Stack>
    </HuTooltip>
  );
};

export default MultipleChoiceField;
