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

import TextField, { type TextFieldProps } from '@material-hu/mui/TextField';
import { sanitizeInput } from '@material-hu/utils/validations';

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

export type FormTextFieldProps = TextFieldProps &
  UseControllerProps & {
    ariaLabel?: string;
    resetOnEmptyBlur?: boolean;
    showErrors?: boolean;
    refValue?: React.Ref<HTMLInputElement | HTMLTextAreaElement>;
    min?: number;
    max?: number;
    minError?: string;
    maxError?: string;
    showCounter?: boolean;
    onAddCurrentAmount?: (value: number) => void;
    disableUnderline?: boolean;
  };

/**
 * @deprecated Use `@material-hu/components/design-system/Inputs/Classic` instead
 */
export const FormTextField = ({
  name,
  refValue,
  rules,
  defaultValue,
  resetOnEmptyBlur,
  onBlur: onBlurProp,
  showErrors = false,
  disabled,
  fullWidth = true,
  maxRows,
  minRows,
  multiline,
  placeholder,
  size,
  label,
  autoFocus,
  type,
  ariaLabel,
  variant,
  onFocus,
  onChange: onChangeProp,
  onKeyDown,
  onPaste,
  InputLabelProps,
  InputProps,
  inputProps,
  margin,
  sx,
  onClick,
  value: valueProp,
  helperText: helperTextProp,
  min,
  max,
  showCounter = false,
  onAddCurrentAmount,
  disableUnderline,
  ...others
}: FormTextFieldProps) => {
  const { control, setValue, watch } = useFormContext();
  const [previousState, setPreviousState] = useState('');

  const { t } = useLokaliseTranslation('web_only');

  const val = watch(name);
  const length = val?.length || 0;

  const getHelperText = (error?: FieldError) => {
    if (helperTextProp) {
      return helperTextProp;
    }
    if (showErrors && error?.message) return error.message;
    if (showCounter)
      return t('form_inputs.characters_counter', { count: length, max });
  };

  return (
    <Controller
      render={({
        field: { ref, onBlur, onChange, value, ...field },
        fieldState: { error },
      }) => (
        <>
          <TextField
            {...field}
            onChange={e => {
              if (onChangeProp) {
                onChangeProp(e);
                return;
              }
              onChange(e);
              if (onAddCurrentAmount) {
                const updatedValue = watch(name);
                onAddCurrentAmount(Number(updatedValue));
              }
            }}
            onFocus={e => {
              if (onFocus) {
                onFocus(e);
              }
              if (resetOnEmptyBlur) {
                setPreviousState(value);
              }
            }}
            onBlur={e => {
              onBlur();
              if (onBlurProp) onBlurProp(e);
              if (resetOnEmptyBlur && value === '')
                setValue(field.name, previousState);
              else {
                if (type === 'number') {
                  setValue(field.name, Number(value), {
                    shouldDirty: Number(value) !== Number(previousState),
                  });
                }
              }
            }}
            inputRef={refValue || ref}
            error={!!error}
            size={size}
            disabled={disabled}
            fullWidth={fullWidth}
            maxRows={maxRows}
            minRows={minRows}
            multiline={multiline}
            placeholder={placeholder}
            label={label}
            autoFocus={autoFocus}
            type={type}
            aria-label={ariaLabel}
            variant={variant}
            onKeyDown={onKeyDown}
            onPaste={onPaste}
            InputProps={(() => {
              // disableUnderline only works with 'standard' and 'filled' variants, not 'outlined'
              // Filter it out if variant is 'outlined' to prevent it from reaching the DOM
              if (variant === 'outlined') {
                if (InputProps) {
                  const { disableUnderline: _, ...restInputProps } =
                    InputProps as Record<string, unknown>;
                  return restInputProps;
                }
                return InputProps;
              }

              return {
                ...InputProps,
                ...(disableUnderline !== undefined && { disableUnderline }),
              };
            })()}
            InputLabelProps={InputLabelProps}
            inputProps={{
              maxLength: max,
              minLength: min,
              ...inputProps,
            }}
            margin={margin}
            sx={sx}
            onClick={onClick}
            helperText={getHelperText(error)}
            value={valueProp || value}
            {...others}
          />
        </>
      )}
      name={name}
      rules={{
        validate: {
          sanitize: input =>
            sanitizeInput(input, t('form_inputs.invalid_characters')),
        },
        ...rules,
      }}
      control={control}
      defaultValue={defaultValue}
    />
  );
};

export default FormTextField;
