export class SideNavController {
    constructor($window, $state, $scope) {
        'ngInject';

        this.$window = $window;
        this.$state = $state;

        var $ctrl = this;
        $ctrl.$onInit = function () {
            $ctrl.helloText = $ctrl.helloText || '您好，';
            this.initMenus();
        };

        $scope.$watch('$ctrl.minus', (newValue) => {
            this.setMinus(newValue);

            if (!newValue) {
                this.openActiveMenu();
            }
        });

        $scope.$watch('$ctrl.menus', (newValue) => {
            if (newValue && newValue.length > 0) {
                this.populateMenusLevel();
                this.openActiveMenu();
            }
        });

        // Active menu when url changed
        var self = this;
        $scope.$watch(function () {
            return self.$state.current.url;
        }, (newValue, oldValue) => {
            if (newValue && newValue !== oldValue) {
                if (!this.minus) {
                    this.openActiveMenu();
                }
            }
        });
    }

    setMinus(minus) {
        if (minus) {
            angular.element('cil-side-nav .side-nav-wrapper').css('width', '70px');
            angular.element('cil-side-nav .side-nav-wrapper').css('font-size', '16px');
            angular.element('cil-side-nav .side-nav-wrapper .menu-item:first').css('margin-top', '8vh');
            angular.element('.second-level-menu-item, .third-level-menu-item').removeClass('animate-if');

            angular.element('cil-side-nav .side-nav-wrapper').css('background', 'linear-gradient(0deg, rgb(106, 75, 250) 10%, rgb(75, 149, 217) 20%, rgb(44, 197, 197) 70%)');
            angular.element('.menu-item').addClass('minus-menu-item').removeClass('normal-menu-item');

            this.collapseAll();
        } else {
            angular.element('cil-side-nav .side-nav-wrapper').css('width', '220px');
            angular.element('cil-side-nav .side-nav-wrapper').css('font-size', '13px');
            angular.element('cil-side-nav .side-nav-wrapper .menu-item:first').css('margin-top', '0vh');
            angular.element('.second-level-menu-item, .third-level-menu-item').removeClass('animate-if').addClass('animate-if');

            angular.element('cil-side-nav .side-nav-wrapper').css('background', 'url("' + this.bg + '") no-repeat');
            angular.element('cil-side-nav .side-nav-wrapper').css('background-size', '100% 100%');

            angular.element('.menu-item').removeClass('minus-menu-item').addClass('normal-menu-item');
        }
    }

    initMenus() {
        setTimeout(() => {
            if (this.bg) {
                angular.element('cil-side-nav .side-nav-wrapper').css('background', 'url("' + this.bg + '") no-repeat');
                angular.element('cil-side-nav .side-nav-wrapper').css('background-size', '100% 100%');
            }
            this.setMinus(this.minus);

            this.openActiveMenu();
        }, 0);
    }

    openActiveMenu() {
        this.populateMenusLevel();

        for (let i = 0; i < this.menus.length; i++) {
            const rootNode = this.menus[i];
            let usecases = [];
            if (this.$state.current.data && this.$state.current.data.usecase) {
                usecases = this.$state.current.data.usecase;
            }

            let currentRouteMenu = this.findMenu(rootNode, this.$state.current.name, usecases);
            if (currentRouteMenu) {
                this.toggleMenuOrNavigate(currentRouteMenu, null, this.$state.current.name);
                break;
            }
        }
    }

    collapseAll() {
        this.menus.forEach(rootNode => {
            rootNode.expanded = false;
            let queue = [];
            queue.push(rootNode);

            while (queue.length > 0) {
                let node = queue.shift();
                node.expanded = false;

                if (node && node.children) {
                    node.children.forEach(element => {
                        queue.push(element);
                    });
                }
            }
        });
    }

