/* eslint-disable no-extra-semi */
/* eslint-disable @typescript-eslint/no-redundant-type-constituents */

import {ElementType, ReactElement, Factory} from "react";
import { NumericFormat, NumericFormatProps } from "react-number-format";
import {
  Conjunctions, Types, Fields, Funcs, CoreConfig, RuleValue, RuleValueI, 
  SimpleValue, OperatorOptionsI, FieldValueI, FieldSource, AsyncListValues,
  InputAction,
  ImmutableTree,
  Actions,
  ActionMeta,
  ItemType,
  ItemProperties,
  ValueSource,
  FactoryWithContext, FnWithContextAndProps, FactoryFnWithoutPropsWithContext, RenderedReactElement, SerializableType,
  ConjsProps,
  AsyncFetchListValuesFn,
  ListOptionUi,
  ListValues,
  ListItem,

  ImmutableList, ImmutableMap, ImmutableOMap,
  ImmutablePath,
  ImmutableItemProperties,

  // to extend
  Config as CoreConfigType,
  ConfigContext as CoreConfigContext,
  ConfigContextUtils as CoreConfigContextUtils,
  Settings as CoreSettings,
  Utils as CoreUtils,
  // to override <C>
  OperatorProximity as _OperatorProximity,
  Operator as _Operator,
  Operators as _Operators,
  FieldProps as _FieldProps,
  Widget as _Widget,
  Widgets as _Widgets,
  BaseWidget as _BaseWidget,
  RangeableWidget as _RangeableWidget,
  TypedWidget as _TypedWidget,
  TextWidget as _TextWidget,
  NumberWidget as _NumberWidget,
  RangeSliderWidget as _RangeSliderWidget,
  DateTimeWidget as _DateTimeWidget,
  TreeSelectWidget as _TreeSelectWidget,
  TreeMultiSelectWidget as _TreeMultiSelectWidget,
  SelectWidget as _SelectWidget,
  MultiSelectWidget as _MultiSelectWidget,
  BooleanWidget as _BooleanWidget,
  FieldWidget as _FieldWidget,
  FuncWidget as _FuncWidget,
  CaseValueWidget as _CaseValueWidget,
  ProximityProps as _ProximityProps,
  ProximityOptions as _ProximityOptions,
  WidgetProps as _WidgetProps,
  TextWidgetProps as _TextWidgetProps,
  DateTimeWidgetProps as _DateTimeWidgetProps,
  BooleanWidgetProps as _BooleanWidgetProps,
  NumberWidgetProps as _NumberWidgetProps,
  PriceWidgetProps as _PriceWidgetProps,
  RangeSliderWidgetProps as _RangeSliderWidgetProps,
  SelectWidgetProps as _SelectWidgetProps,
  MultiSelectWidgetProps as _MultiSelectWidgetProps,
  TreeSelectWidgetProps as _TreeSelectWidgetProps,
  TreeMultiSelectWidgetProps as _TreeMultiSelectWidgetProps,
  CaseValueWidgetProps as _CaseValueWidgetProps,
  CoreOperators as _CoreOperators,
  CoreWidgets as _CoreWidgets,
  ConfigMixin as _ConfigMixin,
  ConfigMixinExt as _ConfigMixinExt,
  ImmutableItem,
} from "@react-awesome-query-builder/core";

// re-export
// Ignore "Multiple exports of name 'Utils'"
// eslint-disable-next-line import/export
export * from "@react-awesome-query-builder/core";

import chroma from "chroma-js";

/////////////////
// override <C> in types
/////////////////

