import React, { Ref, useCallback, useMemo } from 'react';
import NumberFormat, { NumberFormatValues } from 'react-number-format';
import { bem } from 'utils/bem';
import { SInputNumber } from './s-input-number';
import { BgStyle } from 'common/styles/utils';
import { DEFAULT_MAX_LENGTH } from './constants';
import { CURRENCY_CODE_TO_SIGN } from 'common/constants';

interface Props {
  onBlur?(value?: number | string | null): void;
  onChange(value?: number | string | null): void;
  onKeyDown?(event: React.KeyboardEvent<HTMLInputElement>): void;
  isAllowed?(values: NumberFormatValues): boolean;
  value?: number | string | null;
  dataSelector?: string;
  decimalScale?: number;
  maxLength?: number;
  disabled?: boolean;
  isRequired?: boolean;
  isInvalid?: boolean;
  fixedDecimalScale?: boolean;
  bgStyle?: BgStyle;
  allowNegative?: boolean;
  shouldUseCurrencyFormat?: boolean;
  allowEmptyFormatting?: boolean;
  autoFocus?: boolean;
  className?: string;
  currencyCode?: string;
  suffix?: string;
}

const classes = bem('number-input');

export const InputNumber = React.memo(
  React.forwardRef(
    (
      {
        onBlur,
        value,
        onChange,
        isAllowed,
        bgStyle,
        dataSelector,
        disabled,
        isRequired,
        isInvalid,
        allowNegative = true,
        shouldUseCurrencyFormat = true,
        allowEmptyFormatting,
        autoFocus,
        fixedDecimalScale,
        maxLength = DEFAULT_MAX_LENGTH,
        decimalScale,
        className,
        currencyCode,
        suffix,
        onKeyDown,
      }: Props,
      ref: Ref<HTMLInputElement>
    ) => {
      const handleChange = useCallback(
        ({ floatValue }) => {
          onChange(floatValue);
        },
        [onChange]
      );

      const handleBlur = useCallback(() => {
        onBlur?.(value);
      }, [onBlur, value]);

      //TODO change to dynamic currency
      const prefix = useMemo(() => {
        if (currencyCode) {
          return CURRENCY_CODE_TO_SIGN[currencyCode];
        }
        return shouldUseCurrencyFormat ? '$' : undefined;
      }, [currencyCode, shouldUseCurrencyFormat]);

      return (
        <SInputNumber
          disabled={disabled}
          bgStyle={bgStyle}
          isRequired={isRequired}
          isInvalid={isInvalid}
          shouldUseCurrencyFormat={shouldUseCurrencyFormat}
          className={className}
        >
          <NumberFormat
            getInputRef={ref}
            decimalScale={decimalScale}
            maxLength={maxLength}
            className={classes()}
            onBlur={handleBlur}
            onValueChange={handleChange}
            thousandSeparator=","
            prefix={prefix}
            allowEmptyFormatting={allowEmptyFormatting}
            suffix={suffix}
            allowNegative={allowNegative}
            value={value}
            fixedDecimalScale={fixedDecimalScale}
            isAllowed={isAllowed}
            data-selector={dataSelector}
            disabled={disabled}
            onKeyDown={onKeyDown}
            autoFocus={autoFocus}
          />
        </SInputNumber>
      );
    }
  )
);
