import * as React from 'react'
import classNames from 'classnames'

type State = {
  hasBlurredAfterChange: boolean
  hasChanged: boolean
  isFocused: boolean
  value: string
}

type Props = {
  autoComplete?: string
  className?: string
  dataTestId: string
  disabled?: boolean
  id?: string
  label: string
  maxLength?: number
  name: string
  onBlur?: () => void
  onInput: (value: string) => void
  placeholder?: string
  revealValidationMessage?: boolean
  rows?: number
  validationMessage?: string
  value: string
}

export class TextAreaBlock extends React.Component<Props, State> {
  state = {
    hasBlurredAfterChange: false,
    hasChanged: false,
    isFocused: false,
    value: '',
  }

  componentDidMount() {
    this.handleInput(this.props.value)
  }

  UNSAFE_componentWillReceiveProps(nextProps: Props) {
    if (nextProps.value) {
      const value = nextProps.value
      this.setState({ value })
    }
  }

  handleInput = (value: string) => {
    const { onInput } = this.props
    if (value || value === '') this.setState({ value })
    if (onInput) onInput(value)
  }

  handleBlur = () => {
    const { onBlur } = this.props
    const { hasChanged } = this.state
    this.setState(
      {
        isFocused: false,
        hasBlurredAfterChange: hasChanged,
      },
      () => {
        if (onBlur) onBlur()
      }
    )
  }

  onFocus = () => {
    this.setState({ isFocused: true })
  }

  onInput = (e: any) => {
    this.setState({ hasChanged: true })
    this.handleInput(e.target.value)
  }

  render() {
    const {
      autoComplete,
      className,
      dataTestId,
      disabled,
      id,
      label,
      maxLength,
      name,
      placeholder,
      rows,
      revealValidationMessage,
      validationMessage,
    } = this.props

    const { hasBlurredAfterChange, hasChanged, isFocused, value } = this.state

    const hasUserInteracted = hasChanged && hasBlurredAfterChange
    const showError =
      validationMessage && (hasUserInteracted || revealValidationMessage)
    const displayLabel = showError ? validationMessage : label

    const wrapperClass = classNames(
      {
        'ui-input__text-wrapper': true,
        'ui-input__text-wrapper--error': !!showError,
        'ui-input__text-wrapper--focused': isFocused,
        'ui-input__text-wrapper--has-value': !!value,
      },
      className
    )

    return (
      <div className={wrapperClass}>
        {displayLabel && (
          <label
            className="ui-input__text-label"
            htmlFor={id || name}
            data-text={displayLabel}
          >
            {displayLabel}
          </label>
        )}
        <textarea
          autoComplete={autoComplete}
          className="ui-input__textarea"
          data-testid={dataTestId}
          disabled={disabled}
          id={id}
          maxLength={maxLength || 370}
          name={name}
          onBlur={this.handleBlur}
          onChange={() => {}}
          onFocus={this.onFocus}
          onInput={this.onInput}
          placeholder={placeholder}
          rows={rows || 7}
          value={value}
        />
      </div>
    )
  }
}
