//工具
define(['jquery'], function ($) {
    /**
     * 扁平数组转换为树形结构
     * @param {*} list
     */
    function listToTree(list) {
        var map = {}, node, tree = [], i;
        for (i = 0; i < list.length; i++) {
            map[list[i].id] = list[i];
            list[i].children = [];
        }
        for (i = 0; i < list.length; i += 1) {
            node = list[i];
            if (node.pid !== '-1') {
                map[node.pid].children.push(node);
            } else {
                tree.push(node);
            }
        }
        return tree;
    }

    /**
     * 树形结构转换为扁平数组
     * @param {*} tree
     */
    function treeToList(tree) {
        var queen = [];
        var out = [];
        queen = queen.concat(tree);
        while (queen.length) {
            var first = queen.shift();
            if (first.children) {
                queen = queen.concat(first.children)
                delete first['children'];
            }

            out.push(first);
        }
        return out;
    }

    /**
     * 查找树的指定节点
     * @param {String|Number} value 节点的值
     * @param {Array} tree 树形结构
     * @param {String} attr 匹配值的属性
     * @param {String} childAttr 匹配子节点数组的属性
     */
    function findTreeNode(value, tree, attr = 'id', childAttr = 'children') {
        if (!(tree instanceof Array)) {
            console.error('tree: 请传入树形数组进行过滤！')
            return null
        }
        if (tree.length === 0) return

        for (let i = 0; i < tree.length; i++) {
            const item = tree[i]

            if (item[attr] === value) {
                // 如果找到， 则跳出
                return item
            }
            if (item[childAttr]) {
                const node = findTreeNode(value, item[childAttr], attr, childAttr)
                if (node) {
                    // 找到即返回
                    return node
                }
            }
        }

        return null
    }

    /**
     * 查找树的满足条件的节点
     * @param {String|Number} value 节点的值
     * @param {Array} tree 树形结构
     * @param {String} attr 匹配值的属性
     * @param {String} childAttr 匹配子节点数组的属性
     */
    function findTreeList(value, tree, attr = 'id', childAttr = 'children') {
        let array = [];
        if (!(tree instanceof Array)) {
            console.error('tree: 请传入树形数组进行过滤！')
            return array
        }
        if (tree.length === 0) return array;

        for (let i = 0; i < tree.length; i++) {
            const item = tree[i]

            if (item[attr] === value) {
                // 如果找到， 则跳出
                array.push(item);
            }
            if (item[childAttr]) {
                const nodes = findTreeList(value, item[childAttr], attr, childAttr)
                if (nodes) {
                    for (let j = 0; j < nodes.length; j++) {
                        array.push(nodes[j]);
                    }
                }
            }
        }
        return array;
    }

    /**
     * 模糊搜索树中满足条件的节点
     * @param {String|Number} value 节点的值
     * @param {Array} tree 树形结构
     * @param {String} attr 匹配值的属性
     * @param {String} childAttr 匹配子节点数组的属性
     */
    function searchTreeList(value, tree, attr = 'id', childAttr = 'children') {
        let array = [];
        if (!(tree instanceof Array)) {
            console.error('tree: 请传入树形数组进行过滤！')
            return array
        }
        if (value === '' || tree.length === 0) return array;

        for (let i = 0; i < tree.length; i++) {
            const item = tree[i]

            if (item[attr].indexOf(value) > -1) {
                // 如果找到， 则跳出
                array.push(item);
            }
            if (item[childAttr]) {
                const nodes = searchTreeList(value, item[childAttr], attr, childAttr)
                if (nodes) {
                    for (let j = 0; j < nodes.length; j++) {
                        array.push(nodes[j]);
                    }
                }
            }
        }
        return array;
    }

    return {
        listToTree: listToTree,
        treeToList: treeToList,
        findTreeNode: findTreeNode,
        findTreeList: findTreeList,
        searchTreeList: searchTreeList
    }
})