export type OperatorProximity<C = Config, CTX = ConfigContext> = _OperatorProximity<C, CTX>;
export type Operator<C = Config, CTX = ConfigContext> = _Operator<C, CTX>;
export type Operators<C = Config, CTX = ConfigContext> = _Operators<C, CTX>;
export type FieldProps<C = Config> = _FieldProps<C>;
export type Widget<C = Config, CTX = ConfigContext> = _Widget<C, CTX>;
export type Widgets<C = Config, CTX = ConfigContext> = _Widgets<C, CTX>;
export type BaseWidget<C = Config, CTX = ConfigContext> = _BaseWidget<C, CTX>;
export type RangeableWidget<C = Config, CTX = ConfigContext> = _RangeableWidget<C, CTX>;
export type TypedWidget<C = Config, CTX = ConfigContext> = _TypedWidget<C, CTX>;
export type TextWidget<C = Config, CTX = ConfigContext> = _TextWidget<C, CTX>;
export type NumberWidget<C = Config, CTX = ConfigContext> = _NumberWidget<C, CTX>;
export type RangeSliderWidget<C = Config, CTX = ConfigContext> = _RangeSliderWidget<C, CTX>;
export type DateTimeWidget<C = Config, CTX = ConfigContext> = _DateTimeWidget<C, CTX>;
export type TreeSelectWidget<C = Config, CTX = ConfigContext> = _TreeSelectWidget<C, CTX>;
export type TreeMultiSelectWidget<C = Config, CTX = ConfigContext> = _TreeMultiSelectWidget<C, CTX>;
export type SelectWidget<C = Config, CTX = ConfigContext> = _SelectWidget<C, CTX>;
export type MultiSelectWidget<C = Config, CTX = ConfigContext> = _MultiSelectWidget<C, CTX>;
export type BooleanWidget<C = Config, CTX = ConfigContext> = _BooleanWidget<C, CTX>;
export type FieldWidget<C = Config, CTX = ConfigContext> = _FieldWidget<C, CTX>;
export type FuncWidget<C = Config, CTX = ConfigContext> = _FuncWidget<C, CTX>;
/**
 * @deprecated
 */
export type CaseValueWidget<C = Config, CTX = ConfigContext> = _CaseValueWidget<C, CTX>;
export type ProximityProps<C = Config> = _ProximityProps<C>;
export type ProximityOptions<C = Config> = _ProximityOptions<C>;
export type WidgetProps<C = Config> = _WidgetProps<C>;
export type TextWidgetProps<C = Config> = _TextWidgetProps<C>;
export type DateTimeWidgetProps<C = Config> = _DateTimeWidgetProps<C>;
export type BooleanWidgetProps<C = Config> = _BooleanWidgetProps<C>;
export type NumberWidgetProps<C = Config> = _NumberWidgetProps<C>;
export type PriceWidgetProps<C = Config> = _PriceWidgetProps<C>;
export type RangeSliderWidgetProps<C = Config> = _RangeSliderWidgetProps<C>;
export type SelectWidgetProps<C = Config> = _SelectWidgetProps<C>;
export type MultiSelectWidgetProps<C = Config> = _MultiSelectWidgetProps<C>;
export type TreeSelectWidgetProps<C = Config> = _TreeSelectWidgetProps<C>;
export type TreeMultiSelectWidgetProps<C = Config> = _TreeMultiSelectWidgetProps<C>;
/**
 * @deprecated
 */
export type CaseValueWidgetProps<C = Config> = _CaseValueWidgetProps<C>;
export type CoreOperators<C = Config, CTX = ConfigContext> = _CoreOperators<C, CTX>;
export type CoreWidgets<C = Config, CTX = ConfigContext> = _CoreWidgets<C, CTX>;
export type ConfigMixin<C = Config, CTX = ConfigContext, S = Settings> = _ConfigMixin<C, CTX, S>;
export type ConfigMixinExt<C = Config> = _ConfigMixinExt<C>;

/////////////////
// extend config
/////////////////

export interface ConfigContextUtils extends CoreConfigContextUtils {
  ColorUtils?: ColorUtils;
}

export interface ConfigContext extends CoreConfigContext {
  utils: ConfigContextUtils;
  generateCssVars?: (theme: any, config: Config) => CssVars;
}

export interface Config extends CoreConfigType {
  settings: Settings;
  operators: Operators;
  widgets: Widgets;
  ctx: ConfigContext;
}

