import React from 'react';
import PropTypes from 'prop-types';
import omit from 'lodash/omit';
import classNames from 'classnames';
import Hint from './Hint/index';

import './field-control.scss';

const formatErrorLabel = ({ error, label, name }) => (
  error.replace(`"${name}"`, `"${label}"`)
);

const propTypes = {
  className: PropTypes.string,
  label: PropTypes.string,
  children: PropTypes.oneOfType([
    PropTypes.node,
    PropTypes.func
  ]),
  mandatory: PropTypes.bool,
  length: PropTypes.number,
  maxLength: PropTypes.number,
  touched: PropTypes.bool,
  error: PropTypes.node,
  hint: PropTypes.node,
  meta: PropTypes.object,
  input: PropTypes.object,
  withoutMarge: PropTypes.bool,
  formatError: PropTypes.func
};

const defaultProps = {
  className: null,
  label: null,
  hint: null,
  children: null,
  mandatory: false,
  length: 0,
  maxLength: null,
  touched: false,
  error: null,
  meta: null,
  input: null,
  withoutMarge: false,
  formatError: formatErrorLabel
};

const FieldControl = ({
  className,
  label,
  hint,
  children,
  mandatory,
  maxLength,
  length,
  meta,
  withoutMarge,
  formatError,
  ...props
}) => {
  const { error, touched } = meta || props;
  const { name } = props.input || props;
  return (
    <div styleName={classNames('form-group', { 'with-marge': !withoutMarge })} className={className}>
      {label &&
      <span styleName="form-label">
        {label}
        {mandatory && <span styleName="mandatory">*</span>}
      </span>
      }
      {typeof children === 'function' ? children(omit(props, ['error', 'touched'])) : children}
      {touched && !!error && <Hint variant="danger">{formatError({ ...props, name, label, error })}</Hint>}
      {
        !!maxLength
        && <Hint>
          Content length :{' '}
          <Hint component="span" variant={length <= maxLength ? 'success' : 'danger'}>
            {length}
          </Hint> / {maxLength} (Max. length)
        </Hint>
      }
      {!!hint && <Hint>{hint}</Hint>}
    </div>
  );
};

FieldControl.propTypes = propTypes;
FieldControl.defaultProps = defaultProps;

export default FieldControl;
