import React, {
  forwardRef,
  useContext,
  useEffect,
  useImperativeHandle,
  useRef,
  useState,
} from 'react';
import {
  NativeSyntheticEvent,
  TextInput,
  TextInputFocusEventData,
  TouchableOpacity,
  View,
} from 'react-native';
import { ApplicationContext, MiniAppContext } from '../Context';
import { Icon } from '../Icon';
import { Text, useScaleSize } from '../Text';
import { Spacing } from '../Consts';
import { ErrorView, FloatingView, getBorderColor, MAX_LENGTH } from './common';
import { InputTextAreaProps } from './index';
import styles from './styles';
import SystemTextInput from './SystemTextInput';
import { useComponentId } from '../Application';

const InputTextArea = forwardRef(
  (
    {
      errorMessage,
      onChangeText,
      floatingIconColor,
      floatingIcon,
      floatingValue,
      onFocus,
      onBlur,
      disabled = false,
      value,
      defaultValue,
      height,
      placeholder,
      maxLength = MAX_LENGTH,
      required,
      errorSpacing,
      style,
      hintText,
      ...props
    }: InputTextAreaProps,
    ref,
  ) => {
    const componentName = 'InputTextArea';

    const { componentId } = useComponentId(
      `${componentName}/${placeholder}`,
      props.accessibilityLabel,
    );
    const { theme } = useContext(ApplicationContext);
    const context = useContext<any>(MiniAppContext);
    const DEFAULT_HEIGHT = useScaleSize(104);

    const showBaseLineDebug = context?.features?.showBaseLineDebug ?? false;
    const scaledFontSize = useScaleSize(14);
    const [focused, setFocused] = useState(false);
    const [inputValue, setInputValue] = useState(defaultValue ?? '');
    const inputRef = useRef<TextInput | null>(null);

    useEffect(() => {
      setInputValue(value ?? '');
    }, [value]);

    const onClearText = () => {
      inputRef?.current?.clear();
      inputRef.current?.setNativeProps({ text: '' });
      _onChangeText('');
    };

    const _onChangeText = (text: string) => {
      onChangeText?.(text);
      setInputValue(text);
    };

    const _onFocus = (e: NativeSyntheticEvent<TextInputFocusEventData>) => {
      setFocused(true);
      onFocus?.(e);
    };

    const _onBlur = (e: NativeSyntheticEvent<TextInputFocusEventData>) => {
      setFocused(false);
      onBlur?.(e);
    };

    useImperativeHandle(ref, () => {
      return {
        clear: onClearText,
        focus: () => inputRef.current?.focus(),
        blur: () => inputRef.current?.blur(),
        setText: (text: string) => _onChangeText(text),
      };
    });

    const renderCountingView = () => {
      return (
        <View style={styles.countingView}>
          <Text
            color={theme.colors.text.hint}
            typography={'description_xs_regular'}
          >
            {`${inputValue.length}/${maxLength}`}
          </Text>
        </View>
      );
    };
    const renderInputView = () => {
      const disabledColor = theme.colors.text.disable;
      let textColor = theme.colors.text.default;
      let placeholderColor = theme.colors.text.hint;

      if (disabled) {
        textColor = disabledColor;
        placeholderColor = disabledColor;
      }

      return (
        <View
          style={[
            styles.textAreaWrapper,
            {
              height: height || DEFAULT_HEIGHT,
              backgroundColor: theme.colors.background.surface,
            },
            getBorderColor(theme, focused, errorMessage, disabled),
          ]}
        >
          <FloatingView
            floatingValue={floatingValue}
            floatingIconColor={floatingIconColor}
            disabled={disabled}
            floatingIcon={floatingIcon}
            required={required}
            componentId={componentId}
          />
          <View style={styles.rowArea}>
            <View style={styles.textAreaView}>
              <SystemTextInput
                {...props}
                ref={inputRef}
                accessibilityLabel={`${componentId}`}
                accessibilityState={{
                  disabled: disabled,
                  ...props.accessibilityState,
                }}
                editable={!disabled}
                textAlignVertical="top"
                allowFontScaling={false}
                style={[
                  {
                    width: '100%',
                    flex: 1,
                    paddingRight: Spacing.XS,
                    paddingVertical: Spacing.XS,
                    fontSize: scaledFontSize,
                  },
                  {
                    color: textColor,
                  },
                ]}
                defaultValue={defaultValue}
                maxLength={maxLength}
                textBreakStrategy="highQuality"
                multiline={true}
                value={inputValue}
                onChangeText={_onChangeText}
                onFocus={_onFocus}
                onBlur={_onBlur}
                placeholder={placeholder}
                selectionColor={theme.colors.primary}
                placeholderTextColor={placeholderColor}
              />
            </View>
            {focused && inputValue.length > 0 && (
              <TouchableOpacity
                style={styles.iconWrapper}
                onPress={onClearText}
                accessibilityLabel={`${componentId}|clear-icon-touch`}
              >
                <Icon
                  source="24_navigation_close_circle_full"
                  size={16}
                  color={theme.colors.text.hint}
                  accessibilityLabel={`${componentId}|clear-icon`}
                />
              </TouchableOpacity>
            )}
          </View>
          {renderCountingView()}
        </View>
      );
    };

    return (
      <View
        style={[
          style,
          styles.wrapper,
          showBaseLineDebug && styles.debugBaseLine,
        ]}
      >
        {renderInputView()}
        <ErrorView
          errorMessage={errorMessage}
          errorSpacing={errorSpacing}
          hintText={hintText}
        />
      </View>
    );
  },
);

export default InputTextArea;
