import React, {useCallback, useMemo, useRef, useState} from 'react';
import {View} from 'react-native';
import {useTranslation} from 'react-i18next';
import {
  TextInput,
  TextInputProps,
  TextInputType,
} from '@components/_core/TextInput';
import {Typography} from '@components/_core/Typography';
import {Dialog} from '@components/_HuGo/Dialog';
import {useTheme} from '@shared/theme';
import {MAX_INPUT_LENGTH} from '@shared/constants';

import {InputAccessibilities, InputCommonProps} from '../../interfaces';
import {
  useInputController,
  UseInputControllerProps,
} from '../../hooks/useInputController';
import {InputBox} from '../InputBox';
import {InputCore} from '../InputCore';
import {INPUT_STYLES} from '../../constants';
import {styles} from './styles';

interface InputTextAreaProps
  extends InputCommonProps,
    InputAccessibilities,
    Omit<TextInputProps, 'size'> {
  /**
   * Show letters counter. This should be used with "maxLength" prop
   */
  showCounter?: boolean;
  showFooterMessage?: boolean;
}

export function InputTextArea({
  value,
  onChangeText,
  label,
  helper,
  isError,
  isSuccess,
  defaultValue,
  disabled,
  showCounter,
  maxLength = MAX_INPUT_LENGTH,
  placeholder,
  numberOfLines = 5,
  size,
  showFooterMessage,
  ...textInputProps
}: InputTextAreaProps) {
  const {spacing, theme} = useTheme();
  const {t} = useTranslation();
  const dialogInputRef = useRef<TextInputType>(null);
  const [focused, setFocused] = useState(false);
  const inputLength = showCounter ? value?.length || 0 : undefined;
  const showPlaceholder = !!placeholder?.length && !value?.length;

  const onPressInput = useCallback(() => {
    setFocused(true);
    setTimeout(() => {
      dialogInputRef.current?.focus();
    }, 500);
  }, []);

  const onCloseModal = useCallback(() => {
    setFocused(false);
  }, []);

  const dialogFooter = useMemo(() => {
    return {
      secondaryButton: {text: t('general.done'), onPress: onCloseModal},
      ...(showFooterMessage && {
        infoText: t('general.max_characters', {maxLength}),
      }),
    };
  }, [onCloseModal, showFooterMessage, t, maxLength]);

  return (
    <>
      <InputCore
        label={label}
        helper={helper}
        isSuccess={isSuccess}
        isError={isError}
        focused={focused}
        disabled={disabled}
        inputLength={inputLength}
        inputMaxLength={maxLength}>
        <InputBox
          isSuccess={isSuccess}
          isError={isError}
          disabled={disabled}
          focused={focused}
          size={size}
          onPress={onPressInput}
          style={INPUT_STYLES.longInputSpacing}>
          <Typography
            style={styles.text}
            color={
              showPlaceholder
                ? theme.text.neutral.lighter
                : theme.text.neutral.default
            }
            numberOfLines={numberOfLines}>
            {showPlaceholder ? placeholder : value}
          </Typography>
        </InputBox>
      </InputCore>
      <Dialog
        fullScreen
        isVisible={focused}
        onClose={onCloseModal}
        title={label}
        footer={dialogFooter}
        footerKeyboardPaddingBottom={spacing.x2}
        contentStyle={styles.dialogContent}
        enableContentPanningGesture={false}>
        <View style={styles.inputContainer}>
          <TextInput
            {...textInputProps}
            autoFocus
            multiline
            useBottomSheetTextInput
            scrollEnabled
            editable={!disabled}
            defaultValue={defaultValue ?? value}
            onChangeText={onChangeText}
            maxLength={maxLength}
            placeholder={placeholder}
            ref={dialogInputRef}
            textAlignVertical="top"
            style={styles.input}
          />
        </View>
      </Dialog>
    </>
  );
}

type InputTextAreaControllerProps = InputTextAreaProps &
  UseInputControllerProps;

export function InputTextAreaController({
  name,
  showSuccess,
  helper,
  ...props
}: InputTextAreaControllerProps) {
  const {onChange, ...inputController} = useInputController({
    name,
    showSuccess,
    helperText: helper,
  });

  return (
    <InputTextArea {...props} {...inputController} onChangeText={onChange} />
  );
}
