/*
 * Copyright © 2016-2018 European Support Limited
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import React from 'react';
import ReactDOM from 'react-dom';
import classNames from 'classnames';
import Checkbox from 'react-bootstrap/lib/Checkbox.js';
import Radio from 'sdc-ui/lib/react/Radio.js';
import FormGroup from 'react-bootstrap/lib/FormGroup.js';
import FormControl from 'react-bootstrap/lib/FormControl.js';
import Overlay from 'react-bootstrap/lib/Overlay.js';
import Tooltip from 'react-bootstrap/lib/Tooltip.js';
import Datepicker from 'nfvo-components/datepicker/Datepicker.jsx';

class Input extends React.Component {
    state = {
        value: this.props.value,
        checked: this.props.checked,
        selectedValues: []
    };

    render() {
        /* eslint-disable no-unused-vars */
        const {
            label,
            isReadOnlyMode,
            value,
            onBlur,
            onKeyDown,
            type,
            disabled,
            checked,
            name
        } = this.props;
        const {
            groupClassName,
            isValid = true,
            errorText,
            isRequired,
            overlayPos,
            ...inputProps
        } = this.props;
        const {
            dateFormat,
            startDate,
            endDate,
            selectsStart,
            selectsEnd
        } = this.props; // Date Props
        /* eslint-enable no-unused-vars */
        let wrapperClassName =
            type !== 'radio'
                ? 'validation-input-wrapper'
                : 'validation-radio-wrapper';
        if (disabled) {
            wrapperClassName += ' disabled';
        }
        return (
            <div className={wrapperClassName}>
                <FormGroup
                    className={classNames('form-group', [groupClassName], {
                        required: isRequired,
                        'has-error': !isValid
                    })}>
                    {label &&
                        (type !== 'checkbox' && type !== 'radio') && (
                            <label className="control-label">{label}</label>
                        )}
                    {type === 'text' && (
                        <FormControl
                            bsClass={'form-control input-options-other'}
                            onChange={e => this.onChange(e)}
                            disabled={isReadOnlyMode || Boolean(disabled)}
                            onBlur={onBlur}
                            onKeyDown={onKeyDown}
                            value={value || ''}
                            inputRef={input => (this.input = input)}
                            type={type}
                            data-test-id={this.props['data-test-id']}
                            placeholder={this.props.placeholder || ''}
                        />
                    )}
                    {type === 'number' && (
                        <FormControl
                            bsClass={'form-control input-options-other'}
                            onChange={e => this.onChange(e)}
                            disabled={isReadOnlyMode || Boolean(disabled)}
                            onBlur={onBlur}
                            onKeyDown={onKeyDown}
                            value={value !== undefined ? value : ''}
                            inputRef={input => (this.input = input)}
                            type={type}
                            data-test-id={this.props['data-test-id']}
                        />
                    )}

                    {type === 'textarea' && (
                        <FormControl
                            className="form-control input-options-other"
                            disabled={isReadOnlyMode || Boolean(disabled)}
                            value={value || ''}
                            onBlur={onBlur}
                            onKeyDown={onKeyDown}
                            componentClass={type}
                            onChange={e => this.onChange(e)}
                            inputRef={input => (this.input = input)}
                            data-test-id={this.props['data-test-id']}
                        />
                    )}

                    {type === 'checkbox' && (
                        <Checkbox
                            className={classNames({
                                required: isRequired,
                                'has-error': !isValid
                            })}
                            onChange={e => this.onChangeCheckBox(e)}
                            disabled={isReadOnlyMode || Boolean(disabled)}
                            checked={checked}
                            data-test-id={this.props['data-test-id']}>
                            {label}
                        </Checkbox>
                    )}

                    {type === 'radio' && (
                        <Radio
                            name={name}
                            checked={checked}
                            disabled={isReadOnlyMode || Boolean(disabled)}
                            value={value}
                            onChange={isChecked =>
                                this.onChangeRadio(isChecked)
                            }
                            inputRef={input => (this.input = input)}
                            label={label}
                            data-test-id={this.props['data-test-id']}
                        />
                    )}
                    {type === 'select' && (
                        <FormControl
                            onClick={e => this.optionSelect(e)}
                            className="custom-select"
                            componentClass={type}
                            inputRef={input => (this.input = input)}
                            name={name}
                            {...inputProps}
                            data-test-id={this.props['data-test-id']}
                        />
                    )}
                    {type === 'date' && (
                        <Datepicker
                            date={value}
                            format={dateFormat}
                            startDate={startDate}
                            endDate={endDate}
                            inputRef={input => (this.input = input)}
                            onChange={this.props.onChange}
                            disabled={isReadOnlyMode || Boolean(disabled)}
                            data-test-id={this.props['data-test-id']}
                            selectsStart={selectsStart}
                            selectsEnd={selectsEnd}
                        />
                    )}
                </FormGroup>
                {this.renderErrorOverlay()}
            </div>
        );
    }

    getValue() {
        return this.props.type !== 'select'
            ? this.state.value
            : this.state.selectedValues;
    }

    getChecked() {
        return this.state.checked;
    }

    optionSelect(e) {
        let selectedValues = [];
        if (e.target.value) {
            selectedValues.push(e.target.value);
        }
        this.setState({
            selectedValues
        });
    }

    static getDerivedStateFromProps(props, state) {
        if (state.value === props.value) {
            return null;
        } else {
            return { value: props.value, ...state };
        }
    }

    onChange(e) {
        const { onChange, type } = this.props;
        let value = e.target.value;
        if (type === 'number') {
            if (value === '') {
                value = undefined;
            } else {
                value = Number(value);
            }
        }
        onChange(value);
    }

    onChangeCheckBox(e) {
        let { onChange } = this.props;
        let checked = e.target.checked;
        this.setState({
            checked
        });
        onChange(checked);
    }

    onChangeRadio(isChecked) {
        let { onChange } = this.props;
        this.setState({
            checked: isChecked
        });
        onChange(this.state.value);
    }

    focus() {
        ReactDOM.findDOMNode(this.input).focus();
    }

    renderErrorOverlay() {
        let position = 'right';
        const { errorText = '', isValid = true, type, overlayPos } = this.props;

        if (overlayPos) {
            position = overlayPos;
        } else if (
            type === 'text' ||
            type === 'email' ||
            type === 'number' ||
            type === 'radio' ||
            type === 'password' ||
            type === 'date'
        ) {
            position = 'bottom';
        }

        return (
            <Overlay
                show={!isValid}
                placement={position}
                target={() => {
                    let target = ReactDOM.findDOMNode(this.input);
                    return target.offsetParent ? target : undefined;
                }}
                container={this}>
                <Tooltip
                    id={`error-${errorText.replace(' ', '-')}`}
                    className="validation-error-message">
                    {errorText}
                </Tooltip>
            </Overlay>
        );
    }
}
export default Input;