export interface BasicConfig extends CoreConfig {
  settings: Settings;
  operators: CoreOperators<Config, ConfigContext>;
  widgets: CoreWidgets<Config, ConfigContext>;
  ctx: ConfigContext;
}


////////////////
// common
/////////////////


type AnyObject = Record<string, unknown>;
type TypedMap<T> = {
  [key: string]: T;
}
type Empty = null | undefined;


////////////////
// Query, Builder
/////////////////

export type Dispatch = (action: InputAction) => void;

type DragStartFn = (nodeId: string, dom: HTMLDivElement, e: MouseEvent) => void;

export interface BuilderProps {
  tree: ImmutableTree;
  config: Config;
  actions: Actions;
  dispatch: Dispatch;
}

export interface ItemProps {
  config: Config;
  actions: Actions;
  properties: ImmutableItemProperties;
  type: ItemType;
  id: string;
  groupId?: string;
  parentField?: string;
  path: ImmutablePath;
  children1?: ImmutableOMap<string, ImmutableItem>;
  // additional:
  totalRulesCnt?: number;
  reordableNodesCnt?: number;
  parentReordableNodesCnt?: number;
  onDragStart?: DragStartFn;
  isParentLocked?: boolean;
  isDraggingTempo?: boolean;
}
export interface ItemBuilderProps extends ItemProps {
  itemComponent: Factory<ItemProps>;
}

export type OnChange = (immutableTree: ImmutableTree, config: Config, actionMeta?: ActionMeta, actions?: Actions) => void;
export type OnInit = (immutableTree: ImmutableTree, config: Config, actionMeta?: ActionMeta, actions?: Actions) => void;

export interface QueryProps {
  conjunctions: Conjunctions;
  operators: Operators;
  widgets: Widgets;
  types: Types;
  settings: Settings;
  fields: Fields;
  funcs?: Funcs;
  ctx: ConfigContext;
  value: ImmutableTree;
  onChange: OnChange;
  onInit?: OnInit;
  renderBuilder(props: BuilderProps): ReactElement;
}

export type Builder = ElementType<BuilderProps>;
export type Query = ElementType<QueryProps>;


/////////////////
// Props for render* in RenderSettings
/////////////////

type ButtonIconType = "addRule" | "addGroup" | "delRule" | "delGroup" | "addSubRuleSimple" | "addSubRule" | "addSubGroup" | "delRuleGroup";
type IconType = ButtonIconType | "drag";

export interface ButtonProps {
  type: ButtonIconType;
  renderIcon?: FactoryWithContext<IconProps>;
  onClick(): void;
  label: string;
  config: Config;
  readonly?: boolean;
}

export interface IconProps {
  type: IconType;
  config?: Config;
  readonly?: boolean;
}

export interface SwitchProps {
  value: boolean;
  setValue(newValue?: boolean): void;
  label: string;
  checkedLabel?: string;
  hideLabel?: boolean;
  config: Config;
}

export interface ButtonGroupProps {
  children: ReactElement;
  config: Config;
}

export interface ProviderProps {
  children: ReactElement;
  config: Config;
}

export type ValueSourceItem = {
  label: string;
}
type ValueSourcesItems = Array<[ValueSource, ValueSourceItem]>;

export interface ValueSourcesProps {
  config: Config;
  valueSources: ValueSourcesItems;
  valueSrc?: ValueSource;
  setValueSrc(valueSrc: string): void;
  readonly?: boolean;
  title: string;
}

export interface ConfirmModalProps {
  onOk(): void;
  okText: string;
  cancelText?: string;
  title: string | null;
  okType?: string;
  confirmFn?: ConfirmFunc;
}

export interface RuleErrorProps {
  error: string;
}

export interface RuleProps {
  config: Config;
  id: string; // id of rule
  groupId: string | Empty; // id of parent group
  parentField: string | Empty; //from RuleGroup
  selectedField: FieldValueI | Empty;
  selectedFieldSrc: FieldSource | Empty;
  selectedFieldType: string | Empty;
  fieldError: string | Empty;
  selectedOperator: string | Empty;
  operatorOptions: OperatorOptionsI | Empty;
  value: ImmutableList<RuleValueI>; //depends on widget
  valueError: ImmutableList<string | Empty>;
  valueSrc: ImmutableList<ValueSource>;
  valueType: ImmutableList<string>;
  asyncListValues: AsyncListValues | Empty;

