import * as React from 'react';
import {
  View,
  TextInput,
  Platform,
  NativeSyntheticEvent,
  TextInputFocusEventData,
} from 'react-native';

import { translate } from '../../i18n';
import { color, setFont } from '../../theme';
import { enhance } from '../../utils/object';
import { enhanceTextStyle, enhanceViewStyle } from '../../utils/styles';

import {
  blurredInputPresets,
  blurredViewPresets,
  focusedInputPresets,
  focusedViewPresets,
  inputPresets,
  placeholderTextColorPresets,
  viewPresets,
} from './text-field.presets';
import { TextFieldProps as Props } from './text-field.props';
import { textFieldStyles as styles } from './text-field.styles';

/**
 * A component which has an input text.
 *
 * @param {} placeholder optional placeholder text if no placeholderTx is provided.
 * @param {} placeholderTx Optional placeholder i18n key.
 * @param {} preset Optional look & feels.
 * @param {} rightComponent Optional component to show inside the text field on the right side.
 * @param {} textType Optional style to indicate the input keyboard format.
 * @param {} style Optional container style overrides useful for margins & padding.
 * @param {} inputStyle Optional style overrides for the input.
 */
export const TextField = React.forwardRef<TextInput, Props>((props, ref) => {
  const {
    placeholder,
    placeholderTx,
    preset,
    rightComponent,
    textType,
    onBlur,
    onFocus,
    style: styleOverride,
    inputStyle: inputStyleOverride,
    ...rest
  } = props;
  const [inputFocused, setInputFocus] = React.useState<boolean>(false);
  const focusContainerStyle = inputFocused
    ? focusedViewPresets[preset]
    : blurredViewPresets[preset];
  const focusInputStyle = inputFocused ? focusedInputPresets[preset] : blurredInputPresets[preset];
  /* eslint-disable indent */
  const containerStyle =
    Platform.OS === 'ios'
      ? enhanceViewStyle([
          styles.container,
          viewPresets[preset],
          focusContainerStyle,
          styleOverride,
        ])
      : enhanceViewStyle([viewPresets[preset], focusContainerStyle, styleOverride]);
  /* eslint-enable indent */
  const inputStyle = setFont(
    enhanceTextStyle([styles.input, inputPresets[preset], focusInputStyle, inputStyleOverride]),
  );
  const actualPlaceholder = placeholderTx ? translate(placeholderTx) : placeholder;
  const placeholderTextColor = placeholderTextColorPresets[preset] || props.placeholderTextColor;
  const enhancedRest =
    textType === 'email'
      ? enhance([rest, { keyboardType: 'email-address', textContentType: 'emailAddress' }])
      : rest;

  /* Blur event handler */
  const handleBlurEvent = React.useCallback(
    (e: NativeSyntheticEvent<TextInputFocusEventData>) => {
      setInputFocus(false);
      if (typeof onBlur === 'function') {
        onBlur(e);
      }
    },
    [onBlur],
  );

  /* Focus event handler */
  const handleFocusEvent = React.useCallback(
    (e: NativeSyntheticEvent<TextInputFocusEventData>) => {
      setInputFocus(true);
      if (typeof onFocus === 'function') {
        onFocus(e);
      }
    },
    [onFocus],
  );

  return (
    <View style={containerStyle}>
      <TextInput
        {...{ ref }}
        {...{ placeholderTextColor }}
        placeholder={actualPlaceholder}
        placeholderTextColor={color.dim}
        style={inputStyle}
        underlineColorAndroid={color.transparent}
        onBlur={handleBlurEvent}
        onFocus={handleFocusEvent}
        {...enhancedRest}
      />
      {rightComponent}
    </View>
  );
});

TextField.displayName = 'TextField';
TextField.defaultProps = {
  textType: 'default',
};
