import PropTypes from 'prop-types';
import React from 'react';
import './index.css';

const NAME_PREFIX = 'button-group_';

function isTarget(event, element) {
    return event.target === element || event.target === element.parentNode;
}

const ButtonGroup = React.createClass({

    getInitialState() {
        const { val, name } = this.props;

        return {
            name: name || `x${Math.floor(1e8 * Math.random())}`,
            value: this._getAggregateValue(val ? [val] : []),
        };
    },

    componentWillReceiveProps(nextProps) {
        if (nextProps.name !== this.state.name) {
            this.setState({ name: nextProps.name });
        }
    },

    _getAggregateValue(values) {
        if (values === undefined) {
            const siblings = document.querySelectorAll(`input[data-name="${NAME_PREFIX + this.state.name}"]:checked`);

            values = [].map.call(siblings, checkbox => checkbox.value);
        }

        if (!values) {
            values = [];
        }

        switch (this.props.mode) {
            case 'single':
            case 'optional-single':
                return values[0];
            case 'optional':
                return JSON.stringify(values);
        }
    },

    _handleValueChange(event) {
        const { mode, onChange } = this.props;

        if (mode === 'optional') {
            return;
        }

        const siblings = document.querySelectorAll(`input[data-name="${NAME_PREFIX + this.state.name}"]`);

        [].forEach.call(siblings, checkbox => {
            if (isTarget(event, checkbox)) {
                switch (mode) {
                    case 'single':
                        if (!checkbox.checked) {
                            checkbox.checked = true;
                        }
                        break;
                }
            } else {
                switch (mode) {
                    case 'single':
                    case 'optional-single':
                        if (checkbox.checked) {
                            checkbox.checked = false;
                        }
                        break;
                }
            }
        });

        const nextVal = this._getAggregateValue();

        this.setState({ value: nextVal });

        if (onChange) {
            onChange({ val: nextVal });
        }
    },

    _handleAggregateValueChange(event) {
        this.setState({ value: event.target.value });
    },

    _renderButtons() {
        const { options, val } = this.props;

        return options.map((option, index) => (
            <label className="ui-button-group__label" key={index}>
                <input
                    type="checkbox"
                    className="ui-button-group__checkbox"
                    data-name={NAME_PREFIX + this.state.name}
                    defaultChecked={option.val === val}
                    value={option.val}
                    onChange={this._handleValueChange}
                />
                <span className="ui-button-group__caption">
                    {option.text}
                </span>
            </label>
        ));
    },

    render() {
        const { options, className } = this.props;

        if (!options || !options.length) {
            return null;
        }

        return (
            <span className={className}>
                <input
                    type="hidden"
                    name={this.state.name}
                    value={this.state.value || ''}
                    onChange={this._handleAggregateValueChange}
                />
                {this._renderButtons()}
            </span>
        );
    },

});

// @if NODE_ENV='development'
ButtonGroup.propTypes = {
    val: PropTypes.any,
    name: PropTypes.string,
    mode: PropTypes.oneOf(['single', 'optional-single', 'optional']),
    className: PropTypes.string,
    onChange: PropTypes.func,
};
// @endif

ButtonGroup.defaultProps = {
    mode: 'optional',
    className: 'ui-button-group',
};

export default ButtonGroup;
