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

import Checkbox, { CheckboxProps } from '@material-hu/mui/Checkbox';
import FormControlLabel from '@material-hu/mui/FormControlLabel';
import Radio, { RadioProps } from '@material-hu/mui/Radio';
import Typography from '@material-hu/mui/Typography';

import { useLokaliseTranslation } from 'src/utils/i18n';

import { FormOptionsTypes, OptionField } from './types';

export type CheckProps = {
  name: string;
  getOptionName: (index: number) => string;
  optionsName: string;
  index: number;
  type?: FormOptionsTypes;
  minChecked?: number;
  disabledCheck?: boolean;
  ignoreMinChecked?: boolean;
  color?:
    | 'primary'
    | 'secondary'
    | 'error'
    | 'info'
    | 'success'
    | 'warning'
    | 'default';
  checkboxProps?: CheckboxProps;
  radioProps?: RadioProps;
  showErrors?: boolean;
  label?: string;
};

export const Check: FC<CheckProps> = props => {
  const {
    name,
    getOptionName,
    optionsName,
    index,
    type = FormOptionsTypes.RADIO,
    minChecked = 1,
    disabledCheck = false,
    color = 'primary',
    ignoreMinChecked = false,
    checkboxProps = {},
    radioProps = {},
    showErrors = true,
    label,
  } = props;

  const { t } = useLokaliseTranslation('backoffice_only');
  const { setValue, watch } = useFormContext();

  const options: OptionField[] = watch(optionsName);
  const { checked } = watch(name);

  const countChecked = options.filter(option => option.checked).length;
  const isMinChecked = countChecked < minChecked;

  const handleChangeChecked = (newChecked: boolean) =>
    setValue(`${name}.checked`, newChecked);

  const handleChangeRadio = (event: ChangeEvent<HTMLInputElement>) => {
    options.forEach((_, optionIndex) =>
      setValue(`${getOptionName(optionIndex)}.checked`, false),
    );

    handleChangeChecked(event.target.checked);
  };

  const handleChangeCheckbox = (event: ChangeEvent<HTMLInputElement>) =>
    handleChangeChecked(event.target.checked);

  const isMinCheckedError = showErrors && !ignoreMinChecked && isMinChecked;

  return (
    <>
      {type === FormOptionsTypes.RADIO && (
        <FormControlLabel
          sx={{
            mx: 0.5,
            alignSelf: 'flex-start',
          }}
          label={label}
          control={
            <Radio
              aria-label={t(
                'backoffice_only:form_options.mark_as_correct_answer',
              )}
              aria-describedby={isMinCheckedError ? 'error-min' : undefined}
              onChange={handleChangeRadio}
              checked={checked}
              color={isMinCheckedError ? 'error' : color}
              disabled={disabledCheck}
              {...radioProps}
            />
          }
        />
      )}
      {type === FormOptionsTypes.CHECKBOX && (
        <FormControlLabel
          sx={{
            mx: 0.5,
            alignSelf: 'flex-start',
          }}
          label={label}
          control={
            <Checkbox
              aria-label={t(
                'backoffice_only:form_options.mark_as_correct_answer',
              )}
              aria-describedby={isMinCheckedError ? 'error-min' : undefined}
              onChange={handleChangeCheckbox}
              checked={checked}
              color={isMinCheckedError ? 'error' : color}
              disabled={
                disabledCheck ||
                (!checked && countChecked >= options.length - 1)
              }
              {...checkboxProps}
            />
          }
        />
      )}
      {type === FormOptionsTypes.LIST && (
        <Typography
          variant="body2"
          color="gray"
          sx={{
            width: '15px',
            mx: 0.5,
            alignSelf: 'flex-start',
          }}
        >
          {index + 1}
        </Typography>
      )}
    </>
  );
};

export default Check;
