import React from 'react';
import PropTypes from 'prop-types';
import { createNamespace } from '../../tools/namingTools';
import { TEXT, NUMBER, EMAIL, TEL, SEARCH } from '../../constants/inputTypes';

import './styles/Input.scss';

const n = createNamespace('Input');
const inputTypes = [TEXT, NUMBER, EMAIL, TEL, SEARCH];

const Input = ({
    type,
    name,
    label,
    error,
    inputRef,
    hiddenLabel,
    required,
    placeholder,
    hint,
    addon,
    defaultValue,
    ...otherProps
}) => {
    const inputType = inputTypes.includes(type) ? type : TEXT;

    const controlModifier = [
        type,
        addon && 'with-addon',
        error && 'error'
    ];
    const labelTextModifier = hiddenLabel ? 'hidden' : null;

    const renderInput = (
        <input
            id={name}
            type={inputType}
            name={name}
            ref={inputRef}
            placeholder={placeholder}
            defaultValue={defaultValue}
            required={required}
            {...otherProps}
            {...n('control', controlModifier).props}
        />
    );

    return (
        <div {...n('group').props}>
            <label {...n('label').props} htmlFor={name}>
                <span {...n('text', labelTextModifier).props}>{label}</span>
                {addon ? (
                    <span {...n('controlWrapper', controlModifier).props}>
                        <span {...n('addon').props}>{addon}</span>
                        {renderInput}
                    </span>
                ) : renderInput}
            </label>
            {hint && (
                <span {...n('hint').props}>{hint}</span>
            )}
            {error && (
                <span {...n('error').props} aria-live="assertive">
                    {error}
                </span>
            )}
        </div>
    );
};

Input.propTypes = {
    type: PropTypes.oneOf(inputTypes),
    name: PropTypes.string.isRequired,
    label: PropTypes.string,
    error: PropTypes.string,
    required: PropTypes.bool,
    defaultValue: PropTypes.string,
    placeholder: PropTypes.string,
    hint: PropTypes.string,
    addon: PropTypes.string,
    inputRef: PropTypes.func,
    hiddenLabel: PropTypes.bool
};

Input.defaultProps = {
    type: TEXT,
    label: '',
    error: null,
    inputRef: null,
    required: false,
    defaultValue: '',
    placeholder: null,
    hint: null,
    addon: null,
    hiddenLabel: false
};

export default Input;
