import React, {Component} from 'react';
import shortid from 'shortid';
import classNames from 'classnames';

import {validations, getValidator} from '../../helpers/helpers';
import findParentForm from '../../helpers/findParentForm';

@findParentForm
export default class Checkbox extends Component {
    type = 'checkbox';

    id = shortid();

    state = {
        focus: false,
        error: null,
        success: null,
    };

    get _value() {
        if(this.input.value){
            return this.input.checked && this.input.value
        }else{
            return this.input.checked;
        }
    }

    set(value) {
        if (this.props.mask) {
            value = conformToMask(
                value.toString(),
                this.props.mask,
                {
                    guide: false,
                    previousConformedValue: true
                }
            ).conformedValue;
        }
        this.input.value = value;
        if (this.props.onChange) {
            this.props.onChange(value);
        }
    }

    componentWillReceiveProps(nextProps) {
        if (this.props.value !== nextProps.value) {
            this.input.value = nextProps.value;
        }
    }

    componentDidMount() {
        if (this.props.value || this.props.value === 0) {
            this.input.value = this.props.value;
        }
    }

    validate() {
        let {_value: value} = this;
        let {validate} = this.props;
        let promises = [];
        if(!value){
            value = undefined
        }
        if (!validate) {
            this.setState({success: true, error: null});
            return Promise.resolve(value);
        } else if ({}.toString.call(validate) === '[object Function]') {
            promises.push(validate(value));
        } else {
            for (let key in validate) {
                let valid = null;
                let error = validate[key].error || 'ERROR';
                if (validate[key].custom) {
                    valid = validate[key].custom(value);
                } else {
                    let validator = getValidator(key);
                    valid = validations[validator.name](value, ...validator.args);
                }
                if (valid) {
                    promises.push(Promise.resolve(value))
                } else {
                    promises.push(Promise.reject(error));
                    break;
                }
            }
        }
        return Promise.all(promises).then(() => {
            this.setState({success: true, error: null});
            return Promise.resolve(value);
        }).catch((error) => {
            this.setState({success: null, error});
            return Promise.reject(error);
        })
    }

    __setValue(value) {
        let {mask} = this.props;
        if (mask) {
            value = conformToMask(
                value + "",
                mask,
            );
            this.input.value = value.conformedValue;
        } else {
            this.input.value = value;
        }
    }

    __onFocus() {
        this.setState({focus: true})
    }

    __onBlur = (e) => {
        if (this.props.onBlur) {
            this.props.onBlur(e);
        }
        this.validate();
    };

    __onChange = (e) => {
        let {onChange} = this.props;
        if (onChange) {
            onChange(e.target.checked, e);
        }
        this.validate();
    };

    render() {
        let {error, success} = this.state;
        let {
            label,
            validate,
        } = this.props;
        const isRequired = !!validate && !!validate['isRequired'];

        let props = {...this.props};

        delete props.validate;
        delete props.children;


        return <div className="sbxFormField">
            <div
                className={classNames({
                    'sbxFormField__checkbox': true,
                    'sbxFormField__checkbox_invalid': error,
                    'sbxFormField__checkbox_valid': success,
                    [props.className]: !!props.className
                })}
            >
                <input
                    {...props}
                    type="checkbox"
                    id={this.id}
                    ref={e => this.input = e}
                    onChange={this.__onChange}
                    onBlur={this.__onBlur}
                />{' '}
                {label && <label
                    tabIndex={0}
                    htmlFor={this.id}
                >
                    {label}
                </label>}
            </div>
            {error && <div
                className='sbxFormField__invalidFeedback'
            >
                {error}
            </div>}
        </div>
    }
}
