import {
  GestureResponderEvent,
  TextInputProps,
  TouchableOpacityProps,
} from 'react-native';
import Input from './Input';
import InputDropDown from './InputDropDown';
import InputMoney from './InputMoney';
import InputOTP from './InputOTP';
import InputSearch from './InputSearch';
import InputTextArea from './InputTextArea';
import InputPhoneNumber from './InputPhoneNumber';
import { checkValidPhoneNumber } from './utils';

export type OTPInputLength = 2 | 4 | 6 | 8 | 10;

export interface InputProps extends TextInputProps {
  /**
   *  Optional. Defines the size of the Input component.
   */
  size?: 'small' | 'large';

  /**
   * Optional. Represents the value for the floating title in the Input component.
   */
  floatingValue?: string;

  /**
   * Optional. Represents the name or key of the floating icon to be displayed in the Input component.
   */
  floatingIcon?: string;

  /**
   * Optional. Represents the error message to be displayed below the Input component when there is an error.
   */
  errorMessage?: string;

  /**
   * Optional. Represents the name or key of the icon to be displayed in the Input component.
   */
  trailing?: string;

  /**
   * Optional. Represents the color of the icon in the Input component.
   */
  trailingColor?: string;

  /**
   * Optional. callback function to be called when the icon is pressed.
   */
  onPressTrailing?: () => void;

  /**
   * Optional. If `true`, the user won't be able to interact with the Input component.
   * Defaults to `false` if not provided.
   */
  disabled?: boolean;

  /**
   * Optional. Represents the color of the floating icon in the Input component.
   */
  floatingIconColor?: string;

  /**
   * Optional. If `true`, the Input component is marked as required,
   * indicating that the user must provide a value before submitting a form.
   * Defaults to `false` if not provided.
   */
  required?: boolean;

  /**
   * Optional. If `true`,
   * include spacing when Input not have error message.
   * Defaults to `false` if not provided.
   */
  errorSpacing?: boolean;

  /**
   *  If true, the icon of input will use be show indicator loading.
   */
  loading?: boolean;

  /**
   *  Optional. Represents the leading icon in the Input component.
   */
  leadingIcon?: string;

  /**
   * Optional. callback function to be called when the leading icon is pressed.
   */
  onPressLeadingIcon?: () => void;

  /**
   * Optional. Represents the color of the leading icon in the Input component.
   */
  leadingIconColor?: string;

  /**
   * Optional. Represents the font weight of the text in the Input component.
   */
  fontWeight?: string;

  /**
   * Optional. Params auto tracking component.
   */
  params?: any;

  /**
   * Optional. Represents text below the Input component.
   */
  hintText?: string;

  /**
   * Optional. Represents the style of the Input component.
   */
  onPressFloatingIcon?: () => void;

  /**
   * Optional. Represents the style of the Input component.
   */
  showClearIcon?: boolean;
}

export interface InputTextAreaProps extends Omit<InputProps, 'size'> {
  /**
   * Optional. Defines the height of the InputTextArea component.
   * It can be used to set a specific height for the text area.
   */
  height?: number;
}

export interface InputSearchProps extends TextInputProps {
  /**
   * Optional. Represents the text to be displayed on the search button within the InputSearch component.
   */
  buttonText?: string;

  /**
   * Optional. If `true`, the text on the search button will be displayed.
   * Defaults to `false` if not provided.
   */
  showButtonText?: boolean;

  /**
   * Optional. Represents the value for the floating title in the InputSearch component.
   */
  onPressButtonText?: () => void;

  /**
   * @deprecated Use `trailing` instead.
   * Optional. Represents the name or key of the icon to be displayed in the Input component.
   */
  icon?: string;

  /**
   * @deprecated Use `trailingColor` instead.
   * Optional. Represents the color of the icon in the Input component.
   */
  iconColor?: string;

  /**
   * @deprecated Use `onPressTrailing` instead.
   * Optional. callback function to be called when the icon is pressed.
   */
  onPressIcon?: () => void;

  /**
   * Optional. Represents the name or key of the icon to be displayed in the Input component.
   */
  trailing?: string;

  /**
   * Optional. Represents the color of the icon in the Input component.
   */
  trailingColor?: string;

  /**
   * Optional. callback function to be called when the icon is pressed.
   */
  onPressTrailing?: () => void;

