import React, { useRef, useEffect } from 'react'
import PropTypes from 'prop-types'

function InputText ({ value, placeholder, onChange, errorMessage }) {
  const frame = {
    border: '1px solid',
    borderColor: 'var(--mono50)',
    padding: '0.5em',
    borderRadius: '0.5em',
    fontSize: '1em',
    transition: 'background .3s, border .3s, box-shadow .2s'
  }

  const primary = {
    border: '1px solid',
    borderColor: 'var(--primary75)',
    padding: '0.5em',
    borderRadius: '0.5em',
    fontSize: '1em',
    boxShadow: '0 0 0 2px var(--primary00)',
    transition: 'background .3s, border .3s, box-shadow .2s'
  }

  const errorColor = {
    border: '1px solid',
    borderColor: 'var(--red50)',
    padding: '0.5em',
    borderRadius: '0.5em',
    fontSize: '1em',
    transition: 'background .3s, border .3s, box-shadow .2s'
  }

  const blank = {
    width: '100%',
    resize: 'none',
    outline: 'none',
    border: 'none',
    fontFamily: '"Public Sans", sans-serif',
    fontSize: '1em',
    color: 'var(--mono150)'
  }

  const hover = {
    border: '1px solid',
    borderColor: 'var(--primary)',
    padding: '0.5em',
    borderRadius: '0.5em',
    fontSize: '1em',
    transition: 'background .3s, border .3s, box-shadow .2s'
  }

  const [style, setStyle] = React.useState(frame)
  const [styleName, setStyleName] = React.useState('frame')

  const prevCountRef = useRef()
  useEffect(() => {
    prevCountRef.current = style
  })
  const prevCount = prevCountRef.current

  function toggleHover () {
    if (styleName !== 'primary') {
      setStyle(hover)
    }
  }

  function toggleLeave () {
    if (styleName !== 'primary') {
      setStyle(prevCount)
    }
  }

  function toggleClick () {
    setStyle(primary)
    setStyleName('primary')
  }

  function useOutsideAlerter (ref) {
    useEffect(() => {
      /**
           * Alert if clicked on outside of element
           */
      function handleClickOutside (event) {
        if (ref.current && !ref.current.contains(event.target)) {
          if (errorMessage) {
            setStyle(errorColor)
            setStyleName('errorColor')
          } else {
            setStyle(frame)
            setStyleName('frame')
          }
        }
      }

      // Bind the event listener
      document.addEventListener('mousedown', handleClickOutside)
      return () => {
        // Unbind the event listener on clean up
        document.removeEventListener('mousedown', handleClickOutside)
      }
    }, [ref])
  }

  function setBorder (ref) {
    useEffect(() => {
      if (errorMessage) {
        setStyle(errorColor)
      } else if (styleName === 'hover') {
        setStyle(hover)
      } else if (styleName === 'primary') {
        setStyle(primary)
      } else if (styleName === 'frame') {
        setStyle(frame)
      } else if (styleName === 'error') {
        setStyle(errorColor)
      }
    }, [ref])
  }

  const wrapperRef = useRef(null)
  useOutsideAlerter(wrapperRef)
  setBorder(wrapperRef)

  return (
    <>
      <div ref={wrapperRef}>
        <div style={style}>
          <input
            style={blank}
            type="text"
            onClick={toggleClick}
            value={value}
            placeholder={placeholder}
            onChange={onChange}
            onMouseEnter={toggleHover}
            onMouseLeave={toggleLeave}
          />
        </div>
      </div>
      {errorMessage ? <p className="errorSmall">{errorMessage}</p> : null}
    </>
  )
}

InputText.propTypes = {
  value: PropTypes.string,
  placeholder: PropTypes.string,
  onChange: PropTypes.func,
  color: PropTypes.any,
  errorMessage: PropTypes.string
}

export default InputText
