import * as React from 'react';
import * as classNames from 'classnames';
import * as _ from 'lodash';
import {ChangeEvent, PureComponent} from 'react';
import {Col, FormGroup, FormFeedback, FormText, Label} from './../../../../components';
import {InputTextProps} from './InputText';
import {Input} from './Input';

export const mapStringArrayToCommaSeparatedText = (words: string[]) => {
  return words
    .map(word => ` ${word}`)
    .join(',')
    .trim();
};

export const mapStringCommaSeparatedToArray = (text: string) => {
  return text
    .split(',')
    .map(word => word.trim())
    .filter(word => !!word);
};

export interface Props extends InputTextProps {
  onChange: (value: string) => void;
}

export interface State {
  text: string;
}

export class HorizontalFormFieldInput extends PureComponent<Props, {}> {
  state: State;
  private updatedFromInside: boolean;

  constructor(props: Props) {
    super(props);

    const value: any = _.isArray(props.value)
      ? (props.value as Array<string>)
        .map(word => ` ${word}`)
        .join(',')
        .trim()
      : props.value;

    this.state = {
      text: value,
    };
  }

  componentDidUpdate(prevProps: Props) {
    this.updatedFromInside = false;
  }

  render() {
    const {
      helpText,
      label,
      name,
      success,
      successMessage,
      required,
      valueIsArray,
      ...otherProps} = _.omit(this.props, ['className', 'id', 'value', 'onChange']) as Props;

    const labelId = `label-for-${name}`;
    const value = this.getValue();

    return (
      <FormGroup
        row
        aria-labelledby={labelId}
        aria-describedby={name}
      >
        <Label className="col-12" sm={3} id={labelId} for={name}>
          {label}
          {required && ' *'}
        </Label>

        <Col className="col-12" sm={9}>
          <Input
            name={name}
            id={name}
            value={value}
            onChange={this.handleChange}
            {...otherProps as any}
          />

          {success && (
            <FormFeedback>{successMessage}</FormFeedback>
          )}

          {!!helpText && (
            <FormText tag="span" color="muted">{helpText}</FormText>
          )}
        </Col>
      </FormGroup>
    );
  }

  getValue = () => {
    let value = this.updatedFromInside ? this.state.text : this.props.value;

    if (_.isArray(value)) {
      value = mapStringArrayToCommaSeparatedText(this.props.value as string[]);
    }

    return value;
  }

  handleChange = (e: ChangeEvent<HTMLInputElement>) => {
    const {value} = e.target;
    const {valueIsArray} = this.props;

    this.setState({text: e.target.value});

    this.updatedFromInside = true;

    const fieldValue: any = valueIsArray ? mapStringCommaSeparatedToArray(value) : value;

    this.props.onChange(fieldValue);
  }
}