  /**
   * Optional. If `true`, the user won't be able to interact with the Input component.
   */
  backgroundColor?: string;

  /**
   * Optional. Params auto tracking component.
   */
  params?: any;

  /**
   * Optional. Represents the data for typing animation.
   */
  typingData?: string[];

  /**
   * Optional. Represents the callback function to be called when the search button is pressed.
   * @param e
   */
  onPress?: (e: GestureResponderEvent) => void;
}

export interface InputMoneyProps extends InputProps {
  currency?: string;
}

export interface InputOTPProps
  extends Omit<InputProps, 'size' | 'icon' | 'iconColor'> {
  /**
   * Optional. Defines the length of the OTP (One Time Password) input.
   * Can be 2, 4, 6, 8, or 10.
   */
  length?: OTPInputLength;

  /**
   * Optional. Defines the data type of the OTP input.
   * 'string' - The OTP input will be treated as a string.
   * 'number' - The OTP input will be treated as a number.
   */
  dataType?: 'string' | 'number';

  /**
   * Optional. Represents the value for the floating title in the InputOTP component.
   */
  floatingValue: string;
}

export type CaretProps = {
  /**
   * Optional. The index of the caret in the input field.
   * Represents the position where the caret is located.
   */
  index?: number;

  /**
   * Optional. The total length of the input field in which the caret is present.
   * This dictates the maximum value of the 'index' property.
   */
  length?: number;
};

export interface InputDropDownProps extends TouchableOpacityProps {
  /**
   * Optional. Defines the size of the InputDropDown component.
   * 'small' - A smaller, less prominent input.
   * 'large' - A larger, more prominent input.
   */
  size?: 'small' | 'large';

  /**
   * Optional. Represents the text to be displayed in the InputDropDown component.
   */
  value?: string;

  /**
   * Optional. Represents the placeholder text to be displayed in the InputDropDown component.
   */
  placeholder?: string;

  /**
   * Optional. Represents the data for the dropdown.
   */
  multiline?: boolean;

  /**
   * Optional. Represents the value for the floating title in the Input component.
   */
  floatingValue?: string;

  /**
   * Optional. Represents the name or key of the floating icon to be displayed in the Input component.
   */
  floatingIcon?: string;

  /**
   * Optional. Represents the error message to be displayed below the Input component when there is an error.
   */
  errorMessage?: string;

  /**
   * @deprecated Use `trailing` instead.
   * Optional. Represents the name or key of the icon to be displayed in the Input component.
   */
  icon?: string;

  /**
   * @deprecated Use `onPressTrailing` instead.
   * Optional. callback function to be called when the icon is pressed.
   */
  onPressIcon?: () => void;

  /**
   * Optional. Represents the color of the floating icon in the Input component.
   */
  floatingIconColor?: string;

  /**
   * Optional. If `true`, the Input component is marked as required,
   * indicating that the user must provide a value before submitting a form.
   * Defaults to `false` if not provided.
   */
  required?: boolean;

  /**
   * Optional. If `true`,
   * include spacing when Input not have error message.
   * Defaults to `false` if not provided.
   */
  errorSpacing?: boolean;

  /**
   *  If true, the icon of input will use be show indicator loading.
   */
  loading?: boolean;

  /**
   *  Optional. Represents the leading icon in the Input component.
   */
  leadingIcon?: string;

  /**
   * Optional. callback function to be called when the leading icon is pressed.
   */
  onPressLeadingIcon?: () => void;

  /**
   * Optional. Represents the color of the leading icon in the Input component.
   */
  leadingIconColor?: string;

  /**
   * Optional. Params auto tracking component.
   */
  params?: any;

  /**
   * Optional. Represents text below the Input component.
   */
  hintText?: string;

  /**
   * Optional. Represents the style of the Input component.
   */
  onPressFloatingIcon?: () => void;
}

export interface InputPhoneNumberProps extends InputProps {
  /**
   * Optional. Represents the country code to be displayed in the InputPhoneNumber component.
   * It should be in the format of a string, e.g., "+1" for the United States.
   */
  countryCode?: string;
}

export type InputRef = {
  clear: () => void;
  focus: () => void | undefined;
  blur: () => void | undefined;
  setText: (text: string) => void;
};

export {
  Input,
  InputDropDown,
  InputMoney,
  InputOTP,
  InputSearch,
  InputTextArea,
  InputPhoneNumber,
};

export {checkValidPhoneNumber};
