import React, { ReactNode } from 'react';
import { ButtonProps } from '../../button/Button.types';
import { WithInputAttributesProps } from './SelectInput.contexts';

// Item interfaces
export interface SelectInputOptionItem<T = string> {
  type: 'option';
  value: T;
  filterMatchers?: readonly string[];
  disabled?: boolean;
}

export interface SelectInputGroupItem<T = string> {
  type: 'group';
  label: ReactNode;
  options: readonly SelectInputOptionItem<T>[];
  action?: {
    label: string;
    onClick: ButtonProps['onClick'];
  };
}

export interface SelectInputSeparatorItem {
  type: 'separator';
}

export type SelectInputItem<T = string> =
  | SelectInputOptionItem<T>
  | SelectInputGroupItem<T>
  | SelectInputSeparatorItem;

// Main component props
export interface SelectInputProps<T = string, M extends boolean = false> {
  id?: string;
  /**
   * Sets the `data-wds-parent` attribute on the listbox container, which is needed for complex components like DateInput to correctly manage event handling.
   * @internal
   */
  parentId?: string;
  name?: string;
  multiple?: M;
  placeholder?: string;
  items: readonly SelectInputItem<NonNullable<T>>[];
  /**
   * Enables browser autocomplete integration through the search input.
   * Accepts standard HTML autocomplete values (e.g., "country-name", "address-level1").
   *
   * Requires `filterable={true}` to enable the search input.
   *
   * @example
   * <SelectInput
   *   name="country"
   *   autocomplete="country-name"
   *   filterable={true}
   *   items={[{
   *     type: 'option',
   *     value: 'GB',
   *     filterMatchers: ['United Kingdom', 'UK']
   *   }]}
   * />
   */
  autocomplete?: string;
  defaultValue?: M extends true ? readonly T[] : T;
  value?: M extends true ? readonly T[] : T;
  compareValues?:
    | (keyof NonNullable<T> & string)
    | ((a: T | undefined, b: T | undefined) => boolean);
  renderValue?: (value: NonNullable<T>, withinTrigger: boolean) => React.ReactNode;
  renderFooter?: (args: {
    resultsEmpty: boolean;
    queryNormalized: string | null | undefined;
  }) => React.ReactNode;
  renderTrigger?: (args: {
    content: React.ReactNode;
    placeholderShown: boolean;
    clear: (() => void) | undefined;
    disabled: boolean;
    size: 'sm' | 'md' | 'lg';
    className: string | undefined;
  }) => React.ReactNode;
  filterable?: boolean;
  filterPlaceholder?: string;
  sortFilteredOptions?: (
    a: SelectInputOptionItem<NonNullable<T>>,
    b: SelectInputOptionItem<NonNullable<T>>,
    searchQuery: string,
  ) => number;
  disabled?: boolean;
  size?: 'sm' | 'md' | 'lg';
  className?: string;
  UNSAFE_triggerButtonProps?: WithInputAttributesProps['inputAttributes'] & {
    'aria-label'?: string;
  };
  /** Ref to the select trigger button element. */
  triggerRef?: React.MutableRefObject<HTMLButtonElement | null>;
  onFilterChange?: (args: { query: string; queryNormalized: string | null }) => void;
  onChange?: (value: M extends true ? T[] : T) => void;
  onOpen?: () => void;
  onClose?: () => void;
  onClear?: () => void;
}

export type {
  SelectInputTriggerButtonElementType,
  SelectInputTriggerButtonProps,
} from './TriggerButton';
export type { SelectInputClearButtonProps } from './ClearButton';
export type { SelectInputOptionContentProps } from './OptionContent';
export type { SelectInputOptionProps } from './Option';
export type { SelectInputItemViewProps } from './ItemView';
export type { SelectInputGroupItemViewProps } from './ItemView/GroupItemView';
export type { SelectInputOptionsProps } from './Options';
export type { SelectInputOptionsContainerProps } from './Options/OptionsContainer';
