import React from 'react'

import { IconProp, IconProps } from '../icon'
import { PProps } from '../p'
import { SystemProps } from '../system'
import { ThemingProps } from '../theme'
import { ChangeEventHandler, FocusEventHandler, PropsOf } from '../utils'

export type InputInputProps = PropsOf<'input', SystemProps>
export type InputProps = SystemProps &
  ThemingProps<'Input'> & {
    /** Allow to remove input content with clear icon. */
    allowClear?: boolean
    /** Passed to the inner input. */
    autoComplete?: string
    /** List of autocomplete options. */
    autoCompleteOptions?: string[]
    /** Maximum autoComplete container height in px. */
    autoCompleteMaxHeight?: number
    /** Passed to the inner input. */
    autoFocus?: boolean
    /** ARIA label for the input element. */
    ariaLabel?: string
    /** Deprecated. Please use variant instead. @deprecated  */
    colorScheme?: 'green' | 'grey' | 'red'
    /** Passed to the inner input. */
    defaultValue?: number | string
    /** Passed to the inner input. */
    disabled?: boolean
    /** Socket displaying error text below an input. */
    errorText?: string | React.ReactNode
    /** Socket displaying help text below an input. */
    helpText?: React.ReactNode | string
    /** Socket displaying an icon on the left. */
    iconLeft?: IconProp | JSX.Element
    /** Socket displaying an icon on the right. */
    iconRight?: IconProp | JSX.Element
    /** Socket rendering a custom input element. */
    input?: React.ReactNode
    /** Props object passed to the inner input. */
    inputProps?: InputInputProps
    /** Ref passed to the inner input. */
    inputRef?: React.MutableRefObject<HTMLInputElement | null> | null
    /** Deprecated. Please use variant="red" and/or state="error" instead. @deprecated*/
    isInvalid?: boolean
    /** Socket displaying a custom element on the left. */
    itemLeft?: React.ReactNode
    /** Socket displaying a custom element on the right. */
    itemRight?: React.ReactNode
    /** The label. */
    label?: string | React.ReactNode
    /** Should the label indicates that the field is optional */
    labelMarkOptional?: boolean
    /** Adds a tooltip with the text inside the label */
    labelTooltipText?: string
    /** Passed to the inner input. */
    max?: number | string
    /** Passed to the inner input. */
    maxLength?: number
    /** Passed to the inner input. */
    min?: number | string
    /** Passed to the inner input. */
    minLength?: number
    /** Passed to the inner input. */
    name?: string
    /** Passed to the inner input. */
    onBlur?: FocusEventHandler
    /** Passed to the inner input. */
    onChange?: ChangeEventHandler
    /** Passed to the inner input. */
    onFocus?: FocusEventHandler
    /** Passed to the inner input. */
    pattern?: string
    /** Passed to the inner input. */
    placeholder?: string
    /** Passed to the inner input. */
    readOnly?: boolean
    /** Passed to the inner input. */
    required?: boolean
    /** Displays length of input value if also using maxLength. */
    showCount?: boolean
    /** Displays the provided value. */
    displayValueOnly?: boolean
    /** Modifies Input style and content based on the given state. */
    state?: InputState
    /** Object definition of styles and content for each state. */
    stateMapping?: InputStateMapping
    /** Passed to the inner input. */
    step?: number
    /** Passed to the inner input. */
    type?: InputType
    /** Passed to the inner input. */
    value?: number | string
  }

export type AutoCompletePopoverProps = {
  /** List of autocomplete options. */
  autoCompleteOptions?: string[]
  /** Maximum autoComplete container height in px. */
  autoCompleteMaxHeight?: number
  /** The input children. */
  children: JSX.Element
  /** Filter helper function. */
  filterAutoCompleteOptions: (value: string, index: number, array: string[]) => boolean
  onAutoCompleteSelect: (value: string) => void
}

export type HelpTextProps = PProps & {
  isError?: boolean
}

export type InputState = 'default' | 'error' | 'loading' | 'success'

export type InputStateMapping = Record<
  string,
  {
    variant?: InputProps['variant']
    iconProps: IconProps
  }
>

export type InputType =
  | 'date'
  | 'datetime-local'
  | 'email'
  | 'hidden'
  | 'month'
  | 'number'
  | 'password'
  | 'search'
  | 'tel'
  | 'text'
  | 'time'
  | 'url'
  | 'week'
