import { CustomComponentIds } from "../../types/common.js";
import { FormHelperTextProps, FormLabelProps, MuiChipProps } from "../../types/mui.js";
import { JSX, ReactNode, Ref } from "react";
import { Control, FieldValues, Path, RegisterOptions } from "react-hook-form";
import { TextFieldProps } from "@mui/material/TextField";

//#region src/mui/tags-input/index.d.ts
type TextFieldInputProps = Omit<TextFieldProps, 'name' | 'value' | 'defaultValue' | 'onChange' | 'error' | 'multiline' | 'rows' | 'minRows' | 'maxRows' | 'FormHelperTextProps'>;
type OnValueChangeProps = {
  newValue: string[];
};
type RHFTagsInputOnTagAddProps = {
  currentValue: string[];
  newTag: string;
};
type RHFTagsInputOnTagDeleteProps = {
  currentValue: string[];
  deletedTag: string;
};
type RHFTagsInputOnTagPasteProps = {
  currentValue: string[];
  pastedTags: string[];
};
type RHFTagsInputProps<T extends FieldValues> = {
  /**
   * Name/path of the React Hook Form field this component controls.
   */
  fieldName: Path<T>;
  /**
   * React Hook Form control object returned by `useForm`.
   */
  control: Control<T>;
  /**
   * Validation rules passed to React Hook Form for this field.
   */
  registerOptions?: RegisterOptions<T, Path<T>>;
  /**
   * Called before a tag is added.
   *
   * Use this callback to validate, transform, or prevent individual tags.
   *
   * Returning:
   * - `false` prevents the tag from being added.
   * - `string` replaces the original tag with the returned value.
   * - `true` or `void` allows the original tag to be added unchanged.
   *
   * @param props - Details for the tag add action.
   * @param props.currentValue - The current field value before the new tag is added.
   * @param props.newTag - The tag the user is attempting to add.
   * @returns `false` to block the tag, a replacement tag string, or nothing to allow the tag.
   */
  onTagAdd?: ({
    currentValue,
    newTag
  }: RHFTagsInputOnTagAddProps) => boolean | string | void;
  /**
   * Called before a tag is removed.
   *
   * Use this callback to intercept or prevent tag deletion.
   *
   * Returning:
   * - `false` prevents the tag from being removed.
   * - `true` or `void` allows the tag to be removed.
   *
   * @param props - Details for the tag delete action.
   * @param props.currentValue - The current field value before the tag is removed.
   * @param props.deletedTag - The tag being removed.
   * @returns `false` to prevent deletion, or nothing to allow it.
   */
  onTagDelete?: ({
    currentValue,
    deletedTag
  }: RHFTagsInputOnTagDeleteProps) => boolean | void;
  /**
   * Called when one or more tags are pasted into the input.
   *
   * Return:
   * - `false` to prevent all pasted tags from being added.
   * - A `string[]` to replace the parsed tags with a custom set.
   * - `void` to use the parsed tags unchanged.
   *
   * Tags are split using the configured `delimiter`, trimmed,
   * and deduplicated before this callback is invoked.
   *
   * @param props - Details for the tag paste action.
   * @param props.currentValue - The current field value before the paste operation.
   * @param props.pastedTags - The parsed tags extracted from the pasted text.
   */
  onTagPaste?: ({
    currentValue,
    pastedTags
  }: RHFTagsInputOnTagPasteProps) => string[] | boolean | void;
  /**
   * Character used to separate tags when typing or pasting.
   *
   * Pressing this key commits the current input as one or more tags.
   * Pasted values are also split using this delimiter.
   *
   * @default ','
   */
  delimiter?: string;
  /**
   * Maximum number of tags that can be added.
   *
   * When the limit is reached:
   * - Additional tags entered from the keyboard are ignored.
   * - Pasted tags are truncated to fit the remaining available slots.
   *
   * By default, no limit is enforced.
   */
  maxTags?: number;
  /**
   * Called after the default tags input handler stores the next tag array in React Hook Form.
   *
   * @param newValue - Next tag string array.
   */
  onValueChange?: ({
    newValue
  }: OnValueChangeProps) => void;
  /**
   * When true, renders the field label above the form field instead of inside or beside it.
   */
  showLabelAboveFormField?: boolean;
  /**
   * Props forwarded to the internal `FormLabel`. The `id` is managed by the component.
   */
  formLabelProps?: Omit<FormLabelProps, 'id'>;
  /**
   * When true, hides the rendered field label while preserving accessible labeling where possible.
   */
  hideLabel?: boolean;
  /**
   * @deprecated
   * Field error message is now automatically derived from form state.
   * Passing this prop is no longer necessary and it will be removed in the next major version.
   */
  errorMessage?: ReactNode;
  /**
   * If true, hides the error message text while keeping the field in an error state.
   */
  hideErrorMessage?: boolean;
  /**
   * Props forwarded to the internal `FormHelperText`. The `id` is managed by the component.
   */
  formHelperTextProps?: Omit<FormHelperTextProps, 'id'>;
  /**
   * Props applied to the Chip component used to render each tag.
   *
   * Useful for customizing the appearance and behavior of tags,
   * such as color, size, variant, icon, or delete functionality.
   */
  ChipProps?: MuiChipProps;
  /**
   * Maximum number of tags shown when the input is not focused.
   *
   * Set to `-1` to always show all tags.
   *
   * @default 2
   */
  limitTags?: number;
  /**
   * Custom label rendered for the hidden tags counter.
   *
   * Receives the number of hidden tags.
   *
   * @default moreTags => `+${moreTags} more`
   */
  getLimitTagsText?: (moreTags: number) => ReactNode;
  /**
   * Custom renderer for each visible tag label.
   *
   * Receives the tag value and should return the content displayed inside the chip.
   */
  renderTagLabel?: (tag: string) => ReactNode;
  /**
   * Custom ids for generated field, label, helper text, and error elements.
   */
  customIds?: CustomComponentIds;
} & TextFieldInputProps;
declare const RHFTagsInput: <T extends FieldValues>(props: RHFTagsInputProps<T> & {
  ref?: Ref<HTMLInputElement>;
}) => JSX.Element;
//#endregion
export { RHFTagsInputProps, RHFTagsInput as default };