import { type ReactNode } from 'react';
import { Controller, type FieldError, useFormContext } from 'react-hook-form';

import FormControl, {
  type FormControlProps,
} from '@material-hu/mui/FormControl';
import FormHelperText from '@material-hu/mui/FormHelperText';
import InputLabel from '@material-hu/mui/InputLabel';
import ListItemIcon from '@material-hu/mui/ListItemIcon';
import MenuItem from '@material-hu/mui/MenuItem';
import SelectUI, {
  type SelectChangeEvent,
  type SelectProps,
} from '@material-hu/mui/Select';
import { styled } from '@material-hu/mui/styles';

import { type MUIMenuProps } from '@material-hu/components/design-system/Menu/types';

const Select = styled(SelectUI)(({ theme }) => ({
  '&.svgError': {
    '& svg': {
      color: theme.palette.new.text.feedback.error,
    },
  },
}));

const Control = styled(FormControl)({
  width: '100%',
});

const MenuPropsDefault = {
  PaperProps: {
    style: {
      maxHeight: '30%',
      width: '70%',
      borderRadius: '0',
    },
  },
};

type Props = {
  id?: string;
  name: string;
  label?: string;
  placeholder?: string;
  variant?: 'standard' | 'outlined' | 'filled';
  options: {
    label: string;
    value: any;
    icon?: ReactNode;
    disabled?: boolean;
  }[];
  selectProps?: SelectProps;
  formControlProps?: FormControlProps;
  rules?: any;
  defaultValue?: string;
  disabled?: boolean;
  disableUnderline?: boolean;
  renderMenuItems?: () => JSX.Element[];
  onChangeSkipStep?: (param: SelectChangeEvent<unknown>) => void | undefined;
  MenuProps?: Partial<MUIMenuProps>;
  IconComponent?: React.ElementType;
  showErrors?: boolean;
  helperText?: string;
};

/**
 * @deprecated Use `@material-hu/components/design-system/Inputs/Autocomplete` instead
 */
function FormSelect({
  id,
  name,
  label,
  placeholder,
  variant = 'standard',
  options,
  rules,
  selectProps,
  defaultValue,
  disabled,
  formControlProps,
  renderMenuItems,
  onChangeSkipStep = () => undefined,
  MenuProps = MenuPropsDefault,
  disableUnderline = false,
  IconComponent,
  helperText: helperTextProp,
  showErrors = false,
}: Props) {
  const { control } = useFormContext();

  const getHelperText = (error?: FieldError) => {
    if (helperTextProp) {
      return helperTextProp;
    }
    if (showErrors && error?.message) return error.message;
  };

  // Only filled inputs have the prop 'disableUnderline'
  const selectVariantProps =
    variant === 'filled'
      ? {
          ...selectProps,
          disableUnderline,
        }
      : { ...selectProps };

  return (
    <Control
      disabled={disabled}
      {...formControlProps}
    >
      <InputLabel>{label}</InputLabel>
      <Controller
        control={control}
        name={name}
        rules={rules}
        defaultValue={defaultValue ?? ''}
        render={({
          field: { ref, onChange, ...field },
          fieldState: { error },
        }) => (
          <>
            <Select
              id={id}
              variant={variant}
              className={error?.type === 'required' ? 'svgError' : undefined}
              label={label}
              {...field}
              {...selectVariantProps}
              error={!!error}
              inputRef={ref}
              MenuProps={MenuProps}
              onChange={e => {
                onChange(e);
                onChangeSkipStep(e);
              }}
              IconComponent={IconComponent}
            >
              {placeholder && (
                <MenuItem
                  disabled
                  value=""
                >
                  <em>{placeholder}</em>
                </MenuItem>
              )}
              {renderMenuItems && renderMenuItems()}
              {!renderMenuItems &&
                options.map(option => (
                  <MenuItem
                    value={option.value}
                    key={option.value}
                    disabled={option.disabled}
                    sx={{ alignItems: 'center' }}
                  >
                    {!!option.icon && (
                      <ListItemIcon sx={{ mr: 0 }}>{option.icon}</ListItemIcon>
                    )}
                    {option.label}
                  </MenuItem>
                ))}
            </Select>
            {showErrors && (
              <FormHelperText error={!!error}>
                {getHelperText(error)}
              </FormHelperText>
            )}
          </>
        )}
      />
    </Control>
  );
}

export default FormSelect;