  isDraggingMe: boolean | Empty;
  isDraggingTempo: boolean | Empty;
  isLocked: boolean | Empty;
  isTrueLocked: boolean | Empty;
  reordableNodesCnt: number | Empty;
  totalRulesCnt: number | Empty;
  parentReordableNodesCnt: number | Empty;
  onDragStart: DragStartFn | Empty;
  handleDraggerMouseDown: (e: MouseEvent) => void | Empty;
  removeSelf: () => void | Empty;
  confirmFn: ConfirmFunc | Empty; // prop from <WithConfirmFn>

  //actions
  setField(field: FieldValueI): undefined;
  setFieldSrc(fieldSrc: FieldSource): undefined;
  setFuncValue(delta: number, parentFuncs: Array<[string, string]>, argKey: string | null, value: SimpleValue, type: string | "!valueSrc"): undefined;
  setOperator(operator: string): undefined;
  setOperatorOption(name: string, value: SimpleValue): undefined;
  setLock(lock: boolean): undefined;
  setValue(delta: number, value: RuleValueI, valueType: string, asyncListValues?: AsyncListValues): undefined;
  setValueSrc(delta: number, valueSrc: ValueSource): undefined;
}

/////////////////
// CssVars
/////////////////

export interface CssVarsBorderColors {
  "--rule-border-color"?: string;
  "--group-border-color"?: string;
  "--rulegroup-border-color"?: string;
  "--rulegroupext-border-color"?: string;
  "--switch-border-color"?: string;
  "--case-border-color"?: string;
  "--rule-with-error-border-color"?: string;
  "--group-with-error-border-color"?: string;
  /*
   * Border color of placeholder for item that it's being dragged
   */
  "--placeholder-border-color"?: string;
  /*
   * Border color for locked item
   */
  "--locked-border-color"?: string;
  /*
   * [Advanced] Border color for group inside rule-group
   */
  "--group-in-rulegroupext-border-color"?: string;
}
export interface CssVarsBgColors {
  // background for .query-builder
  "--main-background"?: string;
  "--rule-background"?: string;
  "--group-background"?: string;
  "--rulegroup-background"?: string;
  "--rulegroupext-background"?: string;
  "--switch-background"?: string;
  "--case-background"?: string;
}
export interface CssVarsTreelineColors {
  "--treeline-color"?: string;
  "--treeline-rulegroup-color"?: string;
  "--treeline-rulegroupext-color"?: string;
  "--treeline-switch-color"?: string;
  "--treeline-disabled-color"?: string;
}
export interface CssVarsOtherColors {
  "--rule-error-color"?: string;
  "--custom-select-option-color"?: string;
}
export interface CssVarsBorderWidths {
  // example: "1px"
  "--rule-border-width"?: string;
  "--group-border-width"?: string;
  "--rulegroup-border-width"?: string;
  "--rulegroupext-border-width"?: string;
  "--switch-border-width"?: string;
  "--case-border-width"?: string;
}
export interface CssVarsBorderWidthsOnHover {
  "--rule-border-left-width-hover"?: string;
  "--group-border-left-width-hover"?: string;
  "--rulegroup-border-left-width-hover"?: string;
  "--rulegroupext-border-left-width-hover"?: string;
}
export interface CssVarsShadowOnHover {
  "--rule-shadow-hover"?: string;
  "--group-shadow-hover"?: string;
  "--rulegroup-shadow-hover"?: string;
  "--rulegroupext-shadow-hover"?: string;
}
export interface CssVarsRadiuses {
  // example: "5px"
  "--item-radius"?: string;
  "--conjunctions-radius"?: string;
  "--treeline-radius"?: string;
}
export interface CssVarsTreeline {
  // example: "2px"
  "--treeline-thick"?: string;
  "--treeline-switch-thick"?: string;
  "--treeline-rulegroup-thick"?: string;
  "--treeline-rulegroupext-thick"?: string;
}
export interface CssVarsOffsets {
  // example: "20px"
  "--treeline-offset-from-conjs"?: string;
  "--treeline-offset-from-switch"?: string;
  "--item-offset"?: string;
  "--item-offset-left"?: string;
  "--rulegroup-offset"?: string;
  "--rulegroup-offset-left"?: string;
  "--rule-padding"?: string;
  "--rule-parts-distance"?: string;
  "--seps-offset-bottom"?: string;
  "--drag-offset-right"?: string;
  "--group-actions-offset-left"?: string;
  "--group-drag-offset-left"?: string;
  "--rule-group-actions-offset-left"?: string;
  "--main-margin"?: string; // margin for .query-builder
}
export interface CssVarsFonts {
  // Default: "'Helvetica Neue', Helvetica, Arial, sans-serif"
  "--main-font-family"?: string;
  // Default: "14px"
  "--main-font-size"?: string;
  // Default: "initial"
  "--main-text-color"?: string;
}

