import * as React from 'react';
import { Animated, Easing, TextInput, View, ViewProps } from 'react-native';
import { useRestyle, createVariant, createBox } from '@shopify/restyle';
import { colors, fonts, Theme } from './../../theme/theme';
import { Box } from '../Box';
import { Text, AnimatedText } from '../Text';
import { Normalize } from '../../utils/normalize';

type TextInputProps = React.ComponentPropsWithRef<typeof TextInput> & {
  label?: string;
  height?: number;
  icon?: React.ReactNode;
  error?: boolean;
  textHelper?: string;
  disabled?: boolean;
  width?: string | number;
  fontSize?: number;
  outlined?: boolean;
  backgroundColor?: keyof Theme['colors'];
  borderColor?: keyof Theme['colors'];
  borderActiveColor?: keyof Theme['colors'];
  paddingLeft?: number;
  rightComponent?: React.ReactNode;
  maxLength?: number;
};

const variant = createVariant<Theme>({
  themeKey: 'fonts',
  defaults: {
    flex: 1,
    paddingLeft: 'spacing-s',
    fontFamily: fonts.caustenRoundRegular,
    fontSize: Normalize(16),
    paddingBottom: 'spacing-xxxs',
  },
});

const ViewComponent = createBox<
  Theme,
  ViewProps & { children?: React.ReactNode }
>(View);
const restyleFunctions = [variant];

export const TextField = React.forwardRef<TextInput, TextInputProps>(
  (
    {
      width,
      label,
      height = Normalize(44),
      outlined = true,
      backgroundColor = 'white',
      borderColor = 'gray60',
      borderActiveColor = 'gray100',
      paddingLeft,
      fontSize,
      rightComponent,
      maxLength,
      ...rest
    },
    ref
  ) => {
    const props: any = useRestyle(restyleFunctions as any, rest);
    const [focus, setFocus] = React.useState(false);
    const focusAnim = React.useRef(new Animated.Value(0)).current;

    React.useEffect(() => {
      Animated.timing(focusAnim, {
        toValue: focus || !!rest?.value ? 1 : 0,
        duration: 200,
        easing: Easing.bezier(0.4, 0, 0.2, 1),
        useNativeDriver: false,
      }).start();
    }, [focusAnim, focus, rest?.value]);

    const alignItems = outlined ? 'center' : 'flex-end';

    return (
      <ViewComponent width={width || '100%'}>
        <Box
          flexDirection={'row'}
          justifyContent="space-between"
          alignItems={
            (focus || !!rest.value) && label ? 'flex-end' : alignItems
          }
          backgroundColor={
            rest.disabled && outlined ? 'gray25' : backgroundColor
          }
          height={height}
          paddingTop={label ? 'spacing-xs' : 'spacing-none'}
          width={'100%'}
          borderRadius={outlined ? Normalize(4) : 0}
          borderTopWidth={outlined ? Normalize(1) : 0}
          borderRightWidth={outlined ? Normalize(1) : 0}
          borderLeftWidth={outlined ? Normalize(1) : 0}
          borderBottomWidth={1}
          borderColor={
            rest.error
              ? 'chiperBrandRed'
              : !rest?.value
              ? borderColor
              : borderActiveColor
          }
        >
          {rest.icon && <Box paddingLeft={'spacing-xs'}>{rest.icon}</Box>}
          {label && (
            <AnimatedText
              fontFamily={'CaustenRound-Regular'}
              fontSize={Normalize(16)}
              color={
                rest.disabled
                  ? 'gray200'
                  : !rest?.value
                  ? 'gray200'
                  : 'darkBlueGray'
              }
              paddingLeft={outlined ? 'spacing-s' : 'spacing-none'}
              // eslint-disable-next-line react-native/no-inline-styles
              style={{
                position: 'absolute',
                top: focusAnim.interpolate({
                  inputRange: [0, 1],
                  outputRange: [13, 5],
                }),
                fontSize: focusAnim.interpolate({
                  inputRange: [0, 1],
                  outputRange: [Normalize(16), Normalize(10)],
                }),
              }}
            >
              {label}
            </AnimatedText>
          )}
          <TextInput
            {...props}
            style={[
              ...props.style,
              {
                color: rest.disabled ? colors.gray200 : colors.yankeesBlue,
                fontFamily: 'CaustenRound-Regular',
              },
              fontSize ? { fontSize } : {},
              paddingLeft != null ? { paddingLeft } : {},
            ]}
            ref={ref}
            clearButtonMode="while-editing"
            placeholderTextColor={colors.gray200}
            editable={!rest.disabled}
            onFocus={() => setFocus(true)}
            onBlur={() => setFocus(false)}
            placeholder={!focus && label ? '' : rest.placeholder}
            maxLength={maxLength || props.maxLength}
          />
          {rightComponent}
        </Box>
        {rest.textHelper && (
          <Text
            fontSize={12}
            paddingLeft={'spacing-s'}
            marginTop={'spacing-xxs'}
            color={rest.error ? 'chiperBrandRed' : 'gray200'}
          >
            {rest.textHelper}
          </Text>
        )}
      </ViewComponent>
    );
  }
);
