export default class Utils {
    static toDepthObject(obj) {
        var target = {};
        for (var key in obj) {
            var keyArr = key.split("_"); //以下划线或分割
            var tempobj = target;
            for (var i = 0; i < keyArr.length - 1; i++) {
                if (tempobj[keyArr[i]])
                    tempobj = tempobj[keyArr[i]];
                else {
                    tempobj[keyArr[i]] = {};
                    tempobj = tempobj[keyArr[i]];
                }
            }
            //给叶子元素赋值
            tempobj[keyArr[keyArr.length - 1]] = obj[key];
        }
        return target;
    }
    static flatObject(obj, target, pkey) {
        target = target || {};
        for (var key in obj) {
            var nkey = pkey ? pkey + "_" + key : key;
            if (!obj[key])
                target[nkey] = obj[key];
            else if (obj[key] instanceof Array)
                target[nkey] = obj[key];
            else if (obj[key] instanceof Date)
                target[nkey] = obj[key];
            else if (typeof obj[key] == "object")
                /**
                 * IStream类型 
                 * { 
                 *   empty: true
                 *   keepsort: false
                 *   rows: []
                 * }
                */
                if (Object.keys(obj[key]).length === 3 && obj[key].hasOwnProperty("empty") && obj[key].hasOwnProperty("keepsort") && obj[key].hasOwnProperty("rows")) {
                    target[nkey] = obj[key];
                } else {
                    Utils.flatObject(obj[key], target, nkey); //递归赋值
                }
            else
                target[nkey] = obj[key];
        }
        return target;
    }
    static copyValueFromVO(model, vo) {
        var target = model;
        for (var key in vo) {
            var keyArr = key.split("_"); //以下划线或分割
            var tempobj = target;
            for (var i = 0; i < keyArr.length - 1; i++) {
                if (tempobj[keyArr[i]])
                    tempobj = tempobj[keyArr[i]];
                else {
                    tempobj = null;
                    break;
                }
            }
            //给叶子元素赋值
            if (tempobj) {
                let leafProp = keyArr[keyArr.length - 1];
                if (tempobj.hasOwnProperty(leafProp)
                    || "pageId" == leafProp  //对pageId开放判断。
                )
                    tempobj[leafProp] = vo[key];
            }
        }
        return target;
    }

    static showXml(str){
        var text = str
    
        //去掉多余的空格
        text = '\n' + text.replace(/(<\w+)(\s.*?>)/g,function($0, name, props)
        {
            return name + ' ' + props.replace(/\s+(\w+=)/g," $1");
        }).replace(/>\s*?</g,">\n<");
    
        //把注释编码
        text = text.replace(/\n/g,'\r').replace(/<!--(.+?)-->/g,function($0, text)
        {
            var ret = '<!--' + escape(text) + '-->';
            return ret;
        }).replace(/\r/g,'\n');
    
        //调整格式
        var rgx = /\n(<(([^\?]).+?)(?:\s|\s*?>|\s*?(\/)>)(?:.*?(?:(?:(\/)>)|(?:<(\/)\2>)))?)/mg;
        var nodeStack = [];
        var output = text.replace(rgx,function($0,all,name,isBegin,isCloseFull1,isCloseFull2 ,isFull1,isFull2){
            var isClosed = (isCloseFull1 == '/') || (isCloseFull2 == '/' ) || (isFull1 == '/') || (isFull2 == '/');
            var prefix = '';
            if(isBegin == '!')
            {
                prefix = Utils.getPrefix(nodeStack.length);
            }
            else 
            {
                if(isBegin != '/')
                {
                    prefix = Utils.getPrefix(nodeStack.length);
                    if(!isClosed)
                    {
                        nodeStack.push(name);
                    }
                }
                else
                {
                    nodeStack.pop();
                    prefix = Utils.getPrefix(nodeStack.length);
                }
    
            }
                var ret =  '\n' + prefix + all;
                return ret;
        });
    
        var prefixSpace = -1;
        var outputText = output.substring(1);
    
        //把注释还原并解码,调格式
        outputText = outputText.replace(/\n/g,'\r').replace(/(\s*)<!--(.+?)-->/g,function($0, prefix,  text)
        {
            if(prefix.charAt(0) == '\r')
                prefix = prefix.substring(1);
            text = unescape(text).replace(/\r/g,'\n');
            var ret = '\n' + prefix + '<!--' + text.replace(/^\s*/mg, prefix ) + '-->';
            return ret;
        });
        //alert(outputText);
        
        outputText=	outputText.replace(/\s+$/g,'').replace(/\r/g,'\r\n');
        
        
        return outputText
        
    
    }
    
    static getPrefix(prefixIndex)
    {
        var span = '    ';
        var output = [];
        for(var i = 0 ; i < prefixIndex; ++i)
        {
            output.push(span);
        }
       
        return output.join('');
    }