// For advanced usage, not including in CssVars for now
export interface CssVarsColorsForNesting {
  "--rule-in-rulegroup-border-color"?: string;
  "--rulegroup-in-rulegroup-border-color"?: string;
  "--rulegroupext-in-rulegroup-border-color"?: string;
  "--rule-in-rulegroupext-border-color"?: string;
  "--group-in-rulegroupext-border-color"?: string; // defined in CssVarsBorderColors
  "--rulegroupext-in-rulegroupext-border-color"?: string;
  "--rulegroup-in-rulegroupext-border-color"?: string;
}

export interface CssVarsColors extends CssVarsBgColors, CssVarsBorderColors, CssVarsTreelineColors, CssVarsOtherColors {}
export interface CssVarsSizes extends CssVarsBorderWidths, CssVarsRadiuses, CssVarsTreeline, CssVarsOffsets {}
export interface CssVarsExtra extends CssVarsBorderWidthsOnHover, CssVarsShadowOnHover {}

// eslint-disable-next-line @typescript-eslint/no-empty-object-type
export interface CssVars extends CssVarsColors, CssVarsSizes, CssVarsFonts, CssVarsExtra {}

export interface DesignSettings {
  canInheritThemeFromOuterProvider?: boolean;
  useThickLeftBorderOnHoverItem?: boolean;
  useShadowOnHoverItem?: boolean;
  generateCssVarsFromThemeLibrary?: boolean;
  generateCssVars?: {
    material?: (this: ConfigContext, theme: /*Theme*/ any, config: Config) => CssVars;
    mui?: (this: ConfigContext, theme: /*Theme*/ any, config: Config) => CssVars;
    antd?: (this: ConfigContext, token: /*GlobalToken*/ any, config: Config) => CssVars;
    fluent?: (this: ConfigContext, theme: /*Theme*/ any, config: Config) => CssVars;
    bootstrap?: (this: ConfigContext, _ununsed: any, config: Config) => CssVars;
  }
}

/////////////////
// Settings
/////////////////

export type AntdPosition = "topLeft" | "topCenter" | "topRight" | "bottomLeft" | "bottomCenter" | "bottomRight";
export type RenderSize = "small" | "large" | "medium";
export type ThemeMode = "light" | "dark";

export interface ThemeSettings {
  theme?: {
    material?: Record<string, any>; // ThemeOptions from "@material-ui/core/styles"
    mui?: Record<string, any>; // ThemeOptions from "@mui/material/styles";
    antd?: Record<string, any>; // ConfigProviderProps["theme"] from "antd"
    fluent?: Record<string, any>; // PartialTheme from "@fluentui/react";
  };
  designSettings?: DesignSettings;
  renderSize?: RenderSize;
  themeMode?: ThemeMode;
  liteMode?: boolean;
  compactMode?: boolean;
  dropdownPlacement?: AntdPosition;
  groupActionsPosition?: AntdPosition;
  defaultSliderWidth?: string;
  defaultSelectWidth?: string;
  defaultSearchWidth?: string;
  defaultMaxRows?: number;
  showLabels?: boolean;
  maxLabelsLength?: number;
}