    toggleMenuOrNavigate(menu, $event, currentRouteName) {
        if ($event) {
            $event.stopPropagation();
        }

        if (this.minus && menu.level === 0) {
            this.minus = !this.minus;
        }

        menu.expanded = currentRouteName !== undefined || !menu.expanded;
        this.menus.forEach(rootNode => {
            if (!this.isContains(rootNode, menu)) {
                this.toggleOtherMenus(rootNode, false, menu);
            } else {
                this.toggleOtherMenus(rootNode, true, menu);
            }
        });

        if (menu.active) {
            console.log('menu is already active');
            return;
        }

        menu.active = currentRouteName !== undefined || !menu.active;
        this.menus.forEach(rootNode => {
            if (this.isContains(rootNode, menu)) {
                this.activeParents(rootNode, true, menu);
            } else {
                this.activeParents(rootNode, false, menu);
            }
        });

        if (currentRouteName) {
            this.$state.go(currentRouteName);
        } else if (menu.route && (!menu.children || menu.children.length === 0)) {
            if (menu.route.indexOf('https://') > -1 || menu.route.indexOf('http://') > -1) {
                window.location.href = menu.route;
            } else {
                this.$state.go(menu.route);
            }
        }
    }

    findMenu(rootNode, currentRouteName, usecases) {
        let queue = [];
        queue.push(rootNode);

        while (queue.length > 0) {
            let node = queue.shift();
            if (node.routeName && (node.routeName.indexOf(currentRouteName) > -1 || usecases.indexOf(node.id) > -1)) {
                console.log(this.$state.current);
                console.log('currentRouteName = ' + currentRouteName);
                console.log(node.routeName);
                console.log(usecases);
                return node;
            }

            if (node && node.children) {
                node.children.forEach(element => {
                    queue.push(element);
                });
            }
        }

        return null;
    }

    populateMenusLevel() {
        if (this.menus && this.menus.length > 0 && this.menus[0].level === undefined) {
            this.menus.forEach(rootNode => {
                this.populateNodeLevel(rootNode);
            });
        }
    }

    populateNodeLevel(rootNode) {
        let queue = [];
        let l = 0;
        queue.push({
            node: rootNode,
            level: l
        });

        while (queue.length > 0) {
            let nodeObj = queue.shift();
            nodeObj.node.level = nodeObj.level;
            if (nodeObj.node && nodeObj.node.children) {
                l++;
                nodeObj.node.children.forEach(element => {
                    queue.push({
                        node: element,
                        level: l
                    });
                });
            }
        }
    }

    activeParents(rootNode, active, menu) {
        let queue = [];
        queue.push(rootNode);

        while (queue.length > 0) {
            let node = queue.shift();
            if (node.level >= menu.level && node.id !== menu.id) {
                node.active = false;
            } else {
                if (this.isContains(node, menu)) {
                    node.active = active;
                } else {
                    node.active = false;
                }
            }

            if (node && node.children) {
                node.children.forEach(element => {
                    queue.push(element);
                });
            }
        }
    }

    isContains(rootNode, sourceNode) {
        let root = Object.assign({}, rootNode);
        if (root.id === sourceNode.id) {
            return true;
        }

        let queue = [];
        queue.push(root);

        while (queue.length > 0) {
            let node = queue.shift();
            if (node.id === sourceNode.id) {
                return true;
            }
            if (node && node.children) {
                node.children.forEach(element => {
                    queue.push(element);
                });
            }
        }

        return false;
    }

    toggleOtherMenus(rootNode, expanded, menu) {
        let queue = [];
        queue.push(rootNode);

        while (queue.length > 0) {
            let node = queue.shift();
            if (node.id !== menu.id) {
                if (this.isContains(node, menu)) {
                    node.expanded = expanded;
                } else {
                    node.expanded = false;
                }
            }

            if (node && node.children) {
                node.children.forEach(element => {
                    queue.push(element);
                });
            }
        }
    }

    hidenUserName(userName) {
        let regExp = /^.*[\u2E80-\u9FFF].*$/;
        if (!userName) {
            return;
        }
        // 如果长度小于7或者存在中文则不隐藏
        if (userName.length < 7 || regExp.test(userName)) {
            return userName;
        }
        let left = userName.substr(0, 3);
        let right = userName.substring(userName.length - 4);

        // Only show 4 '*' in the middle, make it simple and consistence
        return left.concat('****', right);
    }
}

export const sideNavComponent = {
    bindings: {
        menus: '=',
        userInfo: '=',
        logo: '=',
        bg: '=',
        welcomes: '=',
        minus: '=',
        helloText: '<'
    },
    templateUrl: 'app/controls/components/sideNav/sideNav.html',
    controller: SideNavController
};