import * as React from 'react';
import { FocusOptionsPolyfill, PopoverCommonProps } from '../common';
import {
  DropdownLayoutValueOption,
  DropdownLayoutProps,
} from '../DropdownLayout';
import { InputProps } from '../Input';

export interface InputWithOptionsProps<
  ManualInputFn = ManualInputFnSignature,
  OnSelectFn = OnSelectFnSignature,
>
  extends InputProps, Omit<DropdownLayoutProps, 'onSelect' | 'size'> {
  /** @default 'off' */
  autocomplete?: string;
  /** Use a customized input component instead of the default @wix/design-system `<Input/>` component */
  inputElement?: React.ReactElement;
  /** Closes DropdownLayout on option selection
   * @default true
   */
  closeOnSelect?: boolean;
  /** A callback which is called when the user performs a Submit-Action.
   * Submit-Action triggers are: "Enter", "Tab", [typing any defined delimiters], Paste action.
   * `onManuallyInput(values: Array<string>): void - The array of strings is the result of splitting the input value by the given delimiters */
  onManuallyInput?: ManualInputFn;
  /** Function that receives an option, and should return the value to be displayed. */
  valueParser?: (
    option: DropdownLayoutValueOption,
  ) => DropdownLayoutValueOption['value'];
  /** Sets the width of the dropdown
   * @default null
   */
  dropdownWidth?: string;
  /** Sets the offset of the dropdown from the left
   * @default '0'
   */
  dropdownOffsetLeft?: string;
  customDropdownContent?: React.ReactNode;
  /** Controls whether to show options if input is empty
   * @default true
   */
  showOptionsIfEmptyInput?: boolean;
  /** Mark in bold word parts based on search pattern */
  highlight?: boolean;
  /** Indicates whether to render using the native select element
   * @default false
   */
  native?: boolean;
  /** common popover props */
  popoverProps?: PopoverCommonProps;
  onSelect?: OnSelectFn;
  /** A callback which is called when options dropdown is shown */
  onOptionsShow?: () => void;
  /** A callback which is called when options dropdown is hidden */
  onOptionsHide?: () => void;
  /** Controls whether to show drawer on mobile devices
   * @default true
   */
  showDrawerOnMobile?: boolean;
}

export default class InputWithOptions<
  ManualInputFn = ManualInputFnSignature,
  OnSelectFn = OnSelectFnSignature,
  T extends InputWithOptionsProps<ManualInputFn, OnSelectFn> =
    InputWithOptionsProps<ManualInputFn, OnSelectFn>,
> extends React.Component<T> {
  focus: (options?: FocusOptionsPolyfill) => FocusOptionsPolyfill;
  blur: () => void;
  select: () => void;
  showOptions: () => void;
  hideOptions: () => void;
  clear: (event?: React.ChangeEvent<HTMLInputElement>) => void;
}

export type ManualInputFnSignature = (
  inputValue: string,
  suggestedOption: DropdownLayoutValueOption,
) => void;

export type OnSelectFnSignature = DropdownLayoutProps['onSelect'];
