/*jslint node: true */
/*jslint browser: true*/
/*jslint nomen: true*/
/*global BaseController, angular*/

'use strict';


var includeExcludeSelectionDirective = BaseController.extend({
    /**
     * @override
     */

    selectClassOne: null,
    operator: null,
    selectClassTwo: null,
    init: function ($scope, $elm, $attrs, $filter, $modal, $timeout, naviTreeService, includeExcludeService, IEPaginationService) {
        this._element = $elm;
        this.filter = $filter;
        this.$modal = $modal;
        this.$timeout = $timeout;
        this._naviTreeService = naviTreeService;
        this._paginationService = IEPaginationService;
        this._environmentService = includeExcludeService;

        this._super($scope);

        this.$scope.totalHostList = [];
        this.$scope.treeProfiles = [];

        this.$scope.hostContexts = {name: "All hosts", includes: [], isHosts: false};
        this.$scope.excludedHosts = {};
        this.$scope.includedHosts = {};
        this.$scope.treeProfiles = [];
        this.$scope.searchCompleteHost = false;
        this._naviTreeService.getTreeNodes({id: 1, shared: 0, sharedBy: 0}).then(
            function (result) {
                this.$scope.prepareTreeProfile(result.data, 2)
            }.bind(this)
        );

    },


    /**
     * @override
     */
    defineListeners: function () {
        var self = this, $scope = self.$scope;

        $scope.$watch('context', function (val) {
            if (!val) {
                return;
            }

            self.$scope.nodeLevels = []; // reset nodes
            self.$scope.selectedNodeLevel = [];
            self.$scope.selectedProfile = null;

            self.$scope.$emit('environmentProfileChanged_Event', self.$scope.selectedProfile);
            self.$scope.$emit('environmentNodeChanged_Event', self.$scope.selectedNodeLevel);

            var nodes = [];

            angular.forEach($scope.context, function (value, key) {
                nodes.push({
                    'classRegex': value,
                    'label': value
                });
            });

            self._updateClassEvaluation(nodes);
            self._emitManualClass_selection();
        });


        $scope.$watch('state', function (val) {
            self._loadProfilesAndSetSelected(val);
        });

        $scope.$watch('searchCompleteSelected', function (searchCompleteSelected) {
            if (searchCompleteSelected && Object.keys(searchCompleteSelected).length > 0) {
                $scope.hostContexts = $scope.hostContexts.isHosts == false ? {name: searchCompleteSelected.name, includes: [searchCompleteSelected.id], isHosts: searchCompleteSelected.type == 'Hosts'} : $scope.hostContexts;
                self._emitManualClass_selection();
                $scope.searchCompleteHost = searchCompleteSelected.type == 'Hosts';
            }
        })

        $scope.$watch('excludedHosts', function (v) {
            self.$scope.$emit('environmentExcludeChanged_Event', v);
        })

    },

    _loadProfilesAndSetSelected: function (val) {
        var self = this;
        if (val && !angular.equals({}, val)) {
            if (val.hostContexts) {
                var data = val.hostContexts;
                self.$scope.hostContexts.name = data.name || '';
                self.$scope.hostContexts.includes = Array.isArray(data.includes) && data.includes.length > 0 ? data.includes[0].split('|') : '';
                self.$scope.hostContexts.isHosts = data.isHosts || '';

                var hostKeys =  Array.isArray(data.includes) && data.includes.length > 0 ? data.includes[0].split('|') : [];
                var returnIncluded = {};
                if(self.$scope.hostContexts.isHosts && hostKeys.length > 0){
                    data.name.split(', ').forEach(function (v, i) {
                        var hk = hostKeys[i];
                        returnIncluded[hk] = v;
                    })
                }
                self.$scope.includedHosts = returnIncluded || {};
            }

            if (self.$scope.hostContexts.includes.length > 0 && !self.$scope.hostContexts.isHosts) {
                self.$scope.searchCompleteSelected = {
                    id: self.$scope.hostContexts.includes[0],
                    name: self.$scope.hostContexts.name,
                    type: "OS"
                };
            }
            if (angular.isObject(val.excludedHosts) && Object.keys(val.excludedHosts).length > 0) {
                var returnExcluded = {};
                var hostkeys = val.excludedHosts.excludes;
                val.excludedHosts.name.split(', ').forEach(function (v, i) {
                    returnExcluded[hostkeys[i]] = v;
                })
                self.$scope.excludedHosts = returnExcluded || {};
            }
        }

        self._emitManualClass_selection();
    },

    defineScope: function () {
        var self = this;
        this.$scope.selectedProfile = {};
        this.$scope.treeNodes = [];
        this.$scope.nodeLevels = [];
        this.$scope.selectedNodeLevel = [];
        this.$scope.selectedNode = {};
        this.$scope.hostFilterSet = false;
        this.$scope.showHosts = false;
        this.$scope.showHostButton = false;

        this.$scope.searchComplete = [];
        this.$scope.searchComplete.push({name: "All hosts", type: "", id: "%"});
        this.$scope.prepareTreeProfile = this.prepareTreeProfile.bind(this);
        this.$scope.searchPlaceholder = 'Search: group, hostname, IP, classes ';

        this.$scope.showHost = this.showHost.bind(this);
        this.$scope.selectClass = this.selectClass.bind(this);
        this.$scope.getExcludedHostsCount = this.getExcludedHostsCount.bind(this);
        this.$scope.getIncludedHostsCount = this.getIncludedHostsCount.bind(this);
        this.$scope.clearSearchComplete = this.clearSearchComplete.bind(this);
        this.$scope.applyFilter = this.applyFilter.bind(this);
        this.$scope.clearAll = this.clearAll.bind(this);
    },

    clearSearchComplete: function () {
        this.$scope.searchComplete.forEach(function (value, index) {
            if (value.type == 'Hosts' || value.type == 'Classes') {
                delete  this.$scope.searchComplete[index];
            }
        }.bind(this))

    },

    getExcludedHostsCount: function () {
        return Object.keys(this.$scope.excludedHosts).length.toString() + ' ' + (Object.keys(this.$scope.excludedHosts).length > 1 ? 'hosts' : 'host');
    },

    getIncludedHostsCount: function () {
        return Object.keys(this.$scope.hostContexts.includes).length.toString() + ' ' + (Object.keys(this.$scope.hostContexts.includes).length > 1 ? 'hosts' : 'host');
    },
    selectClass: function (selectedValue) {
        this.$scope.includedHosts = {};
        this.$scope.excludedHosts = {};
        this.$scope.searchCompleteSelected = selectedValue
        this.$scope.hostContexts = {
            name: this.$scope.searchCompleteSelected.name,
            includes: [this.$scope.searchCompleteSelected.id
            ],
            isHosts: false,
        } || [];
    },
    prepareTreeProfile: function (data, level) {
        var self = this;

        if (Array.isArray(data) && data.length > 0) {
            angular.forEach(data, function (v) {
                self.$scope.searchComplete.push({name: '-'.repeat(level) + ' ' + v.label, type: "OS", id: v.classRegex})
                if (v.children != undefined && v.children.length > 0) {
                    self.$scope.prepareTreeProfile(v.children, level + 1)
                }
            })
        }
    },

    clearContextFields: function () {
        this.$scope.nodeLevels = []; // reset nodes
        this.$scope.selectedNodeLevel = [];
        this.$scope.context = null;
        this.$scope.hostContexts = {};
        this.$scope.hostContexts.name = null;
        this.$scope.hostContexts.includes = null;
        this.$scope.hostContexts.isHosts = null;
        this.$scope.selectedProfile = null;
    },

    showHost: function () {
        var self = this;
        this.hostListModalInstance = this.$modal.open({
            templateUrl: 'hostSelectionModal.html',
            backdrop: 'static',
            keyboard: true,
            windowClass: 'include',
            controller: function ($scope, $modalInstance, naviTreeService, $filter, hostContexts, $parent, IEPaginationService) {
                $scope.modalData = {};
                $scope.totalHostList = [];
                $scope.originalHostList = [];
                $scope.selectedHosts = {};
                $scope.excludedHosts = $parent.$scope.excludedHosts;
                $scope.includedHosts = $parent.$scope.includedHosts;
                $scope.hostSearch = {};
                $scope.hostSearch.input = '';
                $scope.allchecked = true;
                $scope.showHosts = false;
                $scope.showEIButtons = false;
                $scope.paginator = IEPaginationService;
                $scope.modalData.searchResult = [];
                $scope.modalData.searchString = '';
                $scope.modalData.showSearchResults = false;

                $scope.searchCompleteSelected = $parent.$scope.searchCompleteSelected;

                var getHostsList = function (v) {
                    v = v === undefined ? $parent.$scope.searchComplete[0] : v;
                    $parent.$scope.searchCompleteSelected = v;
                    naviTreeService.getNodeHosts(v.id, 99999999, 1).then(function (result) {
                        var totalHosts = result.data.length
                        var oldPage = $scope.paginator.page
                        $scope.paginator.refreshPaginator(totalHosts);
                        if (oldPage == $scope.paginator.page) {
                            naviTreeService.getNodeHosts($parent.$scope.searchCompleteSelected.id, $scope.paginator.defaultRowsPerPage, $scope.paginator.page).then(getNodeHostSuccess, getNodeHostfailure);
                        }
                    });
                }


                $scope.close = function () {
                    $modalInstance.close('cancel');
                };


                $scope.isEmptyObject = function (data) {
                    return Object.keys(data).length == 0;
                }

                $scope.clearAll = function () {
                    $parent.$scope.excludedHosts = {};
                    $parent.$scope.includedHosts = {};
                }

                $scope.isHostExcluded = function (key) {
                    key = key.replace('SHA=', '');
                    if ($parent.$scope.excludedHosts[key]) {
                        return true;
                    } else {
                        return false;
                    }
                }

                $scope.isHostIncluded = function (key) {
                    key = key.replace('SHA=', '');
                    if ($parent.$scope.includedHosts[key]) {
                        return true;
                    } else {
                        return false;
                    }
                }

                $scope.deleteExcludedHosts = function (key) {
                    key = key.replace('SHA=', '');
                    if ($parent.$scope.excludedHosts[key]) {
                        delete $parent.$scope.excludedHosts[key];
                    }
                    $parent.$scope.$emit('environmentExcludeChanged_Event', $parent.$scope.excludedHosts);
                    $parent._emitManualClass_selection();
                };

                $scope.deleteIncludedHosts = function (key) {
                    key = key.replace('SHA=', '');
                    if ($parent.$scope.includedHosts[key]) {
                        delete $parent.$scope.includedHosts[key];
                    }
                    changeIncludes($parent.$scope.includedHosts);
                    $parent.$scope.$emit('environmentIncludeChanged_Event', $parent.$scope.includedHosts);
                };

                $scope.addExcludedHost = function (host) {
                    $scope.modalData.showSearchResults = false;
                    $parent.$scope.includedHosts = {};
                    $parent.$scope.excludedHosts[host.id.replace('SHA=','')] = host.hostname;
                    $parent.$scope.$emit('environmentExcludeChanged_Event', $parent.$scope.excludedHosts);
                };

                $scope.addIncludedHost = function (host) {
                    $scope.modalData.showSearchResults = false;
                    $parent.$scope.excludedHosts = {};
                    $parent.$scope.includedHosts[host.id.replace("SHA=", "")] = host.hostname;
                    changeIncludes($parent.$scope.includedHosts);
                };

                $scope.changeShowSearchResults = function () {
                    $scope.showSearchResults = !$scope.showSearchResults;
                }

                $scope.disableButton = function () {
                    var empty = angular.equals({}, $scope.selectedHosts);
                    $scope.showEIButtons = empty ? false : true;
                    return empty;
                };

                $scope.$watch('modalData.searchString', function (query) {
                    if (query.length > 0) {
                        naviTreeService.searchHosts(query).then(function (result) {
                            var hosts = result.data;
                            hosts.forEach(function (v, i) {
                                hosts[i].id = v.hostkey;
                            })
                            $scope.totalHostList = result.data;
                            $scope.originalHostList = angular.copy($scope.totalHostList);
                            $scope.showHosts = true;
                        }, getNodeHostfailure);
                        $scope.paginator.refreshPaginator(10);
                    } else {
                        getHostsList($parent.$scope.searchCompleteSelected)
                    }
                });

                $scope.useSelectedHost = function () {
                    $modalInstance.close();
                };

                var getNodeHostSuccess = function (result) {
                    $scope.totalHostList = result.data;
                    $scope.originalHostList = angular.copy($scope.totalHostList);
                    $scope.showHosts = true;
                };

                var getNodeHostfailure = function (error) {
                    $scope.hostListError = error.data;
                    $scope.totalHostList = [];
                    $scope.selectedHosts = {};
                    $scope.showHosts = true;
                };

                var changeIncludes = function (includedHosts) {
                    $scope.includedHosts = includedHosts;
                    if (Object.keys(includedHosts).length > 0) {
                        $parent.$scope.hostContexts = {
                            name: Object.values(includedHosts).join(', '),
                            includes: Object.keys(includedHosts),
                            isHosts: true,
                        } || [];
                    } else {
                        $parent.$scope.hostContexts = {
                            name: $parent.$scope.searchCompleteSelected.name,
                            includes: [$parent.$scope.searchCompleteSelected.id
                            ],
                            isHosts: false,
                        } || [];
                    }
                    $parent._emitManualClass_selection();
                }


                $scope.$watch('paginator.page', function (newPage, oldPage) {
                    if (newPage !== oldPage) {
                    naviTreeService.getNodeHosts($parent.$scope.searchCompleteSelected.id, $scope.paginator.defaultRowsPerPage, $scope.paginator.page).then(getNodeHostSuccess, getNodeHostfailure);
                    $scope.selectedHosts = {};
                    }
                })


                $parent.$scope.$watch('searchCompleteSelected', function (v) {
                    getHostsList(v);
                });


                $parent.$scope.$watch('searchComplete', function (searchComplete) {
                    $scope.searchComplete = searchComplete;
                })
                $parent.$scope.$watch('excludedHosts', function (excludedHosts) {
                    $scope.excludedHosts = excludedHosts;
                })

                $parent.$scope.$watch('includedHosts', function (includedHosts) {
                    changeIncludes(includedHosts);
                })


                $scope.getExcludedHostsCount = $parent.getExcludedHostsCount.bind($parent);
                $scope.getIncludedHostsCount = $parent.getIncludedHostsCount.bind($parent);


            },
            resolve: {
                naviTreeService: function () {
                    return self._naviTreeService;
                },
                $filter: function () {
                    return self.filter;
                },
                hostContexts: function () {
                    return self.$scope.hostContexts;
                },
                $parent: function () {
                    return self;
                },
                paginationService: function () {
                    return self._paginationService;
                }
            }
        });

    },


    _updateClassEvaluation: function (nodes) {
        var self = this, regex = [];
        var label = [];

        angular.forEach(nodes, function (val) {
            regex.push(val.classRegex.replace(/[-.]/g, "_"));
            label.push(val.label);
        });

        var environmentLabel = label.join(' and ');
        this.$scope.hostContexts.name = environmentLabel;
        this.$scope.hostContexts.includes = regex;

        self._emitManualClass_selection();

    },


    /* emit event and send env object with manually entered classes (or selected from hostpopup)  */
    _emitManualClass_selection: function () {
        var self = this, objToEmit = {};
        objToEmit.name = self.$scope.hostContexts.name.trim().split('-').join('');
        objToEmit.includes = self.$scope.hostContexts.includes.length > 0 ? [self.$scope.hostContexts.includes.join("|")] : [];
        objToEmit.isHosts = self.$scope.hostContexts.isHosts;
        self.$scope.$emit('environmentHostContextChange_Event', objToEmit);
        self.$scope.$emit('hostContextApply_Event', {hostcontexts: objToEmit});
    },

    applyFilter: function() {
        var self = this;
        self._emitManualClass_selection();
        self.$scope.$parent.showFilter = false;
        self._runReport();
    },

    clearAll: function () {
        var self = this;
        self.clearContextFields();
        self.$scope.excludedHosts = {};
        self.$scope.includedHosts = {};
        self.$scope.hostContexts = {name: "All hosts", includes: [], isHosts: false};
        self.$scope.searchCompleteSelected = {name: "All hosts", type: "", id: "%"};
        self._emitManualClass_selection();
        self.$scope.filters = [];
        this.$scope.$emit('clearFilters_EVENT');
    },

    _runReport: function () {
        var self = this;
        // run the report with up to date filter data
        self.$scope.$emit('runQuery_EVENT');
    }
});