policyAnalyzerApp.directive('policyFileExplorer', ['$rootScope', function ($rootScope) {
    return {
        restrict: 'EA',
        replace: false,
        scope: {
            files: '=',
            nodeTemplateId: '@',
            selectedItem: '=?',
            statistics: '=?',
            onFileSelected: '&?',
            allowCopying: '&?',
            onDirectorySelected: '&?',
            policyPath: '=?',
            copyingEnabled: '=?',
            showAllowCopyingMessage: '=?',
        },
        templateUrl: MP_SITE_URL + '/policy/analyzer/partials/fileExplorer',

        link: function ($scope) {
            $scope.$watch('files', function (data) {
                if(data !== undefined){
                    $scope.nodes = initializeNodes(data);
                }
            });

            $scope.$watch('statistics', function (data) {
                buildPolicyStatusCircles(data)
            });

            $scope.hasChildren = hasChildren;
            $scope.isBranch = isBranch;

            $scope.selectNode = function (node) {
                if ($scope.isBranch(node)) {
                    node.expanded = !node.expanded;
                    $scope.onDirectorySelected({dir: node.value});
                }
                else {
                    $scope.onFileSelected({file: node.value});
                }
                $scope.selectedNode = node;
            };

            $scope.countChildrenRecursive = function (node) {
                var count = 0;

                node.children.forEach(function (n) {
                    if ($scope.hasChildren(n)) {
                        count += $scope.countChildrenRecursive(n);
                        return;
                    }

                    count++;
                });

                return count;
            };


            function hasChildren(node) {
                return Array.isArray(node.children) && node.children.length > 0;
            }

            function isBranch(node) {
                return Array.isArray(node.children);
            }

            function initializeNodes(data, parent) {
                var nodes = [];

                for (var i = 0; i < data.length; i++) {
                    var node = {value: data[i], expanded: false};

                    if (parent) {
                        node.parent = parent;
                    }
                    if (i > 0) {
                        node.previous = nodes[i - 1];
                        nodes[i - 1].next = node;
                    }

                    if (isBranch(data[i])) {
                        node.children = initializeNodes(data[i].children, node);
                    }

                    if ($scope.selectedItem.path != undefined && $scope.selectedItem.path.relative === node.value.path.relative) {
                        $scope.selectedNode = node;
                        var nodeToExpand = node.parent;
                        while (nodeToExpand != null) {
                            nodeToExpand.expanded = true;
                            nodeToExpand = nodeToExpand.parent;
                        }
                    }

                    nodes.push(node);
                }

                return nodes;
            }


            function buildPolicyStatusCircles(statistics) {
                let self = this;
                // remove old badges
                $('.badges').remove();

                $('div.file').each(function (index, element) {
                    let relativePath = $(element).attr('relative-path');
                    let absolutePath =  $scope.policyPath + relativePath;

                    if (statistics.hasOwnProperty(absolutePath)) {
                        let statistic = statistics[absolutePath];
                        let badges = createBadges(statistic);
                        $(element).append(badges)


                    }
                });

                $('div.directory').each(function (index, element) {
                    let relativePath = $(element).attr('relative-path');
                    let absolutePath =  $scope.policyPath +  relativePath;

                    let result = {};
                    Object.keys(statistics).forEach(function (key) {
                        if (key.indexOf(absolutePath) == 0) {
                            let childrenStatistics = statistics[key];
                            // combine file statistics to directory
                            Object.keys(childrenStatistics).forEach(function (key) {
                                result[key] = result.hasOwnProperty(key) ? childrenStatistics[key] + result[key] : childrenStatistics[key];
                            })
                        }
                    })

                    if (Object.keys(result).length > 0) {
                        let badges = createBadges(result);
                        $(element).append(badges)
                    }
                });
            }

            function sortObjKeysAlphabetically(obj) {
                const ordered = {};
                Object.keys(obj).sort().forEach(function (key) {
                    ordered[key] = obj[key];
                });
                return ordered;
            }

            function createBadges(data) {
                data = sortObjKeysAlphabetically(data)
                var promiseClasses = {REPAIRED: 'warning', KEPT: 'success', NOTKEPT: 'important'};
                var html = '<span class="badges">';
                var badges = '';
                Object.keys(data).forEach(function (key) {
                    if(data[key] > 0){
                        badges += '<span class="badge badge-' + promiseClasses[key] + '">' + data[key] + '</span>';
                    }
                })
                html += badges + '</span>';
                return html;
            }
        }
    };
}]);