import React, {forwardRef, ReactNode} from 'react';
import {StyleProp, ViewStyle} from 'react-native';
import {IconButton} from '@components/_HuGo/Button';
import {
  TextInput,
  TextInputProps,
  TextInputType,
} from '@components/_core/TextInput';

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

export interface InputClassicProps
  extends InputCommonProps,
    InputAccessibilities,
    Omit<TextInputProps, 'style' | 'size'> {
  RightComponent?: ReactNode;
  withClearButton?: boolean;
  /**
   * Show letters counter. This should be used with "maxLength" prop
   */
  showCounter?: boolean;
  style?: StyleProp<ViewStyle>;
  showStateIcon?: boolean;
  /**
   * Disable only the TextInput, not other components (to avoid disabled styles)
   */
  disableWithoutStyles?: boolean;
}

export const InputClassic = forwardRef<TextInputType, InputClassicProps>(
  (
    {
      value,
      onChangeText,
      label,
      helper,
      isError,
      isSuccess,
      disabled,
      onFocus,
      onBlur,
      showCounter,
      maxLength,
      RightComponent,
      withClearButton,
      multiline,
      style,
      size,
      /**
       * Use "defaultValue" instead of "value" if there are flickering issues in BottomSheet or other components.
       */
      defaultValue,
      showStateIcon = true,
      disableWithoutStyles = false,
      ...textInputProps
    },
    ref,
  ) => {
    const {
      inputRef,
      focused,
      focusInput,
      onInputBlur,
      onInputFocus,
      clearInput,
    } = useInputRef({ref, onFocus, onBlur, onChangeText});
    const inputValue = value ?? defaultValue;
    const inputLength = showCounter ? inputValue?.length || 0 : undefined;

    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={focusInput}
          style={style}
          showStateIcon={showStateIcon}
          RightComponent={
            RightComponent ||
            (withClearButton && focused && inputValue?.length && (
              <IconButton
                Icon={INPUT_ICONS.clear}
                variant="flat"
                onPress={clearInput}
              />
            ))
          }>
          <TextInput
            ref={inputRef}
            value={value}
            onChangeText={onChangeText}
            onFocus={onInputFocus}
            onBlur={onInputBlur}
            maxLength={maxLength}
            editable={!disabled && !disableWithoutStyles}
            multiline={multiline}
            defaultValue={defaultValue}
            accessibilityLabel={label}
            {...textInputProps}
          />
        </InputBox>
      </InputCore>
    );
  },
);

type InputClassicControllerProps = InputClassicProps & UseInputControllerProps;

export const InputClassicController = forwardRef<
  TextInputType,
  InputClassicControllerProps
>(({name, showSuccess, helper, ...props}, ref) => {
  const {onChange, ...inputController} = useInputController({
    name,
    showSuccess,
    helperText: helper,
  });

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