export interface RenderSettings {
  renderField?: SerializableType<FactoryWithContext<FieldProps>>;
  renderOperator?: SerializableType<FactoryWithContext<FieldProps>>;
  renderFunc?: SerializableType<FactoryWithContext<FieldProps>>;
  renderConjs?: SerializableType<FactoryWithContext<ConjsProps>>;
  renderButton?: SerializableType<FactoryWithContext<ButtonProps>>;
  renderIcon?: SerializableType<FactoryWithContext<IconProps>>;
  renderButtonGroup?: SerializableType<FactoryWithContext<ButtonGroupProps>>;
  renderSwitch?: SerializableType<FactoryWithContext<SwitchProps>>;
  renderProvider?: SerializableType<FactoryWithContext<ProviderProps>>;
  renderValueSources?: SerializableType<FactoryWithContext<ValueSourcesProps>>;
  renderConfirm?: SerializableType<FnWithContextAndProps<ConfirmModalProps, ConfigContext, void>>;
  useConfirm?: SerializableType<FactoryFnWithoutPropsWithContext<ConfirmFunc, ConfigContext>>;
  renderItem?: SerializableType<FactoryWithContext<ItemBuilderProps>>;
  renderBeforeWidget?: SerializableType<FactoryWithContext<RuleProps>>;
  renderAfterWidget?: SerializableType<FactoryWithContext<RuleProps>>;
  renderBeforeActions?: SerializableType<FactoryWithContext<RuleProps>>;
  renderAfterActions?: SerializableType<FactoryWithContext<RuleProps>>;
  renderBeforeCaseValue?: SerializableType<FactoryWithContext<RuleProps>>;
  renderAfterCaseValue?: SerializableType<FactoryWithContext<RuleProps>>;
  renderRuleError?: SerializableType<FactoryWithContext<RuleErrorProps>>;
  renderSwitchPrefix?: SerializableType<RenderedReactElement>;

  customFieldSelectProps?: AnyObject;
  customOperatorSelectProps?: AnyObject;
}

export interface Settings extends CoreSettings, RenderSettings, ThemeSettings {
}

/////////////////
// ReadyWidgets
/////////////////

export type ConfirmFunc = (props: ConfirmModalProps) => void;

interface VanillaWidgets {
  // core
  VanillaFieldSelect: ElementType<FieldProps>;
  VanillaConjs: ElementType<ConjsProps>;
  VanillaSwitch: ElementType<SwitchProps>;
  VanillaButton: ElementType<ButtonProps>;
  VanillaButtonGroup: ElementType<ButtonGroupProps>;
  VanillaProvider: ElementType<ProviderProps>;
  VanillaValueSources: ElementType<ValueSourcesProps>;
  vanillaConfirm: ConfirmFunc;

  // value
  VanillaBooleanWidget: ElementType<BooleanWidgetProps>;
  VanillaTextWidget: ElementType<TextWidgetProps>;
  VanillaTextAreaWidget: ElementType<TextWidgetProps>;
  VanillaDateWidget: ElementType<DateTimeWidgetProps>;
  VanillaTimeWidget: ElementType<DateTimeWidgetProps>;
  VanillaDateTimeWidget: ElementType<DateTimeWidgetProps>;
  VanillaMultiSelectWidget: ElementType<SelectWidgetProps>;
  VanillaSelectWidget: ElementType<SelectWidgetProps>;
  VanillaNumberWidget: ElementType<NumberWidgetProps>;
  VanillaPriceWidget: ElementType<PriceWidgetProps>;
  VanillaSliderWidget: ElementType<NumberWidgetProps>;
  
  // common
  ValueFieldWidget: ElementType<WidgetProps>;
  FuncWidget: ElementType<WidgetProps>;
}

/////////////////
// extend Utils
/////////////////

