import React from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';

import '../base';
import styles from './Textfield.styl';
import newId from '../utils/newId';
import Label from './Label';
import labelStyles from './Label.styl';

export default class Textfield extends React.Component {
  constructor(props) {
    super(props);
    this.onClick = this.onClick.bind(this);
    this.onChangeTextArea = this.onChangeTextArea.bind(this);
  }

  componentWillMount() {
    this.id = newId();
  }

  componentDidMount() {
    if (this.props.type === 'textarea') {
      this.resizeTextArea();
    }
  }

  onClick(e) {
    if (!this.context.enforceReadonly && this.context.readonly && this.context.toggleReadonly) this.context.toggleReadonly(e);
    if (this.props.onClick) this.props.onClick(e);
  }

  onChangeTextArea(e) {
    this.resizeTextArea();
    if (this.props.onChange) {
      this.props.onChange(e);
    }
  }

  resizeTextArea() {
    const { paddingTop, paddingBottom } = window.getComputedStyle(this.input);
    const verticalPadding = parseInt(paddingTop, 10) + parseInt(paddingBottom, 10);
    this.input.style.height = 'auto';
    this.input.style.height = `${this.input.scrollHeight + verticalPadding}px`;
  }

  blur() {
    if (this.input) {
      this.input.blur();
    }
  }

  focus() {
    if (this.input) {
      this.input.focus();
    }
  }

  render() {
    // eslint-disable-next-line no-unused-vars
    const { type, label, error, success, warning, info, enforceReadonly, preliminary, applyOnBlur, grouped, ...rest } = this.props;
    const { readonly } = this.context;
    // We need a unique id for the link between input and label, even if the user doesn't provide one.
    const id = this.props.id || this.id;

    const wrapperClasses = classNames({
      [styles.wrapper]: true,
      [styles.readonly]: readonly,
      [styles.enforceReadonly]: this.context.enforceReadonly,
      [styles.preliminary]: preliminary,
      [styles.error]: !!error,
      [styles.warning]: !!warning,
      [styles.info]: !!info,
      [styles.success]: !!success,
      [styles.labelOffset]: label
    });

    const inputLabelText = label;

    const inputProps = {
      ...rest,
      type: type || 'text',
      ref: (ref) => { this.input = ref; },
      id,
      readOnly: readonly,
      onClick: this.onClick,
      className: `${styles.input} ${labelStyles.input}`
    };

    // run onChange handler for onBlur event
    if (applyOnBlur === true) {
      inputProps.onBlur = inputProps.onChange;
      inputProps.defaultValue = inputProps.value;
      delete inputProps.onChange;
      delete inputProps.value;
    }

    const isTextArea = (type === 'textarea');

    return (
      <div className={wrapperClasses}>
        {!!inputLabelText && (
          <Label
            htmlFor={id}
            {...{ error, warning, info, success }}
          >
            {inputLabelText}
          </Label>
        )}
        {isTextArea
          ? <textarea {...inputProps} onChange={this.onChangeTextArea} />
          : <input {...inputProps} />
        }
        {!!grouped && (<div className={styles.groupedWrapper}>{grouped}</div>)
        }
        { /* <div className={styles.hook} /> */}
      </div>
    );
  }
}

Textfield.propTypes = {
  type: PropTypes.string,
  label: PropTypes.string,
  error: PropTypes.string,
  warning: PropTypes.bool,
  info: PropTypes.bool,
  success: PropTypes.bool,
  enforceReadonly: PropTypes.bool,
  grouped: PropTypes.node
};

Textfield.defaultProps = {
  type: undefined,
  label: undefined,
  error: undefined,
  warning: undefined,
  info: undefined,
  success: undefined,
  enforceReadonly: undefined,
  grouped: undefined
};

Textfield.contextTypes = {
  readonly: PropTypes.bool,
  enforceReadonly: PropTypes.bool,
  toggleReadonly: PropTypes.func
};
