import React from 'react'
import PropTypes from 'prop-types'
import Validator from '../../classes/Validator'
import Tooltip from '../Tooltip'

class ValidationField extends React.Component {
  constructor () {
    super()
    this.open = false
    this.errors = []
    this.state = {
      didmount: false
    }
  }

  isValidationField () {
    return true
  }

  handleInputFocus (e) {
    this.open = true
    this.setState({})
  }

  handleInputBlur (e) {
    this.open = false
    this.setState({})
  }

  componentWillReceiveProps (nextProps) {
    clearTimeout(this.getErrorTimeout)
    this.getErrorTimeout = setTimeout(() => {
      this.errors = this.getError(nextProps)
      this.setState({})
    }, 100)
  }

  componentDidMount () {
    if (this.props.setValidationFn) {
      this.props.setValidationFn(this.validateInput.bind(this))
    }
    this.setState({
      didmount: true
    })
  }

  componentWillUnmount () {
    if (this.props.setValidationFn) {
      this.props.setValidationFn(null)
    }
    clearTimeout(this.getErrorTimeout)
  }

  validateInput (showError = true) {
    let errors = this.getError(this.props)
    let isError = errors.length > 0
    let errorMessage = errors[0] ? errors[0].errorMessage : ''
    if (this.props.displayName) {
      errorMessage = errorMessage.replace('%n', this.props.displayName)
    }
    if (showError) {
      this.errors = errors
      if (isError) {
        this.handleInputFocus()
        this.isValidated = true
      } else if (this.open) {
        this.handleInputBlur()
      }
    }
    let { name, value } = this.props
    return { name, value, isError, errorMessage }
  }

  getError (props) {
    let errors = Validator.validateField(props.value, props.validators, props.customValidator)
    return errors.filter((e) => { return e.isError })
  }

  render () {
    let props = {...this.props}
    let errors = this.errors
    let tooltipContent = []
    let totalErrorToDisplay = this.props.singleError ? Math.min(errors.length, 1) : errors.length
    for (let i = 0; i < totalErrorToDisplay; i++) {
      let errorMessage = errors[i] ? errors[i].errorMessage : ''
      if (this.props.displayName) {
        errorMessage = errorMessage.replace('%n', this.props.displayName)
      }
      let content = (
        <div key={i}>{errorMessage}</div>
      )
      if (this.props.customErrorMessageElement) {
        let Element = this.props.customErrorMessageElement
        content = (
          <Element key={i}>{errorMessage}</Element>
        )
      }
      tooltipContent.push(content)
    }
    let disabled = tooltipContent.length === 0
    delete props.validators
    let tooltipProps = {
      onFocus: this.handleInputFocus.bind(this),
      onBlur: this.handleInputBlur.bind(this)
    }
    if (this.props.tooltipProps) {
      tooltipProps = {
        ...tooltipProps,
        ...this.props.tooltipProps
      }
    }
    let onClickFn = this.isValidated ? () => { this.open = false; this.isValidated = false; this.setState({}) } : null
    return this.state.didmount ? (
      <Tooltip
        showed={this.open && !disabled}
        content={tooltipContent}
        tooltipProps={tooltipProps}
        tooltipClassName={this.props.tooltipClassName}
        tooltipPlacement={this.props.tooltipPlacement}
        onTooltipClick={onClickFn}>
        {this.props.children}
      </Tooltip>
    ) : this.props.children
  }
}

ValidationField.propTypes = {
  validators: PropTypes.array,
  showValid: PropTypes.any,
  singleError: PropTypes.any,
  name: PropTypes.string,
  displayName: PropTypes.string,
  value: PropTypes.any,
  tooltipProps: PropTypes.object,
  tooltipClassName: PropTypes.string,
  tooltipPlacement: PropTypes.string,
  setValidationFn: PropTypes.func,
  customValidator: PropTypes.func,
  customErrorMessageElement: PropTypes.any,
  children: PropTypes.any
}

export default ValidationField
