import { Input, Icon } from 'semantic-ui-react'

export default observer class _Input extends Component
  @propTypes:
    name: PropTypes.string
    onChange: PropTypes.func
    label: PropTypes.string
    isRequired: PropTypes.bool
    type: PropTypes.oneOf [
      'email',
      'password',
      'id',
      'number'
    ]
    isResetVisible: PropTypes.bool
    resetButtonSize: PropTypes.string
    isHeaderVisible: PropTypes.bool
    style: PropTypes.object
    inputProps: PropTypes.object
    labelPosition: PropTypes.oneOf [
      'top',
      'left'
    ]

  @defaultProps:
    onChange: =>
    resetButtonSize: 'large'
    isHeaderVisible: false
    labelPosition: 'left'

  constructor: (props) ->
    super props

    @state = observable
      value: props.value
      error: @validate @props.type, @props.value, @props.validator

    reaction(
      =>
        @state.value
    ,
      (value) =>
        props.onChange value, @state.error, @props.name
    )

  componentDidUpdate: =>
    @state.error = @validate @props.type, @props.value, @props.validator

    @state.value = @props.value

  validate: (type, value, validator) =>
    if value is ''
      return null

    if not validator
      if type is 'id'
        isValid = not /[^a-z0-9]/.test(value) and 6 <= value.length <= 20

        if not isValid
          return '아이디는 6~20자의 영문 소문자, 숫자만 사용 가능합니다.'

      else if type is 'email'
        isValid = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/.test value

        if not isValid
          return '이메일이 형식에 맞지 않습니다'

      else if type is 'password'
        isValid = true

        if value.length < 8
          isValid = false

        if not /[^a-zA-Z0-9]/.test value
          isValid = false

        if not /[1234567890]/.test value
          isValid = false

        if not isValid
          return '비밀번호는 숫자, 특수문자 포함 8글자 이상으로 해주세요'

      else
        isValid = true

    else
      return validator value

    if isValid
      return ''

  onChangeInput: (event, data) =>
    if data.value isnt '' and @props.type is 'number'
      if not /^-?[0-9]*\.?[0-9]*$/.test data.value
        return

    @state.error = @validate @props.type, data.value, @props.validator

    @state.value = data.value

  onClickReset: () =>
    @state.error = null

    @state.value = ''

  render: =>
    style = _.cloneDeep @props.style

    _.extend style,
      position: 'relative'

    <div style={style}>
      { @props.isHeaderVisible and
        <div style={{ marginBottom: 4, height: 20 }}>
          { @props.labelPosition is 'top' and
            <span>
              { @props.label and
                <span style={{ color: 'rgba(0, 0, 0, 0.87)', fontWeight: 'bold', marginRight: if @props.isRequired then 2 else 10 }}>{ @props.label }</span>
                }
              { @props.isRequired and
                <span style={{ color: '#ff0000', marginRight: 10 }}>*</span>
                }
            </span>
            }
          <span style={{ color: '#ff0000', fontSize: 11, fontWeight: 'normal', marginLeft: if @props.labelPosition is 'left' then 100 else 0 }}>{ @state.error }</span>
        </div>
        }
      <div style={{ display: 'flex' }}>
        { @props.labelPosition is 'left' and @props.label and
          <div style={{ display: 'flex', alignItems: 'center', width: 100 }}>
            <span style={{ color: 'rgba(0, 0, 0, 0.87)', fontWeight: 'bold', marginRight: if @props.isRequired then 2 else 10 }}>{ @props.label }</span>
            { @props.isRequired and
              <span style={{ color: '#ff0000', marginRight: 10 }}>*</span>
              }
          </div>
          }
        <div style={{ flex: 1 }}>
          <Input fluid type={if @props.type is 'password' then 'password' else 'text'} onChange={@onChangeInput} {...@props.inputProps} />
        </div>
      </div>
      { @props.isResetVisible and @state.value and
        <div onClick={@onClickReset} style={{ cursor: 'pointer', position: 'absolute', bottom: 0, right: 0, height: (if @props.isHeaderVisible then 'calc(100% - 20px)' else '100%'), width: 25, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
          <Icon name="close" size={@props.resetButtonSize} />
        </div>
        }
    </div>
