'use strict';

import React from 'react';
import PropTypes from 'prop-types';
import classnames from 'classnames';
import BSFormGroup from 'react-bootstrap/lib/FormGroup';
import ControlLabel from 'react-bootstrap/lib/ControlLabel';
import HelpBlock from 'react-bootstrap/lib/HelpBlock';
import {FormControl} from './FormControl';
import {Block} from '../Block';
import _ from 'lodash';

export class FormGroup extends FormControl {
    static initialAriaDescId = Date.now();
    static propTypes = {
        ...FormControl.propTypes,
        groupClassName: PropTypes.string,
        ariaDescId: PropTypes.string,
        noOffset: PropTypes.bool
    };

    static defaultProps = {
        ...FormControl.defaultProps,
        ariaDescId: null
    };

    constructor(props, context) {
        super(props, context);
        this.ariaDescId = `descId-${FormGroup.initialAriaDescId++}`;
    }

    getAriaDescProps(hasError) {
        return hasError ? {'aria-describedby': this.props.ariaDescId || this.ariaDescId} : {};
    }

    getValue() {
        if (this.refs.control) {
            return this.refs.control.getValue();
        }
        return null;
    }

    getInputDOMNode() {
        if (this.refs.control) {
            return this.refs.control.getInputDOMNode();
        }
        return null;
    }

    controlLabelFallback() {
        return true;
    }

    renderLabel() {
        let {
            label,
            controlLabel,
            labelClassName,
            disabled,
            readOnly,
            id,
            htmlFor
        } = this.getPropsFromContext(this.props);

        let controlLabelNode = null;

        if (!controlLabel && label && this.controlLabelFallback()) {
            controlLabel = label;
        }

        if (controlLabel) {
            controlLabelNode = readOnly ? (
                <Block condensed className={labelClassName}>
                    <strong>{controlLabel}</strong>
                </Block>
            ) : (
                <ControlLabel
                    htmlFor={htmlFor || id}
                    data-test-automation-id="label"
                    className={classnames(labelClassName, {'disabled-label': disabled})}>
                    {controlLabel}
                </ControlLabel>
            );
        }

        return controlLabelNode;
    }

    render() {
        let {
            validationState,
            bsStyle,
            controlId,
            help,
            wrapperClassName,
            groupClassName,
            onChange, // to prevent double onChange -- extract and don't use in BSFormGroup props,
            noOffset, // no bottom Offset
            ...props // properly handle old-style props
        } = this.getPropsFromContext(this.props);

        onChange = null;

        if (!validationState && bsStyle) {
            validationState = bsStyle;
        }

        if (!controlId) {
            controlId = this.props.testAutomationId;
        }

        groupClassName = classnames(groupClassName, {'rc-form-group-noOffset': noOffset});
        let control = wrapperClassName ? (
            <div className={wrapperClassName}>{this.renderInput(help)}</div>
        ) : (
            this.renderInput(help)
        );

        // we have to remove tabIndex and id from group props, otherwise Filter for ex. will have 2 focusable elements
        const {tabIndex, id, className, ...groupProps} = this.getSafeProps(props);

        const filteredProps = this.filterGroupProps(groupProps);
        return (
            <BSFormGroup
                validationState={validationState}
                data-test-automation-id={this.props.testAutomationId}
                controlId={controlId}
                className={classnames(className, groupClassName)}
                {...filteredProps}>
                {this.renderLabel()}

                {control}

                {help ? (
                    <HelpBlock
                        id={this.props.ariaDescId || this.ariaDescId}
                        data-test-automation-id="helpBlock">
                        {help}
                    </HelpBlock>
                ) : (
                    help
                )}
            </BSFormGroup>
        );
    }

    filterGroupProps(props) {
        const attrs = ['name', 'value', 'aria-label', 'aria-hidden', 'aria-checked', 'removeName'];
        let cloneProps = _.clone(props);

        attrs.forEach(item => {
            delete cloneProps[item];
        });

        return cloneProps;
    }

    renderInput() {
        return this.props.children;
    }
}
