import { css } from 'glamor';
import React from 'react';
import { useApphouse } from '../../context/useApphouse';
import { InputComponentStyles } from './input.styles.interface';
import { getComponentInputStyles } from './input.component.styles';
import { ResizableInput } from './ResizableInput';
import { InputToggleTypeButton } from './InputToggleTypeButton';
import { omit } from '../../utils/obj/omit';
import { observer } from 'mobx-react';
import { InputProps } from './input.interface';
import { useLocalStyles } from '../../styles/defaults/useLocalStyles';
import { InputWrapper } from './InputWrapper';

/**
 * An input component that comes packed with features
 */
export const Input = observer(
  React.forwardRef(
    (
      props: InputProps,
      ref: React.Ref<HTMLInputElement | HTMLTextAreaElement>
    ) => {
      const {
        value,
        onChange,
        placeholder,
        variant = 'm',
        label,
        children,
        id,
        multiline = false,
        required = false,
        type = 'text',
        styleOverwrites,
        gutters,
        description,
        fullWidth,
        password = false,
        error,
        width,
        ...rest
      } = props;
      const { theme } = useApphouse();
      const [iType, setIType] = React.useState(type);
      const [paddingRight, setPaddingRight] = React.useState('0px');
      const resizable = props.resizableWidth || props.resizableHeight || false;
      const [Component, setComponent] = React.useState<'input' | 'textarea'>(
        multiline || resizable ? 'textarea' : 'input'
      );

      const togglePasswordButtonRef = React.useRef<HTMLButtonElement>(null);
      const componentStyles: InputComponentStyles = getComponentInputStyles(
        theme,
        variant
      );
      const localStyles = useLocalStyles(
        componentStyles,
        styleOverwrites,
        gutters
      );
      const isPassword = password === true;
      // Padding in the input will be adjusted according to the type of the input
      // to take into account the toggle password button
      const inputPaddingOffset = isPassword ? { paddingRight } : {};

      React.useEffect(() => {
        if (password) {
          setIType('password');
          const padding =
            togglePasswordButtonRef.current &&
            togglePasswordButtonRef.current.offsetWidth;
          setPaddingRight(`${padding || 0}px`);
          setComponent('input');
        }
      }, [password, type, variant]);
      return (
        <InputWrapper
          fullWidth={fullWidth}
          variant={variant}
          label={label}
          id={id}
          required={required}
          styleOverwrites={localStyles}
          gutters={gutters}
          description={description}
          error={error}
          width={fullWidth ? '100%' : width}
        >
          {!children && resizable ? (
            <ResizableInput
              ref={ref as React.Ref<HTMLTextAreaElement>}
              styleOverwrites={localStyles.input}
              {...omit(props, ['styleOverwrites', 'ref'])}
            />
          ) : null}
          {!children && !resizable ? (
            <div
              {...css({ position: 'relative', width: '100%', display: 'flex' })}
            >
              <Component
                id={id}
                ref={ref as any}
                title="key"
                placeholder={placeholder}
                value={value}
                onChange={(e) => {
                  onChange && onChange(e.target.value);
                }}
                type={iType}
                data-xray="Input"
                data-style="input"
                autoComplete={type === 'password' ? 'new-password' : 'off'}
                onKeyDown={(e) => {
                  const shiftKey = e.shiftKey;
                  if (shiftKey && e.key === 'Enter') {
                    e.preventDefault();
                    e.stopPropagation();
                    // @ts-ignore
                    onChange && onChange(e.target?.value + '\n');
                  }
                }}
                {...css(
                  { width: '100%' },
                  localStyles.input,
                  inputPaddingOffset
                )}
                {...omit(rest, ['resizableWidth', 'resizableHeight', 'error'])}
              />
              {isPassword && (
                <InputToggleTypeButton
                  ref={togglePasswordButtonRef}
                  variant="clear"
                  size={variant}
                  onToggle={(type) => {
                    setIType(type);
                  }}
                  type={iType}
                  styleOverwrites={localStyles.passwordToggleButton}
                />
              )}
            </div>
          ) : null}

          {children ? children : null}
        </InputWrapper>
      );
    }
  )
);
