import { useRouteMatch } from 'react-router-dom'

import isEmpty from 'lodash/isEmpty'
import map from 'lodash/map'

import { useLexicsStore } from 'features/LexicsStore'

import { PAGES } from 'config'

import { AudioPlayer } from 'components/AudioPlayer'

import { T9n } from 'features/T9n'
import { Loader } from 'features/Loader'
import { Icon } from 'features/Icon'
import { OutsideClick } from 'features/OutsideClick'
import {
  Column,
  Error,
  InputWrapper,
  InputStyled,
  Label,
  LabelTitle,
  LabelAfter,
  LabelBefore,
  ScTooltip,
} from 'features/Common/Input/styled'

import { Props, Option } from './types'
import { useCombobox } from './hooks'
import {
  PopOver,
  ListOption,
  WrapperIcon,
  ScLoaderWrapper,
} from './styled'

import { Arrow } from './components/Arrow'

export const Combobox = <T extends Option>(props: Props<T>) => {
  const {
    className,
    disabled,
    error,
    iconName,
    label,
    labelAfter,
    labelBefore,
    labelLexic,
    labelWidth,
    loading,
    maxLength,
    noSearch,
    title,
    toolTip,
    withError,
    wrapperHeight,
  } = props

  const {
    index,
    inputFieldRef,
    isOpen,
    onInputBlur,
    onKeyDown,
    onOptionSelect,
    onOutsideClick,
    onQueryChange,
    open,
    options,
    popoverRef,
    query,
    toggle,
  } = useCombobox(props)
  const { translate } = useLexicsStore()
  const isUserAccountPage = useRouteMatch(PAGES.useraccount)?.path === PAGES.useraccount

  return (
    <Column isUserAccountPage={isUserAccountPage} className={className}>
      <InputWrapper
        error={error}
        wrapperHeight={wrapperHeight}
      >
        <Label>
          <LabelTitle
            labelWidth={labelWidth}
            isUserAccountPage={isUserAccountPage}
            onClick={(e) => {
              if (toolTip) {
                e.preventDefault()
                e.stopPropagation()
              }
            }}
          >
            {labelLexic ? <T9n t={labelLexic} /> : label}
            {toolTip && <ScTooltip className='Highlight__Tooltip'><T9n t={toolTip} /></ScTooltip>}
          </LabelTitle>
          {labelBefore && (
            <LabelBefore>
              <AudioPlayer asset={labelBefore} />
            </LabelBefore>
          )}
          <InputStyled
            maxLength={maxLength}
            onBlur={onInputBlur}
            onFocus={open}
            ref={inputFieldRef}
            autoComplete='off'
            title={title}
            value={query}
            disabled={disabled}
            readOnly={noSearch}
            onChange={onQueryChange}
            onKeyDown={onKeyDown}
            placeholder={translate(labelLexic || '')}
            isUserAccountPage={isUserAccountPage}
            style={{ cursor: noSearch ? 'pointer' : '' }}
          />
          {labelAfter && query && <LabelAfter>{labelAfter}</LabelAfter>}
        </Label>
        {loading ? (
          <ScLoaderWrapper>
            <Loader color='#363636' />
          </ScLoaderWrapper>
        ) : ''}
        {iconName ? (
          <WrapperIcon>
            <Icon refIcon={iconName} />
          </WrapperIcon>
        ) : !disabled && (
          <Arrow isExpanded={isOpen} toggle={toggle} />
        )}
        {isOpen && !isEmpty(options) && (
          <OutsideClick onClick={onOutsideClick}>
            <PopOver ref={popoverRef}>
              {map(options, (option, i) => (
                <ListOption
                  onClick={(e) => onOptionSelect(option.name, e)}
                  aria-selected={index === i}
                  isHighlighted={index === i}
                  key={option.id}
                  id={option.id.toString()}
                >
                  {option.name}
                </ListOption>
              ))}
            </PopOver>
          </OutsideClick>
        )}
      </InputWrapper>
      {withError && <Error t={error || ''} />}
    </Column>
  )
}
