'use client'

import type {
  ChangeEvent,
  ChangeEventHandler,
  FocusEvent,
  KeyboardEvent,
  MouseEvent as ReactMouseEvent,
  KeyboardEvent as ReactKeyboardEvent,
  ReactNode,
  RefObject,
} from 'react'
import type { IPktComboboxOption, TPktComboboxDisplayValue, TPktComboboxTagPlacement } from 'shared-types/combobox'

export interface IPktCombobox {
  // Values & options
  value?: string | string[]
  defaultValue?: string | string[]
  options?: IPktComboboxOption[]
  defaultOptions?: IPktComboboxOption[]

  // Behavior
  multiple?: boolean
  maxlength?: number
  typeahead?: boolean
  includeSearch?: boolean
  allowUserInput?: boolean
  displayValueAs?: TPktComboboxDisplayValue
  tagPlacement?: TPktComboboxTagPlacement
  searchPlaceholder?: string

  // Form
  name?: string
  id?: string
  disabled?: boolean
  required?: boolean
  placeholder?: string

  // InputWrapper props
  label?: string
  helptext?: string | ReactNode
  helptextDropdown?: string | ReactNode
  helptextDropdownButton?: string
  hasError?: boolean
  errorMessage?: string | ReactNode
  fullwidth?: boolean
  requiredTag?: boolean
  requiredText?: string
  optionalTag?: boolean
  optionalText?: string
  tagText?: string
  useWrapper?: boolean
  inputSize?: 'small' | 'medium' | 'xsmall'

  // Events
  onChange?: ChangeEventHandler<HTMLInputElement>
  onValueChange?: (values: string[]) => void

  // React
  className?: string
  children?: ReactNode
}

export interface IComboboxState {
  // Identity
  id: string
  inputId: string
  listboxId: string

  // Values
  values: string[]
  inputValue: string
  searchValue: string

  // Options
  options: IPktComboboxOption[]
  filteredOptions: IPktComboboxOption[]

  // UI state
  isOpen: boolean
  userInfoMessage: string
  addValueText: string | null
  maxIsReached: boolean
  editingSingleValue: boolean
  inputFocus: boolean
  focusedTagIndex: number

  // Props passthrough
  label?: string
  multiple: boolean
  maxlength?: number
  typeahead: boolean
  includeSearch: boolean
  allowUserInput: boolean
  displayValueAs: TPktComboboxDisplayValue
  tagPlacement?: TPktComboboxTagPlacement
  searchPlaceholder?: string
  placeholder?: string
  disabled: boolean
  required: boolean
  fullwidth: boolean
  hasError: boolean
  errorMessage?: string | ReactNode
  helptext?: string | ReactNode
  helptextDropdown?: string | ReactNode
  helptextDropdownButton?: string
  optionalTag: boolean
  optionalText?: string
  requiredTag: boolean
  requiredText?: string
  tagText?: string
  useWrapper: boolean
  inputSize: 'small' | 'medium' | 'xsmall'
  name?: string
  className?: string

  // Derived state
  hasCounter: boolean

  // Refs
  inputRef: RefObject<HTMLInputElement | null>
  changeInputRef: RefObject<HTMLInputElement | null>
  triggerRef: RefObject<HTMLDivElement | null>
  listboxRef: RefObject<HTMLDivElement | null>
  wrapperRef: RefObject<HTMLDivElement | null>

  // Event handlers
  handleInputChange: (e: ChangeEvent<HTMLInputElement>) => void
  handleInputKeydown: (e: KeyboardEvent<HTMLInputElement>) => void
  handleInputFocus: () => void
  handleInputBlur: () => void
  handleFocusOut: (e: FocusEvent) => void
  handleInputClick: (e: ReactMouseEvent) => void
  handlePlaceholderClick: (e: ReactMouseEvent) => void
  handleSelectOnlyKeydown: (e: ReactKeyboardEvent) => void
  handleOptionClick: (value: string) => void
  handleOptionKeydown: (e: KeyboardEvent<HTMLLIElement>, value: string) => void
  handleTagRemove: (value: string) => void
  handleTagKeydown: (e: ReactKeyboardEvent, index: number) => void
  handleSearchInput: (e: ChangeEvent<HTMLInputElement>) => void
  handleSearchKeydown: (e: KeyboardEvent<HTMLInputElement>) => void
  handleNewOptionClick: (value: string) => void
  handleNewOptionKeydown: (e: KeyboardEvent<HTMLDivElement>) => void

  // Form integration
  onChange?: ChangeEventHandler<HTMLInputElement>
}
