import clsx from 'clsx'
import React, { ChangeEvent, FC, FocusEvent, useRef, useState } from 'react'

import closeIconSvg from '../../assets/svg/close.svg'
import { theming } from '../../themes'
import { useStyles } from './styles'

export type InputProps = {
  value?: string | number
  type?: string
  label?: string
  disabled?: boolean
  autoFocus?: boolean

  onFocus?: (e: FocusEvent) => void
  onBlur?: (e: FocusEvent) => void
  onChange?: (value: string) => void

  inputWrapperClassName?: string
  inputLabelClassName?: string

  inputClassName?: string

  error?: boolean

  startAdornment?: string
  endAdornment?: string
  isCloseIcon?: boolean
}

export const Input: FC<InputProps> = ({
  value,
  type = 'text',
  disabled = false,
  label,
  error,
  onFocus,
  onChange,
  startAdornment,
  endAdornment,
  onBlur,
  inputWrapperClassName,
  inputLabelClassName,
  isCloseIcon = true,
  ...props
}) => {
  const {
    closeButton,
    inputWrapper,
    input,
    inputLabelClass,
    inputActiveClass,
    inputDisabledClass,
    inputErrorClass,
    inputLabelActiveClass,
    inputLabelErrorClass,
    inputStartAdornmentClass,
    hideCloseButton,
  } = useStyles({ theme: theming.useTheme() })

  const inputEl = useRef<HTMLInputElement>(null)

  const [activeClass, setActiveClass] = useState(false)

  const handleFocus = (e: FocusEvent<HTMLInputElement>) => {
    if (disabled) return

    setActiveClass(true)

    if (onFocus) {
      onFocus(e)
    }
  }

  const handleChange = (event: ChangeEvent<HTMLInputElement>) => {
    if (onChange) {
      onChange(event.target.value)
    }
  }

  const handleBlur = (event: FocusEvent<HTMLInputElement>) => {
    setActiveClass(false)

    if (onBlur) {
      onBlur(event)
    }
  }

  const handleClean = () => {
    if (onChange) {
      onChange('')
    }
  }

  const isEndAdornmentShown = activeClass || error || value

  return (
    <div
      className={clsx(
        inputWrapper,
        inputWrapperClassName,
        activeClass && inputActiveClass,
        disabled && inputDisabledClass,
        error && inputErrorClass,
      )}
    >
      {startAdornment && <span className={inputStartAdornmentClass}>{startAdornment}</span>}

      {label && (
        <p
          className={clsx(
            inputLabelClass,
            inputLabelClassName,
            (value || activeClass) && inputLabelActiveClass,
            error && inputLabelErrorClass,
          )}
        >
          {label} {endAdornment && !isEndAdornmentShown && `- ${endAdornment}`}
        </p>
      )}
      <input
        ref={inputEl}
        type={type}
        disabled={disabled}
        className={clsx(input, disabled && inputDisabledClass)}
        value={value}
        onBlur={handleBlur}
        onChange={handleChange}
        onFocus={handleFocus}
        {...props}
      />
      {endAdornment && isEndAdornmentShown && <span>{endAdornment}</span>}

      <button onClick={handleClean} className={clsx(closeButton, isCloseIcon && !value && hideCloseButton)}>
        <img src={closeIconSvg} alt="Reset" />
      </button>
    </div>
  )
}