    /**
     * 执行checkAll之后根据返回的错误信息定位
     * @param {Object} fieldErrors 错误信息
     * @param {Array} formFields 表单字段
     * @returns El-Tab实例
     */
    static positioningErrorMsg(fieldErrors, formFields) {
        if (Object.keys(fieldErrors).length === 0) {
            return null;
        }
        let firstErrorItem = null
        // 顺序
        for (let i = 0; i < formFields.length; i++) {
            const field = formFields[i];
            const fieldError = fieldErrors[field.prop];
            if (fieldError) {
                field.validateState  = 'error';
                field.validateMessage = fieldError;
                if (!firstErrorItem) {
                    firstErrorItem = field
                }
            }                
        }
        let firstErrorTab = null, collapsePanel = null
        if (firstErrorItem) {
            let parentVC = firstErrorItem
            while(!firstErrorTab) {
                const vcName = parentVC.$options.componentName
                // 没有Tabs的表单
                if (vcName === "ElForm") {
                    break;
                }
                if (vcName === "ElTabPane") {
                    firstErrorTab = parentVC
                    break;
                }
                if (vcName === "ElCollapseItem") {
                    collapsePanel = parentVC;
                }
                parentVC = parentVC.$parent;
            }
            if (firstErrorTab) {
                const tabs = firstErrorTab.$parent
                tabs.currentName = firstErrorTab.name
            }
            if (collapsePanel && collapsePanel.collapse.activeNames.indexOf(collapsePanel.name) < 0) {
                collapsePanel.collapse.activeNames.push(collapsePanel.name)
            }
            setTimeout(() => {
                // 滚动到指定节点
                firstErrorItem.$el.scrollIntoView({
                    // 值有start,center,end,nearest,当前显示在视图区域中间
                    block: 'center', 
                    // 值有auto、instant,smooth,缓动动画(当前是慢速的)
                    behavior: 'smooth' 
                })
            }, 0)
        }
        return firstErrorTab;
    }

    /**
     * 表单自身的validate方法执行后,错误提示定位
     * @param {Array} formFields 表单字段
     * @returns El-Tab实例
     */
    static formValidateTips(formFields) {
        let firstErrorItem = null
        // 顺序
        for (let i = 0; i < formFields.length; i++) {
            const field = formFields[i];
            if (field.validateState === 'error') {
                firstErrorItem = field
                break;
            }                
        }
        let firstErrorTab = null, collapsePanel = null
        if (firstErrorItem) {
            let parentVC = firstErrorItem
            while(!firstErrorTab) {
                const vcName = parentVC.$options.componentName
                // 没有Tabs的表单
                if (vcName === "ElForm") {
                    break;
                }
                if (vcName === "ElTabPane") {
                    firstErrorTab = parentVC
                    break;
                }
                if (vcName === "ElCollapseItem") {
                    collapsePanel = parentVC;
                }
                parentVC = parentVC.$parent;
            }
            if (firstErrorTab) {
                const tabs = firstErrorTab.$parent
                tabs.currentName = firstErrorTab.name
            }
            if (collapsePanel && collapsePanel.collapse.activeNames.indexOf(collapsePanel.name) < 0) {
                collapsePanel.collapse.activeNames.push(collapsePanel.name)
            }
            setTimeout(() => {
                // 滚动到指定节点
                firstErrorItem.$el.scrollIntoView({
                    // 值有start,center,end,nearest,当前显示在视图区域中间
                    block: 'center', 
                    // 值有auto、instant,smooth,缓动动画(当前是慢速的)
                    behavior: 'smooth' 
                })
            }, 0)
        }
        return firstErrorTab;
    }

    static defaultFunction(rule, value, callback){
        this.executeNotify().then(res => {
            if (res.respCode == SUCCESS){
                const data = res.data;
                Utils.copyValueFromVO(this.model, data)
                if (typeof callback === "function") {
                    callback()
                }
            }
        })
    }

    static reflectCheck(key){
        return async function(rule, value, callback){
            //调用具体的check
            const res = await this.executeCheck(key)
            // if (res.respCode == SUCCESS){
                
            // }
            if (Object.hasOwnProperty.call(res.fieldErrors, key)) {
                callback(new Error(res.fieldErrors[key]))
            } else {
                callback();
            }
        }
    }

    static generateUUID() {
        console.log(111);
        var d = new Date().getTime();
        console.log(2222);
        if (window.performance && typeof window.performance.now === "function") {
            d += performance.now(); //use high-precision timer if available
        }
        var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
            var r = (d + Math.random() * 16) % 16 | 0;
            d = Math.floor(d / 16);
            return (c == 'x' ? r : (r & 0x3 | 0x8)).toString(16);
        });
        return uuid;
    }

    static copyCustomFromModel(customModel, model){
        for(let key in customModel){
            if(typeof customModel[key] == "object"){
                this.copyCustomFromModel(customModel[key], model[key])
            }else{
                customModel[key] = model[key]
            }
        }
    }
    
}