import Validator from '../validator';
const validation = (($) => {
    const className = {
        error: 'cd-error',
        success: 'cd-success'
    }
    const DefaultConfig = {list: [
    ]};
    class validation {
        constructor(config) {
            this._config = this._getConfig(config);
            this._addEvent(this._config.list);
        }
        
        _getConfig(config) {
            return $.extend(true,{}, DefaultConfig, config);
        }
        _addEvent(list) {
            for(let i = 0; i < list.length; i++) {
                let obj = list[i];
                let el = $(obj.element);
                if(obj.trigger) {
                    this._addCustomEvent(obj);
                }else {
                    if(el[0].tagName == 'INPUT' || el[0].tagName == 'TEXTAREA') {
                        this._addInputEvent(obj);
                    }
                }
            }
        }
        _addInputEvent(obj) {
            let el = $(obj.element);
            el.on('focus', (ev)=>{
                let target = $(ev.target);
                let val = target.val();
                let tip = this._getTip(obj.tip, el);
                this._resetTip(tip);
                if(obj.rules.maxLength) {
                    let maxLength = obj.rules.maxLength;
                    let countTip = target.parent().find('.J_validationCountTip');
                    if(!countTip.length) {
                        countTip = this._renderCountTip(el, maxLength);
                    }else {
                        countTip.removeClass(className.error).show();
                    }
                }
            });
            el.on('keyup', (ev)=>{
                let target = $(ev.target);
                let val = target.val();
                let errorTypes = target.data('error-types');
                target.removeClass(className.error);
                if(obj.rules.maxLength) {
                    let maxLength = obj.rules.maxLength;
                    let countTip = target.parent().find('.J_validationCountTip');
                    let countNow = countTip.find('.cd-validation-count-now');
                    if(!this._checkItem(el, val, {maxLength: maxLength})) {
                        console.log('maxLength error:', val, val.length);
                        if(val.length > maxLength) {
                            countTip.addClass(className.error);
                        }
                        val = val.substring(0, maxLength);
                        target.val(val);
                    }
                    if(val.length < maxLength) {
                        countTip.removeClass(className.error);
                    }
                    countNow.text(val.length);
                }
                if(obj.rules.type == 'number') {
                    console.log('keyup number');
                }
            });
            el.on('blur', (ev)=>{
                let target = $(ev.target);
                this._checkRules(obj);
                if(obj.rules.maxLength) {
                    let countTip = target.parent().find('.J_validationCountTip');
                    countTip.hide();
                }
                if(obj.rules.type == 'number') {
                }
            })
        }
        _addCustomEvent(obj) {
            let el = $(obj.element);
            el.on(obj.trigger, (ev)=>{
                let target = $(obj.element);
                if(el[0].tagName != 'INPUT' && el[0].tagName != 'TEXTAREA') {
                    obj.value = target.data('val');
                }
                this._checkRules(obj);
            });
        }
        _resetTip(tip) {
            let tipDefaultText = tip.data('defaultText');
            tip.html(tipDefaultText).removeClass(className.error);
        }
        _checkRules(obj) {
            let el = $(obj.element);
            let tip = this._getTip(obj.tip, el);
            let message = obj.message;
            let placeholderText = el.attr('placeholder');
            let val;
            if(el[0].tagName == 'INPUT' || el[0].tagName == 'TEXTAREA') {
                val = obj.value || el.val();
            }else {
                val = obj.value;
            }
            let errorTypes = {};
            let isReady = true;
            for(let key in obj.rules) {
                if(obj.rules.hasOwnProperty(key)) {
                    let rule = {};
                    rule[key] = obj.rules[key];
                    if(!this._checkItem(el, val, rule)) {
                        errorTypes[key] = true;
                        isReady = false;
                    }else {
                        errorTypes[key] = false;
                    }
                }
            }
            if(!isReady) {
                el.removeClass(className.success).addClass(className.error);
                console.log('error:', !val, message, placeholderText);
                if(!val && (el[0].tagName == 'INPUT' || el[0].tagName == 'TEXTAREA')) {
                    this._resetTip(tip);
                }else {
                    tip.removeClass(className.success).addClass(className.error).html(obj.message);
                }
            }else {
                el.removeClass(className.error).addClass(className.success);
                this._resetTip(tip);
            }
            return isReady;
        }
        _renderCountTip(el, maxLength) {
            let countTip = $(`<div class="cd-validation-count J_validationCountTip"><span class="cd-validation-count-now">0</span>/<span class="cd-validation-count-max">${maxLength}</span></div>`);
            let parent = el.parent();
            let parentPosition = parent.css('position');
            if(parentPosition != 'relative') {
                parent.css('position', 'relative');
            }
            countTip.insertAfter(el);
        }
        _checkItem(el, val, rule) {
            let result = Validator([{
                value: val,
                name: el.attr('name'),
                rules: rule
            }]);
            return result.result;
        }
        _getTip(selector, el) {
            let tip = $(selector);
            if(!tip.length) {
                tip = el.data('tip');
            }else {
                tip.data('defaultText', tip.html());
            }
            if(!tip || !tip.length) {
                tip = $(`<span class="cd-validation-tip"></span>`);
                tip.insertAfter(el);
                tip.data('defaultText', '');
            }else {
                tip.addClass('cd-validation-tip');
            }
            el.data('tip', tip);
            return tip;
        }
        _checkNumber(el) {
            let reg = /^[0-9]+$/;
            let str = el.val();
            console.log('_checkNumber:', str)
            if(!reg.test(str)) {
                el.val(str.replace(/[^\d]/g, ''));
            }
        }
        validate(list, callback) {
            let isReady = true;
            if(!list) {
                list = this._config.list;
            }else {
                list = list.concat(this._config.list);
            }
            for(let i = 0; i < list.length; i++) {
                let obj = list[i];
                if(!this._checkRules(obj)) {
                    isReady = false;
                }
            }
            if(callback) {
                console.log('validate isReady:', isReady);
                callback({result: isReady});
            }
            return isReady;
        }
        
        addRules(list) {
            console.log('addRules', list);
            this._config.list = this._config.list.concat(list);
            console.log('addRules', this._config.list);
            this._addEvent(list);
        }
        
        dispose() {
        }
    }
    return validation;
})($);
export default validation;