import React, {Component} from 'react';
import shortid from 'shortid';
import MaskedInput, {conformToMask} from 'react-text-mask';
import classNames from 'classnames';

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

@findParentForm
export default class File extends Component {
    id = shortid();

    state = {
        focus: false,
        error: null,
        success: null,
        value: this.props.value
    };

    get _value() {
        return this.state.value;
    }

    set(value) {
        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 (!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;
        }
    }

    __onChange = (e) => {
        let files = e.target.files;
        if (!files.length) {
            files = null;
        }
        this.setState({
            value: files,
        }, () => {
            let {onChange} = this.props;
            if (onChange) {
                onChange(files);
            }
            this.validate();
        });

    };

    getInputText() {
        let {value} = this.state;
        let {multiple} = this.props;
        if (!value) {
            if (multiple) {
                return 'Select files...'
            } else {
                return 'Select a file...'
            }
        } else {
            if (value.length > 1) {
                return `Number of files: ${value.length}`
            } else {
                return value[0].name
            }
        }
    }

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

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

        if (props.validate) {
            delete props.validate;
        }

        return <div
            className="sbxFormField"
        >
            {label && <label
                htmlFor={this.id}
                className="sbxFormField__label"
            >
                {label}
            </label>}
            <input
                {...props}
                id={this.id}
                ref={e => this.input = e}
                multiple={this.props.multiple}
                name={this.props.name}
                style={{display: 'none'}}
                type="file"
                onChange={this.__onChange}
            />
            <label
                tabIndex={0}
                htmlFor={this.id}
                className={classNames({
                    'sbxFormField__input': true,
                    'sbxFormField__inputFile': true,
                    'sbxFormField__input_invalid': error,
                    'sbxFormField__input_valid': success,
                    [props.className]: !!props.className
                })}
            >
                {this.getInputText()}
                {/*<div className="sbxFormField__fileBrowse">*/}
                    {/*Browse*/}
                {/*</div>*/}
            </label>
            {error && <div
                className='sbxFormField__invalidFeedback'
            >
                {error}
            </div>}
        </div>
    }
}
