import { TextInput, Platform, StyleSheet } from 'react-native';
import React, {
  forwardRef,
  useCallback,
  useEffect,
  useImperativeHandle,
  useState,
} from 'react';
import {
  interpolate,
  useAnimatedStyle,
  useSharedValue,
  withTiming,
} from 'react-native-reanimated';

import { fonts, colors } from '../../theme/theme';
import { Box, ReanimatedBox } from '../Box';
import { Text } from '../Text';
import type { TextAreaProps, TextAreaRef } from './interfaces';

/**
 * @label TextArea label
 * @input All props of TextInput component and "defaultLines" prop to show the number of lines in the TextArea
 * @props All props of Box component
 **/
export const TextArea = forwardRef<TextAreaRef, TextAreaProps>(
  ({ label, input, ...props }, ref) => {
    const overInput = useSharedValue(0);
    const [value, setValue] = useState(input?.defaultValue);
    useImperativeHandle(ref, () => ({ setImperativeValue: setValue }));

    const defaultLines = input?.defaultLines ?? 3;

    const spacingPlatform = Platform.OS === 'ios' ? 32 : 24;
    const minHeight = 16 * defaultLines + 8;
    const marginTop = Platform.OS === 'ios' ? -4 : 12;

    const Animate = useCallback(
      (focus?: boolean) => {
        if (value) overInput.value = 1;
        else overInput.value = focus ? 1 : 0;
      },
      [overInput, value]
    );

    const animatedBoxStyles = useAnimatedStyle(() => {
      const scaleInterpolation = interpolate(overInput.value, [0, 1], [1, 0.8]);
      const translateYInterpolation = interpolate(
        overInput.value,
        [0, 1],
        [6, -2]
      );
      const translateXInterpolation = interpolate(
        overInput.value,
        [0, 1],
        [4, -12]
      );
      return {
        transform: [
          { scale: withTiming(scaleInterpolation, { duration: 300 }) },
          {
            translateY: withTiming(translateYInterpolation, { duration: 300 }),
          },
          {
            translateX: withTiming(translateXInterpolation, { duration: 300 }),
          },
        ],
      };
    });

    useEffect(() => Animate(), [Animate, value]);

    return (
      <Box
        borderRadius={4}
        borderWidth={1}
        borderColor="gray200"
        paddingHorizontal="spacing-xs"
        minHeight={minHeight + spacingPlatform}
        backgroundColor={'white'}
        {...props}
      >
        <ReanimatedBox
          ml="spacing-xs"
          position="absolute"
          style={animatedBoxStyles}
        >
          <Text
            fontFamily={fonts.caustenRoundRegular}
            color="darkBlueGray"
            marginTop="spacing-xs"
            fontSize={16}
          >
            {label}
          </Text>
        </ReanimatedBox>

        <Box
          flex={1}
          alignItems="center"
          flexDirection="row"
          justifyContent="space-between"
          marginTop={Platform.OS === 'ios' ? 'spacing-s' : 'spacing-xs'}
          marginLeft="spacing-xxs"
        >
          <TextInput
            clearButtonMode="while-editing"
            autoCapitalize="none"
            multiline
            style={[styles.textInput, { marginTop, minHeight }]}
            onFocus={(e) => {
              Animate(true);
              input?.onFocus?.(e);
            }}
            onBlur={(e) => {
              Animate();
              input?.onBlur?.(e);
            }}
            {...input}
            onChangeText={(val) => {
              setValue(val);
              input?.onChangeText?.(val);
            }}
            value={value}
          />
        </Box>
      </Box>
    );
  }
);

const styles = StyleSheet.create({
  textInput: {
    flex: 1,
    borderRadius: 4,
    padding: 0,
    fontSize: 16,
    textAlignVertical: 'top',
    fontFamily: fonts.caustenRoundRegular,
    lineHeight: 20,
    color: colors.black,
  },
});
