import { DefineComponent, Slot } from 'vue';
import { Nullable } from '../ts-helpers';

/**
 * InputText component props
 */
export interface InputTextProps {
  /**
   * String modelValue of the input.
   */
  modelValue?: Nullable<string>;
  /**
   * Sets the initial value of the field.
   * This will only available with option 'useValidator'.
   *
   * In usecase like edit form, you need to display the previous inputted value.
   */
  value?: string;
  /**
   * The maximun character length allowed.
   *
   * @default 30 - for inputText;
   * @default unlimited - for textarea;
   */
  maxLength?: number;
  /**
   * The input label. Tell the user what input is this.
   */
  label?: string;
  /**
   * Wether the input should be validated with vee-validator or not.
   * If you use this component within form input, you need to set this props as true.
   */
  useValidator?: boolean;
  /**
   * This prop is required if you use this component in a form input.
   * Specify the unique field name, match with your needs for API request.
   *
   * @default 'textInput'
   */
  fieldName?: string;
  /**
   * Wether this input field is required or not.
   */
  mandatory?: boolean;
  /**
   * Invalid input state.
   */
  invalid?: boolean;
  /**
   * Set manual invalid input container state.
   */
  manualInvalidContainer?: boolean;
  /**
   * Set custom validator message.
   * Will be show if invalid="true"
   */
  validatorMessage?:
    | string
    | {
        exist?: string;
      };
  /**
   * Function to check the availability of the input value.
   * Useful for checking if a username or email already exists.
   */
  checkAvailability?: (value: string) => Promise<boolean>;
  /**
   * Validate the input on blur event.
   *
   * @default false - on input event
   */
  validateOnBlur?: boolean;
  /**
   * Classes for validator message in input field.
   */
  validatorMessageClass?: string;
  /**
   * Wether to format the message
   *
   * @default true
   */
  formatValidatorMessage?: boolean;
  /**
   * Specify the input placeholder.
   *
   * @default 'Enter {label}' or 'Enter {type}'
   */
  placeholder?: string;
  /**
   * Specify the validation type. Wether 'email' or 'text' validation.
   */
  type?: 'email' | 'text' | 'url';
  /**
   * Disabled the input.
   */
  disabled?: boolean;
  /**
   * Show information to user about the field.
   */
  fieldInfo?: string;
  /**
   * Specify classes for input.
   */
  inputClass?: string;
  /**
   * Specify classes for input container.
   */
  inputContainerClass?: string;
  /**
   * Specify classes for label.
   */
  labelClass?: string;
  /**
   * Auto blur while input value has reached the max length.
   */
  blurOnReachMax?: boolean;
  /**
   * Allow user to input special characters
   *
   * @default true
   */
  allowSpecialCharacters?: boolean;
  /**
   * Wether the input should be trimmed or not.
   *
   * @default false
   */
  trimInput?: boolean;
}

/**
 * InputText component emits
 */
export type InputTextEmits = {
  'blur': [payload?: Nullable<string>];
  'input': [payload?: Nullable<string>];
  'update:modelValue': [payload?: Nullable<string>];
};

export interface InputTextSlots {
  'addon-left': Slot;
  'addon-right': Slot;
}

/**
 * **TSVue - InputText**
 *
 * _Handle input text with form validation._
 *
 * --- ---
 * ![TSVue](https://ik.imagekit.io/kurniadev/TS-HEAD-BLACK.png)
 *
 * @group form
 */
declare const InputText: DefineComponent<
  InputTextProps,
  InputTextEmits,
  InputTextSlots
>;

export default InputText;
