import React from 'react';
import { Controller, useFormContext } from 'react-hook-form';

import Checkbox from '@mui/material/Checkbox';
import FormGroup from '@mui/material/FormGroup';
import FormLabel from '@mui/material/FormLabel';
import FormControl from '@mui/material/FormControl';
import FormHelperText from '@mui/material/FormHelperText';
import FormControlLabel, { formControlLabelClasses } from '@mui/material/FormControlLabel';

import { IRHFCheckboxProps, IRHFMultiCheckboxProps } from '../types';

/**
 * @description {RHFCheckbox} - React hook form checkbox component.
 * @param {IRHFCheckboxProps} name - The name of the checkbox.
 * @param {IRHFCheckboxProps} helperText - The helper text for the checkbox.
 * @param {IRHFCheckboxProps} other - Other props for the checkbox.
 * @return {JSX.Element} The rendered checkbox component.
 */
export const RHFCheckbox = ({ name, helperText, ...other }: IRHFCheckboxProps) => {
  const { control } = useFormContext();

  return (
    <Controller
      name={name}
      control={control}
      render={({ field, fieldState: { error } }) => (
        <div>
          <FormControlLabel control={<Checkbox {...field} checked={field.value} />} {...other} />

          {(!!error || helperText) && (
            <FormHelperText error={!!error}>{error ? error?.message : helperText}</FormHelperText>
          )}
        </div>
      )}
    />
  );
};

/**
 * @description {RHFMultiCheckbox} - Renders a multi-select checkbox component with form control and validation.
 * @param {Object} IRHFMultiCheckboxProps - Props for the RHFMultiCheckbox component
 * @return {JSX.Element} The multi-select checkbox component
 */
export const RHFMultiCheckbox = ({
  row,
  name,
  label,
  options,
  spacing,
  helperText,
  sx,
  ...other
}: IRHFMultiCheckboxProps) => {
  const { control } = useFormContext();

  const getSelected = (selectedItems: string[], item: string) =>
    selectedItems.includes(item)
      ? selectedItems.filter((value) => value !== item)
      : [...selectedItems, item];

  return (
    <Controller
      name={name}
      control={control}
      render={({ field, fieldState: { error } }) => (
        <FormControl component="fieldset">
          {label && (
            <FormLabel component="legend" sx={{ typography: 'body2' }}>
              {label}
            </FormLabel>
          )}

          <FormGroup
            sx={{
              ...(row && {
                flexDirection: 'row',
              }),
              [`& .${formControlLabelClasses.root}`]: {
                '&:not(:last-of-type)': {
                  mb: spacing || 0,
                },
                ...(row && {
                  mr: 0,
                  '&:not(:last-of-type)': {
                    mr: spacing || 2,
                  },
                }),
              },
              ...sx,
            }}
          >
            {options.map((option) => (
              <FormControlLabel
                key={option.value}
                control={
                  <Checkbox
                    checked={field.value.includes(option.value)}
                    onChange={() => field.onChange(getSelected(field.value, option.value))}
                  />
                }
                label={option.label}
                {...other}
              />
            ))}
          </FormGroup>

          {(!!error || helperText) && (
            <FormHelperText error={!!error} sx={{ mx: 0 }}>
              {error ? error?.message : helperText}
            </FormHelperText>
          )}
        </FormControl>
      )}
    />
  );
};
