import * as React from 'react';

import InputWithOptions, {
  InputWithOptionsProps,
  OnSelectFnSignature,
} from '../InputWithOptions';
import {
  DropdownLayoutProps,
  DropdownLayoutValueOption,
} from '../DropdownLayout';
import { TagProps } from '../Tag';
import { InputStatus } from '../Input';

export type MultiSelectStatus = InputStatus;

export interface MultiSelectProps extends InputWithOptionsProps<
  (values: string[]) => void
> {
  selectedId?: DropdownLayoutProps['selectedId'];
  /** Closes list once list item is selected */
  closeOnSelect?: DropdownLayoutProps['closeOnSelect'];
  selectedHighlight?: DropdownLayoutProps['selectedHighlight'];
  /** Callback predicate for the filtering options function */
  predicate?: (option: DropdownLayoutValueOption) => boolean;
  /** Defines a message to be displayed instead of options when no options exist or no options pass the predicate filter function. */
  emptyStateMessage?: React.ReactNode;
  /** Optional list of strings that are selected suggestions. */
  tags?: MultiSelectTag[];
  /** Max number of visible lines */
  maxNumRows?: number;
  /** Delimiters that will trigger a Submit action (call to onTagsAdded). By default it is [,] but also enter and tab keys work. */
  delimiters?: string[];
  /** Passing 'select' will render a readOnly input with menuArrow suffix **/
  mode?: MultiSelectMode;
  /** The status of the input */
  status?: MultiSelectStatus;
  /** Text to be shown in the status icon tooltip */
  statusMessage?: React.ReactNode;
  /** When this callback function is set, tags can be reordered. The expected callback signature is `onReorder({addedIndex: number, removedIndex: number}) => void` **/
  onReorder?: OnReorderFn;
  /** A callback which is called when the user selects an option from the list. `onSelect(option: Option): void` - Option is the original option from the provided options prop. */
  onSelect?: (option: DropdownLayoutValueOption) => void;
  customInput?: React.ReactNode | Function;
  /** A node to display as input suffix when the dropdown is closed */
  customSuffix?: React.ReactNode;
  /** A node to display as input prefix when the dropdown is closed */
  customPrefix?: React.ReactNode;
  /** When set to true this component is disabled */
  disabled?: boolean;
  /** Specifies whether input should be read only */
  readOnly?: boolean;
  /** A callback function to be called when a tag should be removed. The expected callback signature is `onRemoveTag(tagId: number | string) => void.` */
  onRemoveTag?: (tagId: TagProps['id']) => void;
  /** When set to false, the input will not be cleared on blur
   * @default true
   */
  clearOnBlur?: boolean;
  /** When set to true, the input will be submitted as new tag on blur */
  acceptOnBlur?: boolean;
  /** Adds a fixed footer container at the bottom of options list. */
  fixedFooter?: React.ReactNode;
}

export default class MultiSelect extends InputWithOptions<
  (values: string[]) => void,
  OnSelectFnSignature,
  MultiSelectProps
> {}

export type MultiSelectMode = 'select';
export type OnReorderFn = (data: {
  addedIndex: number;
  removedIndex: number;
}) => void;

export type MultiSelectTag = Omit<TagProps, 'children'> & {
  label: string;
};