export interface ColorUtils {
  chroma: typeof chroma;
  setColorOpacity(color: string, alpha: number): string;
  generateCssVarsForLevels(isDark: boolean, cssVar: string, baseColor: string, baseDarkColor?: string): Record<string, string>;
  isDarkColor(color?: string): boolean | undefined;
  isColor(color: any): boolean;
}
export interface NumberFormat {
  getNumberFormatProps: (props: Record<string, any>, excludePropsNames?: string[]) => Record<string, any>;
  NumericFormat: typeof NumericFormat;
  numericFormatter: (val: number, numericFormatProps: NumericFormatProps) => string;
  numericParser: (str: string, numericFormatProps: NumericFormatProps, lastStrValue?: string, lastNumValue?: number) => number | undefined;
}
export interface Utils extends CoreUtils {
  NumberFormat: NumberFormat;
  ColorUtils: ColorUtils;
  // ReactUtils: {
  //   useOnPropsChanged(obj: ReactElement): void;
  // }
}

// Ignore "Multiple exports of name 'Utils'"
// eslint-disable-next-line import/export
export declare const Utils: Utils;

//////////////////


type AutocompleteChangeReason = "selectOption" | "removeOption" | "clear" | null;
type AutocompleteInputChangeReason = "selectOption" | "removeOption" | "clear" | "blur" | "input" | "reset" | "my-reset" | null;
export interface UseListValuesAutocompleteProps {
  asyncFetch: AsyncFetchListValuesFn;
  useLoadMore?: boolean;
  useAsyncSearch?: boolean;
  forceAsyncSearch?: boolean;
  fetchSelectedValuesOnInit?: boolean;
  asyncListValues?: ListValues; // selectedAsyncListValues
  listValues: ListValues; // staticListValues
  allowCustomValues?: boolean;
  value?: string | number | string[] | number[]; // selectedValue (array for multiple=true)
  setValue: (value: string | number | string[] | number[]) => void;
  placeholder?: string;
  config: Config;
}
export interface UseListValuesAutocompleteOptions {
  multiple: boolean;
  debounceTimeout?: number;
  uif?: "antd" | "material" | "mui";
  isFieldAutocomplete?: boolean;
  dontFixOptionsOrder?: boolean;
}
export interface UseListValuesAutocompleteReturn {
  open: boolean;
  onOpen: () => void;
  onClose: () => void;
  onChange: (
    // tip: null for mui
    e: React.SyntheticEvent<HTMLInputElement> | null, 
    // tip: string or string[] for mui
    val: Empty | string | number | ListOptionUi | Array<string | number | ListOptionUi>,
    // tip: ListOptionUi or ListOptionUi[] for mui, AutocompleteChangeReason for antd
    option: AutocompleteChangeReason | ListOptionUi | ListOptionUi[],
  ) => Promise<void>;
  onInputChange: (
    e: React.SyntheticEvent<HTMLInputElement> | null,
    newInputValue: string,
    eventType: AutocompleteInputChangeReason,
  ) => Promise<void>;
  inputValue: string;
  options: ListOptionUi[];
  isInitialLoading: boolean;
  isLoading: boolean;
  aPlaceholder: string;
  extendOptions: (options: ListOptionUi[]) => ListOptionUi[];
  getOptionSelected: (option: ListOptionUi, selectedValueOrOption: ListItem | null) => boolean;
  getOptionDisabled: (valueOrOption: ListItem) => boolean;
  getOptionIsCustom: (option: ListItem) => boolean;
  getOptionLabel: (option: ListItem | null) => string | null;
  selectedListValue: ListItem | null;
}

export interface Hooks {
  useListValuesAutocomplete: (props: UseListValuesAutocompleteProps, options: UseListValuesAutocompleteOptions) => UseListValuesAutocompleteReturn;
}

export declare const Query: Query;
export declare const Builder: Builder;
export declare const BasicConfig: BasicConfig;
export declare const VanillaWidgets: VanillaWidgets;
export declare const Hooks: Hooks;

