const ARR = "Array";
const NUMBER = "Number";
const STRING = "String";
const OBJECT = "Object";
const UNDEFINED = "Undefined";
const NULL = "Null";
const BOOLEAN = "Boolean";

//  数据类型判断
const Type = {
    typeConstent: {
        'array': ARR,
        'number': NUMBER,
        'string': STRING,
        'object': OBJECT,
        'undefined': UNDEFINED,
        'null': NULL,
        'boolean': BOOLEAN
    },
    tolower: (str)=> {
        if(typeof str !== "string") {
            return "";
        }
        return str.toLowerCase();
    },
    checkType: (el, type)=> {
        type = Type.tolower(type);
        type = Type.typeConstent[type];
        return Object.prototype.toString.call(el) === "[object "+ type +"]";
    }
}

// 判断字符串长度
const regexp = {
    ch: (str)=> {//匹配中文
        if(typeof str !== "string") {
            return "";
        }
        return str.match(/[\u4e00-\u9fa5]/g) || "";
    },
    chLen: function (str) {//中文长度
        return this.ch(str).length;
    },
    strLen: function (str) {//字符串长度(一个中文当作两个英文字母)
        if(typeof str !== "string") {
            return 0;
        }
        return str.length + this.chLen(str);
    }
}

//广度遍历整个数据,递归查找pid
function findNode(data, pid, parentData) {
    const travelWidely = (roots) => {
        const queue = [...roots];
        while (queue.length) {
            const node = queue.shift();
            //打印被遍历的一个节点
            if (node.id === pid) {
                //记录到
                parentData.push(node)
                return node;
            }
            if (node === undefined) {
                return;
            };
            if (node.children && node.children.length) {
                queue.push(...node.children)
            }
        }
    }
    return travelWidely(data)
}
function findAllParentByPid(data, pid, parentData) {
    let thisParent = findNode(data, pid, parentData)
    if (thisParent.hasOwnProperty("pid")) {
        findAllParentByPid(data, thisParent.pid, parentData)
    }
}

const clone = {
    getType: function(obj){
        //tostring会返回对应不同的标签的构造函数
        var toString = Object.prototype.toString;
        var map = {
           '[object Boolean]'  : 'boolean', 
           '[object Number]'   : 'number', 
           '[object String]'   : 'string', 
           '[object Function]' : 'function', 
           '[object Array]'    : 'array', 
           '[object Date]'     : 'date', 
           '[object RegExp]'   : 'regExp', 
           '[object Undefined]': 'undefined',
           '[object Null]'     : 'null', 
           '[object Object]'   : 'object'
       };
       if(obj instanceof Element) {
            return 'element';
       }
       return map[toString.call(obj)];
    },
    deep: function(data){
        var type = clone.getType(data);
        var obj = null;
        if(type === 'array'){
            obj = [];
        } else if(type === 'object'){
            obj = {};
        } else {
            //不再具有下一层次
            return data;
        }
        if(type === 'array'){
            for(var i = 0, len = data.length; i < len; i++){
                obj.push(clone.deep(data[i]));
            }
        } else if(type === 'object'){
            for(var key in data){
                obj[key] = clone.deep(data[key]);
            }
        }
        return obj;
    }
}

const isUndefined = function (str) {
    if(str === 0 || str === "") {
        return false;
    }
    return (Type.checkType(str, 'null') || Type.checkType(str, 'undefined'));
   
}

const Storage = {
    session: {
        get: function (name) {
            return JSON.parse(sessionStorage.getItem(name));
        },
        set: function (name, data) {
            sessionStorage.setItem(name, JSON.stringify(data));
        },
        remove: function (name) {
            sessionStorage.removeItem(name);
        },
        clear: function () {
            sessionStorage.clear();
        }
    }
}

module.exports = {
    checkType: Type.checkType,
    regexp,
    findAllParentByPid,
    clone,
    isUndefined,
    Storage
}