'use client'

import { findOptionByValue, findOptionIndex } from 'shared-utils/combobox'
import { PktIcon } from '../icon/Icon'
import { ComboboxTags, SingleValueDisplay } from './ComboboxTags'
import type { IComboboxState } from './types'

interface IComboboxInputProps {
  state: IComboboxState
}

export const ComboboxInput = ({ state }: IComboboxInputProps) => {
  const {
    id,
    inputId,
    listboxId,
    values,
    options,
    isOpen,
    multiple,
    typeahead,
    allowUserInput,
    tagPlacement,
    placeholder,
    disabled,
    fullwidth,
    hasError,
    label,
    inputFocus,
    inputRef,
    triggerRef,
    handleInputChange,
    handleInputKeydown,
    handleInputFocus,
    handleInputBlur,
    handleInputClick,
    handlePlaceholderClick,
    handleSelectOnlyKeydown,
    name,
    inputSize,
  } = state

  const inputClasses = [
    'pkt-combobox__input',
    `pkt-combobox__input--${inputSize}`,
    fullwidth && 'pkt-combobox__input--fullwidth',
    isOpen && 'pkt-combobox__input--open',
    hasError && 'pkt-combobox__input--error',
    disabled && 'pkt-combobox__input--disabled',
  ]
    .filter(Boolean)
    .join(' ')

  const arrowIconClasses = ['pkt-combobox__arrow-icon', isOpen && 'pkt-combobox__arrow-icon--open']
    .filter(Boolean)
    .join(' ')

  const hasTextInput = typeahead || allowUserInput
  const showPlaceholder =
    !hasTextInput && placeholder && (!values.length || (multiple && tagPlacement === 'outside')) && !inputFocus

  const showInlineValues = tagPlacement !== 'outside'

  // Compute aria-activedescendant for select-only mode
  const activeDescendant =
    values[0] && findOptionByValue(options, values[0])
      ? `${listboxId}-${findOptionIndex(options, values[0])}`
      : undefined

  // Build selection description for screen readers
  const selectionDescription = multiple && values.length > 0 ? `${values.length} valgt` : undefined

  // Select-only ARIA props (applied to the container div)
  const selectOnlyProps = !hasTextInput
    ? {
        id: `${id}-combobox`,
        role: 'combobox' as const,
        'aria-expanded': isOpen ? ('true' as const) : ('false' as const),
        'aria-controls': listboxId,
        'aria-haspopup': 'listbox' as const,
        'aria-labelledby': `${id}-combobox-label`,
        'aria-activedescendant': activeDescendant,
        'aria-description': selectionDescription,
        tabIndex: disabled ? -1 : 0,
        onKeyDown: handleSelectOnlyKeydown,
      }
    : {
        tabIndex: -1,
      }

  return (
    <div ref={triggerRef} className={inputClasses} onClick={handleInputClick} {...selectOnlyProps}>
      {showPlaceholder ? (
        <span className="pkt-combobox__placeholder" onClick={handlePlaceholderClick}>
          {placeholder}
        </span>
      ) : showInlineValues ? (
        multiple ? (
          <ComboboxTags state={state} />
        ) : !hasTextInput ? (
          <SingleValueDisplay state={state} />
        ) : null
      ) : null}

      {hasTextInput ? (
        <div className="pkt-combobox__input-div combobox__input">
          <input
            ref={inputRef}
            type="text"
            id={inputId}
            name={`${name || id}-input`}
            onChange={handleInputChange}
            onKeyDown={handleInputKeydown}
            onFocus={handleInputFocus}
            onBlur={handleInputBlur}
            placeholder={!values.length || (multiple && tagPlacement === 'outside') ? placeholder : undefined}
            autoComplete="off"
            role="combobox"
            aria-expanded={isOpen ? 'true' : 'false'}
            aria-label={label}
            aria-autocomplete={typeahead ? 'both' : allowUserInput ? 'list' : 'none'}
            aria-controls={listboxId}
            aria-activedescendant={activeDescendant}
            aria-description={selectionDescription}
            disabled={disabled}
          />
        </div>
      ) : (
        <input
          ref={inputRef}
          type="hidden"
          id={inputId}
          name={`${name || id}-input`}
          value={values.join(',')}
          readOnly
        />
      )}

      <PktIcon className={arrowIconClasses} name="chevron-thin-down" aria-hidden="true" />
    </div>
  )
}
