import React from 'react';
import {Icon} from './common.js';

var formFieldCounter = 0,
    formFieldNestedLabelTypes = ['radio', 'checkbox'];

function formFieldId() {
  return "form-field-" + (++formFieldCounter);
}

export let FormField = React.createClass({
  _fieldRequiredText: 'This field is required',
  _type: null,
  _element: null,

  propTypes: {
    type: React.PropTypes.string.isRequired,
    prefix: React.PropTypes.string,
    postfix: React.PropTypes.string,
    hasError: React.PropTypes.bool
  },
  getInitialState: function() {
    return {
      isError: null,
      errorMessage: null,
    }
  },
  componentWillMount: function() {
    if (['text', 'number', 'radio', 'checkbox', 'file'].includes(this.props.type)) {
      this._element = 'input';
      this._type = this.props.type;
    } else if (this.props.type == 'text-number') {
      this._element = 'input';
      this._type = 'text';
    } else {
      // Non <input> field, e.g. <select>, <textarea>
      this._element = this.props.type;
    }
  },
  showError: function(text) {
    this.setState({
      isError: true,
      errorMessage: text,
    });
  },
  focus: function() {
    this.refs.field.focus();
  },
  getValue: function() {
    if (this.props.type == 'checkbox') {
      return this.refs.field.checked;
    } else if (this.props.type == 'file') {
      return this.refs.field.files.length && this.refs.field.files[0].path ?
                this.refs.field.files[0].path : null;
    } else {
      return this.refs.field.value;
    }
  },
  getSelectedElement: function() {
    return this.refs.field.options[this.refs.field.selectedIndex];
  },
  render: function() {
    // Pass all unhandled props to the field element
    const otherProps = Object.assign({}, this.props),
          isError = this.state.isError !== null ? this.state.isError : this.props.hasError,
          elementId = this.props.id ? this.props.id : formFieldId(),
          renderElementInsideLabel = this.props.label && formFieldNestedLabelTypes.includes(this.props.type);

    delete otherProps.type;
    delete otherProps.label;
    delete otherProps.hasError;
    delete otherProps.className;
    delete otherProps.postfix;
    delete otherProps.prefix;

    const element = <this._element id={elementId} type={this._type} name={this.props.name} ref="field" placeholder={this.props.placeholder}
                                    className={'form-field__input form-field__input-' + this.props.type + ' ' + (this.props.className || '') + (isError ? 'form-field__input--error' : '')}
      {...otherProps}>
      {this.props.children}
    </this._element>;

    return <div className="form-field">
      { this.props.prefix ? <span className="form-field__prefix">{this.props.prefix}</span> : '' }
      { renderElementInsideLabel ?
          <label htmlFor={elementId} className={"form-field__label " + (isError ? 'form-field__label--error' : '')}>
            {element}
            {this.props.label}
          </label> :
        element }
      { this.props.postfix ? <span className="form-field__postfix">{this.props.postfix}</span> : '' }
      { isError && this.state.errorMessage ?  <div className="form-field__error">{this.state.errorMessage}</div> : '' }
    </div>
  }
})

export let FormRow = React.createClass({
  _fieldRequiredText: 'This field is required',
  propTypes: {
    label: React.PropTypes.oneOfType([React.PropTypes.string, React.PropTypes.element])
    // helper: React.PropTypes.html,
  },
  getInitialState: function() {
    return {
      isError: false,
      errorMessage: null,
    }
  },
  showError: function(text) {
    this.setState({
      isError: true,
      errorMessage: text,
    });
  },
  showRequiredError: function() {
    this.showError(this._fieldRequiredText);
  },
  clearError: function(text) {
    this.setState({
      isError: false,
      errorMessage: ''
    });
  },
  getValue: function() {
    return this.refs.field.getValue();
  },
  getSelectedElement: function() {
    return this.refs.field.getSelectedElement();
  },
  focus: function() {
    this.refs.field.focus();
  },
  render: function() {
    const fieldProps = Object.assign({}, this.props),
          elementId = formFieldId(),
          renderLabelInFormField = formFieldNestedLabelTypes.includes(this.props.type);

    if (!renderLabelInFormField) {
      delete fieldProps.label;
    }
    delete fieldProps.helper;

    return <div className="form-row">
      { this.props.label && !renderLabelInFormField ?
        <div className={"form-row__label-row " + (this.props.labelPrefix ? "form-row__label-row--prefix" : "") }>
          <label htmlFor={elementId} className={"form-field__label " + (this.state.isError ? 'form-field__label--error' : '')}>
            {this.props.label}
          </label>
        </div> : '' }
      <FormField ref="field" hasError={this.state.isError} {...fieldProps} />
      { !this.state.isError && this.props.helper ?  <div className="form-field__helper">{this.props.helper}</div> : '' }
      { this.state.isError ?  <div className="form-field__error">{this.state.errorMessage}</div> : '' }
    </div>
  }
})