import React, { useState } from 'react';
import i18next from 'i18next';
import PropTypes from 'prop-types';
import { ThemeProvider } from 'styled-components';

import { getTheme } from '../utils/theme';

import IconPlus from '../images/icon-plus-black.svg';
import IconMinus from '../images/icon-minus-black.svg';

import {
  Input,
  InputContainer,
  Text,
  Icon,
  ArrowsContainer,
  Arrow,
  MultipleInputContainer,
} from './styledComponents';

import { Props } from './interfaces';

const renderSingleInput = (
  min: number,
  value: number | string,
  onChange,
  isSingleInputHovered: boolean,
  setIsSingleInputHovered: Function,
  changeValue,
  height: string,
  borderStyle: string,
  borderRadius: string,
  width?: string
) => {
  return (
    <InputContainer
      height={height}
      width={width}
      borderStyle={borderStyle}
      borderRadius={borderRadius}
      onMouseEnter={() => setIsSingleInputHovered(true)}
      onMouseLeave={() => setIsSingleInputHovered(false)}
    >
      <Input min={min} type="number" onChange={onChange} value={value} />
      {isSingleInputHovered && (
        <ArrowsContainer>
          <Arrow top onClick={() => changeValue('+', value, '')}>
            <Icon top src={IconPlus} alt="icon-arrow-up-grey" />
          </Arrow>
          <Arrow onClick={() => changeValue('-', value, '')}>
            <Icon bottom src={IconMinus} alt="icon-arrow-down-grey" />
          </Arrow>
        </ArrowsContainer>
      )}
    </InputContainer>
  );
};

const renderMultipleInput = (
  min: number,
  limitValues: {
    minValue: number | string;
    maxValue: number | string;
  },
  onChange,
  isInputMinHovered: boolean,
  setIsInputMinHovered: Function,
  isInputMaxHovered: boolean,
  setIsInputMaxHovered: Function,
  changeValue,
  height: string,
  borderStyle: string,
  borderRadius: string,
  width?: string
) => {
  return (
    <MultipleInputContainer>
      <InputContainer
        height={height}
        width={width}
        borderStyle={borderStyle}
        borderRadius={borderRadius}
        onMouseEnter={() => setIsInputMinHovered(true)}
        onMouseLeave={() => setIsInputMinHovered(false)}
      >
        <Input
          id="min"
          min={min}
          type="number"
          onChange={(e) => onChange(e, e.target.id)}
          value={limitValues.minValue}
        />
        {isInputMinHovered && (
          <ArrowsContainer>
            <Arrow
              top
              onClick={() => changeValue('+', limitValues.minValue, 'min')}
            >
              <Icon top src={IconPlus} alt="icon-arrow-up-grey" />
            </Arrow>
            <Arrow
              onClick={() => changeValue('-', limitValues.minValue, 'min')}
            >
              <Icon bottom src={IconMinus} alt="icon-arrow-down-grey" />
            </Arrow>
          </ArrowsContainer>
        )}
      </InputContainer>
      <Text>{i18next.t('GENERAL_AND')}</Text>
      <InputContainer
        width={width}
        height={height}
        borderStyle={borderStyle}
        borderRadius={borderRadius}
        onMouseEnter={() => setIsInputMaxHovered(true)}
        onMouseLeave={() => setIsInputMaxHovered(false)}
      >
        <Input
          id="max"
          min={min}
          type="number"
          onChange={(e) => onChange(e, e.target.id)}
          value={limitValues.maxValue}
        />
        {isInputMaxHovered && (
          <ArrowsContainer>
            <Arrow
              top
              onClick={() => changeValue('+', limitValues.maxValue, 'max')}
            >
              <Icon top src={IconPlus} alt="icon-arrow-up-grey" />
            </Arrow>
            <Arrow
              onClick={() => changeValue('-', limitValues.maxValue, 'max')}
            >
              <Icon bottom src={IconMinus} alt="icon-arrow-down-grey" />
            </Arrow>
          </ArrowsContainer>
        )}
      </InputContainer>
    </MultipleInputContainer>
  );
};

const InputNumber = (props: Props): JSX.Element => {
  const {
    value,
    limitValues,
    onChange,
    min,
    display,
    height,
    width,
    borderStyle,
    borderRadius,
    theme,
  } = props;

  const updatedTheme = getTheme(theme, 'inputnumber');

  const [isSingleInputHovered, setIsSingleInputHovered] = useState(false);
  const [isInputMinHovered, setIsInputMinHovered] = useState(false);
  const [isInputMaxHovered, setIsInputMaxHovered] = useState(false);

  const changeValue = (type, initialValue, id) => {
    const updatedValue =
      type === '+' ? initialValue + 1 : Math.max(min, initialValue - 1);

    onChange({ target: { value: updatedValue } }, id);
  };

  return (
    <ThemeProvider theme={updatedTheme}>
      {(display === 'multiple' &&
        renderMultipleInput(
          min,
          limitValues,
          onChange,
          isInputMinHovered,
          setIsInputMinHovered,
          isInputMaxHovered,
          setIsInputMaxHovered,
          changeValue,
          height,
          borderStyle,
          borderRadius,
          width
        )) ||
        renderSingleInput(
          min,
          value,
          onChange,
          isSingleInputHovered,
          setIsSingleInputHovered,
          changeValue,
          height,
          borderStyle,
          borderRadius,
          width
        )}
    </ThemeProvider>
  );
};

InputNumber.propTypes = {
  // eslint-disable-next-line react/forbid-prop-types
  theme: PropTypes.objectOf(PropTypes.any),
  min: PropTypes.number,
  value: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
  limitValues: PropTypes.shape({
    minValue: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
    maxValue: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
  }),
  onChange: PropTypes.func.isRequired,
  display: PropTypes.string,
  height: PropTypes.string,
  width: PropTypes.string,
  borderStyle: PropTypes.string,
  borderRadius: PropTypes.string,
};

InputNumber.defaultProps = {
  value: '',
  min: 0,
  display: 'single',
  limitValues: { minValue: '', maxValue: '' },
  height: '30px',
  width: null,
  borderStyle: '1px solid #dbdbdb',
  borderRadius: '4px',
  theme: null,
};

export default InputNumber;
