import { bool, func, any, node, number, oneOf, oneOfType, string } from 'prop-types';
import React, { useState } from 'react';
import Icon from '../Icon/index';
import css from '@styled-system/css';
import styled from '@emotion/styled';
import CurrencyIcon from './CurrencyIcon/index';

const InputWrapper = styled('div')(
  css({
    display: 'flex',
    borderRadius: 'input',
    paddingRight: '10px',
    position: 'relative',
    alignItems: 'center',
    paddingLeft: '10px',
    outline: 'none',
    boxShadow: 'none',
  }),
  ({ width, height, type, theme, error, disabled, backgroundColor }) =>
    css({
      width,
      height: type === 'textarea' ? '120px' : height,
      border: `1px solid ${error ? theme.colors.borderError : theme.colors.border}`,
      ':not(:focus-within):hover': {
        border: `1px solid ${theme.colors.borderActive}`,
      },
      ':focus-within': {
        outline: 'none',
        borderColor: theme.colors.borderFocus,
        boxShadow: `inset 0 0 0 1px ${theme.colors.borderFocus}`,
      },
      cursor: disabled ? 'not-allowed' : 'default',
      backgroundColor: backgroundColor || (disabled ? theme.colors.backgroundDisabled : 'white'),
      ':-moz-focusring': { color: 'transparent', textShadow: '0 0 0 #000' },
    }),
);

const TextInput = styled('input')(
  css({
    boxShadow: 'none',
    border: 'none',
    height: '100%',
    outline: 'none',
    fontSize: 'input',
    justifyContent: 'center',
    alignItems: 'center',
    paddingLeft: '5px',
    background: 'transparent',
    resize: 'none',
    width: '100%',
  }),
  ({ type, theme, disabled, error }) => ({
    cursor: disabled ? 'not-allowed' : 'initial',
    paddingTop: type === 'textarea' ? '8px' : '0px',
    paddingBottom: type === 'textarea' ? '8px' : '0px',
    '::placeholder': {
      color: theme.colors.placeholder,
      opacity: '1',
      textIndent: '0px',
    },
    color: disabled ? theme.colors.disabled : error ? theme.colors.error : theme.colors.input,
  }),
);

const EyeIcon = styled('div')(
  {
    alignItems: 'center',
    height: '100%',
    width: '20px',
  },
  ({ isPasswordField }) => ({
    position: 'absolute',
    display: isPasswordField ? 'flex' : 'none',
    cursor: isPasswordField ? 'pointer' : 'inherit',
    right: isPasswordField ? '8px' : 'unset',
  }),
);

const TextIcon = styled('div')(
  {
    alignItems: 'center',
    height: '100%',
    whiteSpace: 'nowrap',
  },
  ({ isIconField }) => ({
    display: !isIconField ? 'none' : 'inline-flex',
  }),
);

const Input = ({
  backgroundColor,
  as,
  currencyCode,
  className,
  value,
  icon,
  iconColor = 'Mid Neutral 2',
  iconRight,
  iconRightColor,
  onChange,
  placeholder,
  onBlur,
  error,
  width = '300px',
  height = '40px',
  type = 'text',
  min = '0',
  step = '1',
  disabled = false,
  readOnly = false,
  ...rest
}) => {
  const [isObscure, setIsObscure] = useState(true);

  function handleBlur(e) {
    if (onBlur) onBlur(e);
  }

  const Comp = as || type === 'textarea' ? 'textarea' : 'input';
  let inputType = type;
  let inputVal = value;
  let isReadOnly = readOnly;

  if (type === 'password' && !isObscure) {
    inputType = 'text';
  }
  if (currencyCode) {
    inputType = 'number';
  }

  return (
    <InputWrapper
      backgroundColor={backgroundColor}
      disabled={disabled}
      width={width}
      height={height}
      type={type}
      error={error}
      className={className}
    >
      <TextIcon isIconField={icon || currencyCode}>
        {currencyCode && !icon && <CurrencyIcon currencyCode={currencyCode} />}
        {icon && typeof icon === 'string' ? <Icon name={icon} color={iconColor} /> : icon}
      </TextIcon>
      <TextInput
        as={Comp}
        type={inputType}
        readOnly={isReadOnly}
        value={inputVal}
        placeholder={placeholder}
        onChange={onChange}
        onBlur={handleBlur}
        min={min}
        step={step}
        error={error}
        disabled={disabled}
        {...rest}
      />
      <EyeIcon isPasswordField={type === 'password'} onClick={() => setIsObscure(!isObscure)}>
        {isObscure ? <Icon name="eye-hidden" /> : <Icon name="eye-visible" />}
      </EyeIcon>
      <TextIcon isIconField={iconRight}>
        {iconRight && typeof iconRight === 'string' ? (
          <Icon name={iconRight} color={iconRightColor || iconColor} />
        ) : (
          iconRight
        )}
      </TextIcon>
    </InputWrapper>
  );
};

Input.propTypes = {
  backgroundColor: string,
  as: any,
  currencyCode: string,
  className: string,
  value: oneOfType([string, number]),
  icon: node,
  onChange: func,
  placeholder: string,
  onBlur: func,
  error: bool,
  type: oneOf(['text', 'submit', 'email', 'password', 'number', 'tel', 'textarea']),
  width: oneOfType([string, number]),
  height: oneOfType([string, number]),
  min: oneOfType([string, number]),
  step: oneOfType([string, number]),
  readOnly: bool,
  onKeyDown: func,
  unobscure: bool,
};

export default Input;
