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 HuCheckbox from '@material-hu/components/design-system/Checkbox/Checkbox';
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 CheckboxField: 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,
  });

  const handleChange = (optionIndex: number) => {
    const currentIndexes: number[] = Array.isArray(answer)
      ? answer
          .map((val: string | number) =>
            typeof val === 'number' ? val : choices.indexOf(val),
          )
          .filter((idx: number) => idx >= 0)
      : [];

    if (currentIndexes.includes(optionIndex)) {
      setValue(
        name,
        currentIndexes.filter((item: number) => item !== optionIndex),
      );
    } else {
      setValue(name, [...currentIndexes, optionIndex]);
    }
  };

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

  const selectedIndexes: number[] = Array.isArray(answer)
    ? answer
        .map((val: string | number) =>
          typeof val === 'number' ? val : choices.indexOf(val),
        )
        .filter((idx: number) => idx >= 0)
    : [];

  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,
          '& .MuiCheckbox-root': {
            width: checkboxSize,
            height: checkboxSize,
            borderColor: hasErrors
              ? ({ palette }) => palette.new.text.feedback.error
              : undefined,
            '&:hover': {
              backgroundColor: hasErrors
                ? ({ palette }) => palette.new.background.feedback.error
                : undefined,
            },
          },
          '& .PrivateSwitchBase-input': {
            width: checkboxSize,
            height: checkboxSize,
          },
          '& .MuiSvgIcon-root': {
            fontSize: checkboxSize,
          },
          '& svg': {
            width: checkboxSize,
            height: checkboxSize,
          },
        }}
      >
        {choices.map((option, index) => {
          return (
            <HuTooltip
              delay={300}
              key={option}
              description={option}
              disableTooltip={hasErrors}
            >
              <span
                style={{
                  display: 'flex',
                  alignItems: 'center',
                  justifyContent: 'center',
                }}
              >
                <HuCheckbox
                  sx={{
                    backgroundColor: ({ palette }) =>
                      palette.new.background.layout.tertiary,
                    '& .MuiCheckbox-root': {
                      width: checkboxSize,
                      height: checkboxSize,
                    },
                  }}
                  checked={selectedIndexes.includes(index)}
                  onChange={() => handleChange(index)}
                />
              </span>
            </HuTooltip>
          );
        })}
      </Stack>
    </HuTooltip>
  );
};

export default CheckboxField;
