import clsx from 'clsx';
import React, { KeyboardEventHandler, useState } from 'react';
import { noop } from '../../../../helpers/utils';
import { FilterValidationResult, FilterValue } from '../../Filters.model';
import classes from './NumericTextFilter.scss';

export interface NumericTextFilterProps {
  value?: string | number;

  /** Callback triggered when a new filter value is selected */
  onSelect: (value: FilterValue) => void;

  /** Callback triggered when validation fails */
  onError?: () => void;

  /** Callback triggered for custom validations of the filter */
  onValidate?: (currentValue: FilterValue) => FilterValidationResult;

  /** CSS Class name for additional styles */
  className?: string;

  /** Optional id for the input field */
  inputId?: string;
}

export const NumericTextFilter: React.FC<NumericTextFilterProps> = ({
  value,
  onSelect,
  onError = noop,
  onValidate: customValidate,
  className = '',
  inputId,
}) => {
  const [errorMsg, setErrorMsg] = useState<string>();
  const ENTER_KEY = 'Enter';

  const [valueLocal, setValue] = useState(value || '');

  const handleKeyDown: KeyboardEventHandler<HTMLInputElement> = (e): void => {
    if (e.key === ENTER_KEY) {
      if (e.currentTarget.value === '') {
        onSelect(undefined);
        return;
      }

      const value = Number(e.currentTarget.value);

      const validationMessage = customValidate && customValidate(value);

      if (validationMessage) {
        setErrorMsg(validationMessage);
        onError();
      } else if (isNaN(value)) {
        setErrorMsg('Enter a number');
        onError();
      } else {
        onSelect(value);
      }
    }
  };

  return (
    <div
      className={clsx(
        classes.container,
        'numeric-text-filter-container',
        className,
      )}
    >
      <input
        id={inputId}
        autoFocus
        value={valueLocal}
        className={clsx(classes.inputValue, errorMsg && classes.hasError)}
        onKeyDown={handleKeyDown}
        type="number"
        onChange={(e) => setValue(e.target.value)}
      />
      {errorMsg !== undefined && <small>{errorMsg}</small>}
    </div>
  );
};
