import { Combobox, ComboboxItem, TextInput, useCombobox } from '@tidbcloud/uikit'
import { useUncontrolled } from '@tidbcloud/uikit/hooks'
import { ReactNode, forwardRef } from 'react'

export interface TargetInputProps {
  data: ComboboxItem[]
  label?: string
  placeholder?: string
  error?: ReactNode
  getCreateLabel?: (value: string) => ReactNode
  onChange?: (value: string) => void
  value?: string
  width?: number
  disabled?: boolean
  'data-testid'?: string
}

export const TargetInput = forwardRef<HTMLInputElement, TargetInputProps>(
  (
    { data, label, placeholder, error, onChange, getCreateLabel, value, width, disabled, 'data-testid': dataTestId },
    ref
  ) => {
    const combobox = useCombobox()
    const [_value, setValue] = useUncontrolled({
      value,
      onChange
    })
    const shouldFilterOptions = !data.some((item) => item.value === _value)
    const filteredOptions = shouldFilterOptions
      ? data.filter((item) => item.label.toLowerCase().includes(_value.toLowerCase().trim()))
      : data

    const options = filteredOptions.map((item) => (
      <Combobox.Option value={item.value} key={item.value} disabled={item.disabled}>
        {item.label}
      </Combobox.Option>
    ))

    return (
      <Combobox
        onOptionSubmit={(optionValue) => {
          setValue(optionValue)
          combobox.closeDropdown()
        }}
        store={combobox}
      >
        <Combobox.Target>
          <TextInput
            ref={ref}
            label={label}
            placeholder={placeholder}
            error={error}
            value={_value}
            onChange={(event) => {
              setValue(event.currentTarget.value)
              combobox.openDropdown()
              combobox.updateSelectedOptionIndex()
            }}
            onClick={() => combobox.openDropdown()}
            onFocus={() => combobox.openDropdown()}
            onBlur={() => combobox.closeDropdown()}
            width={width}
            disabled={disabled}
            data-testid={dataTestId}
          />
        </Combobox.Target>

        <Combobox.Dropdown>
          <Combobox.Options>
            {options.length === 0 ? (
              <Combobox.Option value={_value}>{getCreateLabel?.(_value) ?? `+ Create ${_value}`}</Combobox.Option>
            ) : (
              options
            )}
          </Combobox.Options>
        </Combobox.Dropdown>
      </Combobox>
    )
  }
)

TargetInput.displayName = 'TargetInput'
