'use strict';
var resultController = BaseController.extend({
    /**
     * Initialize  Controller
     * @param $scope, current controller scope
     */

    init: function($scope, $q, $location, $cookies, $routeParams, reportService, wizardSharedService, commonHelper, notificationService, paginationService, modalWindowService) {
        var self = this;
        self.goToTopIcon = $('.go-to-top');
        self.goToTopIcon.click(function() {
            $("html, body").animate({
                scrollTop: 0
            }, 600);
            return false;
        });
        self.goToBottomIcon = $('.go-to-bottom');
        self.goToBottomIcon.click(function() {
            $("html, body").animate({
                scrollTop: $('#wrapper').height()
            }, 600);
            return false;
        });

        $(window).on('scroll', function()
        {
            if ($(this).scrollTop() <= 100) {
                 self.goToBottomIcon.hide();
                 self.goToTopIcon.hide();
             } else if ($(this).scrollTop() <= 180) {
                self.goToTopIcon.hide();
                self.goToBottomIcon.show();
            } else {
                self.goToTopIcon.show();
                self.goToBottomIcon.show();
            }

            if (($(this).scrollTop()+100) >= $('#wrapper').height()-$(window).height()) {
                self.goToBottomIcon.hide();
            }
        });

        this._super($scope);

        this.$location            = $location;
        this.$q                   = $q;
        this.$cookies             = $cookies;
        this._reportService       = reportService;
        this._wizardSharedService = wizardSharedService;
        this._commonHelper        = commonHelper;
        this._notificationService = notificationService;

        this.$scope.paginator     = paginationService;

        this.$scope.modalWindow   = modalWindowService;


        self.$scope.alertData   = {};
        self.$scope.hostcontexts = {};
        self.$scope.excludedHosts = '';
        self.$scope.hostselectionstate = {};
        self.$scope.showEnvironmentFilterButtons = false;


        self.$scope.savedSearchName = {};
        self.$scope.savedSearchCategory = {};
        self.$scope.is_public = {};

        // scope variables
        self.$scope.notification = {};

        self._initVIEWParams();

        self.$scope.Math = Math;

        self.$scope.reportId    = '';
        self.$scope.reportLabel = '';
        self.$scope.show_buttons = 0;

        self.$scope.reportRoles = {};

        self.$scope.roles    = this._commonHelper.getRolesArray();
        self.$scope.is_admin = self._commonHelper.checkifAdmin(self.$scope.roles);

        self.$scope.reportCategories = ReportCategories;

        self.$scope.SQL = {};

        this.externalSQL = '';
        this.externalIncludes = [];
        this.externalTitle = '';
        this.skipHostContextInitialization = false;
        this.customNoRowsMessage = '';
        this.notificationType = 'warning';

        if($routeParams.hasOwnProperty('state') && $routeParams.state !== '') {
            let state = JSON.parse(atob($routeParams.state));
            this.externalTitle = $routeParams.title;
            self.$scope.SQL = state;
            this.externalSQL = state.SQLSTRING;
            this.skipHostContextInitialization = true;
        }

        if ($routeParams.sql !== undefined && $routeParams.sql !== '')
        {
            this.externalSQL = self._base64_decode(decodeURIComponent($routeParams.sql));

            // only if sql is set we will check for includes, otherwise -try use global context
            if ($routeParams.includes !== undefined && $routeParams.includes !== '')
            {
                var tmpIncludes = self._base64_decode(decodeURIComponent($routeParams.includes));
                var includes;

                // try to check and convert includes to json, if this is json. othervice use it as string
                try {
                    includes = JSON.parse(tmpIncludes);
                    this.externalIncludes = includes;
                } catch(e) {
                    includes = tmpIncludes;
                    this.externalIncludes.push(includes);
                }
            }

            if ($routeParams.title !== undefined && $routeParams.title !== '')
            {
                this.externalTitle = decodeURIComponent($routeParams.title);
            }
        }
        // this parameter show the delete host button on the result view
        // 1st parameter of the SQL result should always be hostkey for this to work.
        if ($routeParams.delview !== undefined && $routeParams.delview == 1)
        {
            self.$scope.deleteTableView = 1;
        }



        /*Load query data and run*/
        if (!self._commonHelper._isObjEmpty(self._wizardSharedService.restoreScopeState()))
        {
            self.$scope.SQL = self._wizardSharedService.restoreScopeState();
            self._commonHelper.setContextVariables(self.$scope, self.$scope.SQL);
            self.$scope.excludedHosts         = self.$scope.SQL.excludedHosts;
            self.$scope.alertData.hostContexts = self.$scope.hostcontexts;
            self.$scope.alertData.excludedHosts = self.$scope.excludedHosts;
            if (self.$scope.SQL === undefined || self.$scope.SQL.SQLSTRING === '')
            {
                var error = self._notificationService.createObjectForNotification('error', 500, 'Error getting report. Please return to the report list');
                self._notificationService.setNotification(error.type, error.data);
                self.$scope.show_buttons = 0;
            }
            else
            {
                var tmpReport =  self._wizardSharedService.restoreReportProperties();

                self.$scope.reportLabel     = tmpReport.reportLabel;
                self.$scope.savedSearchName.input = self.$scope.reportLabel; // for modal window
                self.$scope.savedSearchCategory.input = (tmpReport.reportCategory !== undefined ? tmpReport.reportCategory: ''); // for modal window
                self.$scope.noResultsSuccess = tmpReport.noResultsSuccess;
                if (self.$scope.noResultsSuccess){
                    self.noResultsSuccessNotify();
                }
                self.$scope.reportCategory = (tmpReport.reportCategory !== undefined ? tmpReport.reportCategory: {});


                self.$scope.reportId    = tmpReport.reportId;
                self.$scope.reportRoles = tmpReport.reportRoles;

                self.$scope.is_own      = tmpReport.is_own;
                self.$scope.can_edit    = tmpReport.can_edit;
                self.$scope.can_delete  = tmpReport.can_delete;
                self.$scope.readonly    = tmpReport.readonly;
                self.$scope.is_public.input   = Boolean(tmpReport.is_public);
                // this is new report
                if (self.$scope.reportId === '' && self.$scope.reportLabel === '')
                {
                    self.$scope.is_own   = 1;
                    self.$scope.can_edit = 1;
                }

                self._runQuery();
                self.$scope.show_buttons = 1;
                self._wizardSharedService.reportPropertiesChanged(self._commonHelper.getReportData(self.$scope));
            }
        }
        else if ($routeParams.reportid !== undefined)
        {
            self.$scope.reportId = $routeParams.reportid;
            self._reportService.loadReport(self.$scope.reportId).then(
                    function(result) {
                        var data = result.data;
                        self.$scope.reportId        = data['id'];
                        self.$scope.reportLabel     = data['label'];
                        self.$scope.savedSearchName.input = self.$scope.reportLabel; // for modal window
                        self.$scope.savedSearchCategory.input = (data['reportCategory'] !== undefined ? data['reportCategory']: '') ;

                        self.$scope.reportCategory = (data['reportCategory'] !== undefined ? data['reportCategory']: '');

                        self.$scope.is_own          = data['is_own'];
                        self.$scope.can_edit        = data['can_edit'];
                        self.$scope.can_subscribe   = data['can_subscribe'];
                        self.$scope.is_subscribed   = data['is_subscribed'];
                        self.$scope.is_public.input = Boolean(data.is_public);

                        self.$scope.SQL = angular.fromJson(data['AdvancedReportsData']['SQL']);
                        self.$scope.noResultsSuccess = angular.fromJson(data['AdvancedReportsData']['noResultsSuccess']);
                        if (self.$scope.noResultsSuccess){
                            self.noResultsSuccessNotify();
                        }
                        self._wizardSharedService.scopeStateChanged(self.$scope.SQL);

                        $scope.reportRolesTMP    = (data.sharedPermission  !== undefined ? angular.fromJson(data.sharedPermission)  : {});
                        angular.forEach($scope.reportRolesTMP, function(key, value){
                           $scope.reportRoles[key] = true;
                        });

                        self._wizardSharedService.reportPropertiesChanged(self._commonHelper.getReportData(self.$scope));
                        self._runQuery();
                        self.$scope.show_buttons = 1;
                    },
                    function(error) {
                        self._notificationService.setNotification('error', error.data);
                        self.$scope.show_buttons = 0;
                    });
        }
        else if (this.externalSQL !== '')
        {
            self.$scope.SQL.SQLSTRING   = this.externalSQL;

            self.$scope.reportLabel  = this.externalTitle || '';

            // set environment variables for this call only
            if (this.externalIncludes !== undefined && this.externalIncludes.length > 0)
            {
                self.$scope.SQL.hostcontexts = {};
                self.$scope.SQL.hostcontexts.includes  = this.externalIncludes;
            }


            self._wizardSharedService.scopeStateChanged(self.$scope.SQL);
            self._runQuery();
            self.$scope.show_buttons = 1;

            self.$scope.is_own          = 1;
            self.$scope.can_edit        = 1;
            self.$scope.can_subscribe   = 0;
            self.$scope.is_subscribed   = 0;
            self.$scope.is_public.input = 0;

            self._wizardSharedService.reportPropertiesChanged(self._commonHelper.getReportData(self.$scope));
        }
        else if(sessionStorage.getItem('sql')) {
            self.$scope.is_own          = 1;
            self.$scope.can_edit        = 1;
            self.$scope.can_subscribe   = 0;
            self.$scope.is_subscribed   = 0;
            self.$scope.is_public.input = 0;
            self.$scope.SQL = JSON.parse(sessionStorage.getItem('sql'));
            self._commonHelper.setContextVariables(self.$scope, self.$scope.SQL);
            self.$scope.excludedHosts         = self.$scope.SQL.excludedHosts;
            self.$scope.hostсontexts         = self.$scope.SQL.hostcontexts;
            self.$scope.alertData.hostContexts = self.$scope.hostcontexts;
            self.$scope.alertData.excludedHosts = self.$scope.excludedHosts;
            self._runQuery();
            self.$scope.show_buttons = 1;
            self.$scope.noResultsSuccess = JSON.parse(sessionStorage.getItem('noResultSuccess'))
            self._wizardSharedService.reportPropertiesChanged(self._commonHelper.getReportData(self.$scope));
            self.$scope.noResultsSuccess = JSON.parse(sessionStorage.getItem('noResultSuccess'))
            if (self.$scope.noResultsSuccess){
                self.noResultsSuccessNotify();
            }
            console.log(self.$scope);
        } else {
            var reportError = self._notificationService.createObjectForNotification('error', 500, 'Unable to find SQL expression');
            self._notificationService.setNotification(reportError.type, reportError.data);
            self.$scope.show_buttons = 0;
        }

        var contextTmp = {};
        contextTmp.hostContexts = self.$scope.alertData.hostContexts || '';
        contextTmp.excludedHosts =  self.$scope.alertData.excludedHosts || '';
        self.$scope.hostselectionstate = contextTmp;

    },
    noResultsSuccessNotify: function() {
        var self = this;
        self.customNoRowsMessage = ' There are no failures / results.'
        self.notificationType = 'good';
    },
    defineScope: function() {
        var self = this;

        self.$scope.instance    = "resultController";
        self.$scope.deleteTableView = 0;
        self.$scope.checkAllDeleteHost = false;
        self.$scope.deleteHostList = {};
        self.$scope.deleteHostKeyMessage = {};

        self.$scope.sortReorder = self.sortReorder.bind(this);

        self.$scope.editReport     = self.editReport.bind(this);
        self.$scope.scheduleReport = self.scheduleReport.bind(this);

        this.$scope.cleanStoredScope = this.cleanStoredScope.bind(this);

        this.$scope.subscribe        = this.subscribe.bind(this);
        this.$scope.unsubscribe      = this.unsubscribe.bind(this);
        this.$scope.saveReport       = self.saveReport.bind(this);

        this.$scope.copyReport       = this.copyReport.bind(this);
        this.$scope.setCurrentReportData = this.setCurrentReportData.bind(this);

        this.$scope.roles_disablePublicReport = this.roles_disablePublicReport.bind(this);
        this.$scope.publicReport_disableRoles = this.publicReport_disableRoles.bind(this);

        this.$scope.isObjEmpty      = this.checkIfObjEmpty.bind(this);
        this.$scope.runQuery = this.runQuery.bind(this);
        this.$scope.checkAllDeleteHost = this.checkAllDeleteHost.bind(this);
        this.$scope.deleteSeletedHosts = this.deleteSeletedHosts.bind(this);
        this.$scope.deleteConfirmedHosts = this.deleteConfirmedHosts.bind(this);
        this.$scope.closeHostDeleteConfirmDialog = this.closeHostDeleteConfirmDialog.bind(this);
        this.$scope.noResultsSuccessNotify = this.noResultsSuccessNotify.bind(this);

    },
   defineListeners: function() {
        var self = this;

        self.$scope.$on("hostContextApply_Event", function(event, hostContextObj) {

            if (!self.skipHostContextInitialization) {
                self.$scope.SQL.hostcontexts           = angular.copy(hostContextObj.hostcontexts);
                self.$scope.SQL.hostcontextsprofileid  = angular.copy(hostContextObj.hostcontextsprofileid);
                self.$scope.SQL.hostcontextspath       = angular.copy(hostContextObj.hostcontextspath);
            }

            self.skipHostContextInitialization = false;


            self.$scope.hostcontexts       = self.$scope.SQL.hostcontexts;
            self.$scope.alertData.hostContexts = self.$scope.SQL.hostcontexts;
            self._wizardSharedService.reportPropertiesChanged(self._commonHelper.getReportData(self.$scope));

            self.$scope.showFilter = false;
            self._runQuery('environmentFilter');
        });

       self.$scope.$on('environmentExcludeChanged_Event', function(event, excludedHosts) {

           if (Object.keys(excludedHosts).length)
           {
               self.$scope.alertData.excludedHosts = {name: Object.values(excludedHosts).join(', '), excludes: Object.keys(excludedHosts)};
               self.$scope.SQL.excludedHosts = {name: Object.values(excludedHosts).join(', '), excludes: Object.keys(excludedHosts)};
               self.$scope.excludedHosts = {name: Object.values(excludedHosts).join(', '), excludes: Object.keys(excludedHosts)};
           }
           else {
               self.$scope.alertData.excludedHosts = '';
               self.$scope.excludedHosts = '';
               self.$scope.SQL.excludedHosts = '';
           }
       });

        self.$scope.$on('paginatorChange', function() {
            self._runQuery('paging');
        });

        self.$scope.$on('subscribeToReport', function(event, data) {
          self.cleanStoredScope();
          self._reloadReport(data['id']);
        });

        self.$scope.$on('unSubscribeFromReport', function(event, data) {
          self.cleanStoredScope();
          self._reloadReport(data['id']);
        });
    },

   sortReorder: function(col,e) {
        var self = this;
        angular.forEach(self.$scope.VIEW.tablehead, function(el) {
            if (el.nameToSort===col)
            {
                el.sort = el.sort>0?-1:1;

                self.$scope.VIEW.sortColumn     = el.name;
                self.$scope.VIEW.sortDescending = el.sort>0 ? 0:1; //
            }
            else
            {
                el.sort = null;
            }
        });

        if (self.$scope.VIEW.sortColumn !== undefined && self.$scope.VIEW.sortColumn !=='')
        {
            self._runQuery('reorder');
        }
    },


    checkAllDeleteHost: function() {
        var self = this;
        self.$scope.selectedAllDeleteHost = !self.$scope.selectedAllDeleteHost;
        angular.forEach(self.$scope.deleteHostList, function(value, key){
            self.$scope.deleteHostList[key].checked = self.$scope.selectedAllDeleteHost;
        });
    },

    deleteSeletedHosts: function() {
        var self = this;
        self.$scope.selectedKeysForDelete = [];
        angular.forEach(self.$scope.deleteHostList, function(value, key){
            if (value.checked === true)
            {
                self.$scope.selectedKeysForDelete.push(key);
            }
        });
        if ( self.$scope.selectedKeysForDelete.length)
        {
           self.$scope.showDeleteButton = true;
            self.$scope.modalWindow.open('deleteHostConfirmModal', self.$scope);
        }
    },

    deleteConfirmedHosts: function() {
        var self = this;
        self.$scope.showDeleteButton = false;
        var successCallback = function(data) {
           self.$scope.rerunQueryAfterDelete = true;
           self.$scope.deleteHostList = {};
           self.$scope.deleteHostKeyMessage.type = 'alert-success';
           self.$scope.deleteHostKeyMessage.message = 'Host deleted successfully';
        };
        var failureCallback = function(error) {
           self.$scope.rerunQueryAfterDelete = false;
           self.$scope.deleteHostKeyMessage.type = 'alert-error';
           self.$scope.deleteHostKeyMessage.message = 'Failed deleting hosts. Error: '+ error.data;
        };
        self._reportService.deleteHosts(self.$scope.selectedKeysForDelete).then(successCallback,failureCallback);
    },

    closeHostDeleteConfirmDialog: function() {
        var self = this;
        self.$scope.deleteHostKeyMessage = {};
        self.$scope.modalWindow.close('deleteHostConfirmModal');
        if (self.$scope.rerunQueryAfterDelete)
        {
            self.runQuery();
        }
    },

    editReport: function() {
        var self = this;
        self._wizardSharedService.reportPropertiesChanged(self._commonHelper.getReportData(self.$scope));
        self._wizardSharedService.scopeStateChanged(self.$scope.SQL);
        var url = '/custom/edit';
        if (self.$scope.reportId !== undefined && self.$scope.reportId !=='' )
        {
            url = url + '/'+self.$scope.reportId;
        }
        self.$location.path(url);
    },
    scheduleReport: function() {
        var self = this;
        self._wizardSharedService.scopeStateChanged(self.$scope.SQL);
        var url = '/report/schedule';
        if (self.$scope.reportId !== undefined && self.$scope.reportId !=='' )
        {
            url = url + '/'+self.$scope.reportId;
        }
        self.$location.path(url);
    },

    saveReport: function (isOverwrite) {
        var self = this;
        self._commonHelper.saveReport(isOverwrite, self.$scope, 'result');
    },

    _runQuery: function(action) {
        var self = this;

        self._notificationService.resetNotification();

        if (self.externalSQL === '')
        {
            // apply current envirnment to SQL
            self.$scope.SQL.hostcontexts = self.$scope.hostcontexts;
        }

        // reset pagination to default if this is new query
        if (action !== 'reorder' && action !== 'paging' && action !== 'environmentFilter')
        {
           self.$scope.paginator.paginationReset();
        }

        if (self.$scope.SQL.SQLSTRING == undefined) {
            return;
        }
        var data = $.param({
            SQLString      : self.$scope.SQL.SQLSTRING.length > 0 ? encodeURIComponent(self.$scope.SQL.SQLSTRING) : false,
            sortColumn     : self.$scope.VIEW.sortColumn,
            sortDescending : self.$scope.VIEW.sortDescending,

            skip           : self.$scope.paginator.skip,
            limit          : self.$scope.paginator.rowsPerPage,

            includes       : ((self.$scope.SQL.hostcontexts !== undefined && self.$scope.SQL.hostcontexts.includes !== undefined) ? self.$scope.SQL.hostcontexts.includes : []),
            excludes       : ((self.$scope.SQL.excludedHosts !== undefined && self.$scope.SQL.excludedHosts.excludes !== undefined) ? self.$scope.SQL.excludedHosts.excludes : [])
        });

        self._reportService.runQuery(data).then(
        function(result)
        {
            common.globalSpinner.show();
            self.$scope.result = result.data;
            self.$scope.showdDeleteHostButton = false;
            if (self.$scope.deleteTableView && result.data.rows.length) {
               self.$scope.showdDeleteHostButton = true;
               angular.forEach(result.data.rows, function(value, key){
                    var key = value[0];
                    self.$scope.deleteHostList[key] = {};
                    self.$scope.deleteHostList[key].checked = false;
                });
            }
            // do not reset table header and sorting params if result table column headers are the same
            if (action !== 'reorder' && action !== 'paging' && action !== 'environmentFilter')
            {
                self._initVIEWParams();

                angular.forEach(self.$scope.result.header, function(field, key){
                    var tmp   = {};
                    tmp.name  = field.columnName;
                    tmp.type = field.columnType;

                    tmp.sort = 0;
                    tmp.fieldIndex = key;
                    tmp.nameToSort = tmp.name + '_' + key;
                    self.$scope.VIEW.tablehead.push(tmp);
                });
            }

            self.$scope.VIEW.rows = self.$scope.result.rows;
            self.$scope.VIEW.rowCount = self.$scope.result.rowCount;

            self.$scope.paginator.refreshPaginator(result.data.rowCount);

            if(self.$scope.result.rowCount === 0)
            {
                var error = self._notificationService.createObjectForNotification(self.notificationType, 505, self.customNoRowsMessage ? self.customNoRowsMessage : 'Query returned 0 rows');
                self._notificationService.setNotification(error.type, error.data);
            }
            common.globalSpinner.hide();
        },
        function(error) {
            error.data[0].text = error.data[0].text || 'Error encountered.Please view the logs for more detailed information.';
            self._notificationService.setNotification('error', error.data);
            common.globalSpinner.hide();
        });
     },

     runQuery:function() {
        var self = this;
        self._runQuery();
     },
    _initVIEWParams: function(){
        var self = this;
        self.$scope.VIEW = {};

        self.$scope.VIEW.sortColumn     = '';
        self.$scope.VIEW.sortDescending = 0;

        self.$scope.VIEW.tablehead      = [];
    },
    // see http://phpjs.org/functions/base64_decode/
    _base64_decode: function(data) {

        var b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
        var o1, o2, o3, h1, h2, h3, h4, bits, i = 0,
        ac = 0,
        dec = "",
        tmp_arr = [];

        if (!data) {
            return data;
        }

        data += '';

        do { // unpack four hexets into three octets using index points in b64
            h1 = b64.indexOf(data.charAt(i++));
            h2 = b64.indexOf(data.charAt(i++));
            h3 = b64.indexOf(data.charAt(i++));
            h4 = b64.indexOf(data.charAt(i++));

            bits = h1 << 18 | h2 << 12 | h3 << 6 | h4;

            o1 = bits >> 16 & 0xff;
            o2 = bits >> 8 & 0xff;
            o3 = bits & 0xff;

            if (h3 === 64) {
                tmp_arr[ac++] = String.fromCharCode(o1);
            } else if (h4 === 64) {
                tmp_arr[ac++] = String.fromCharCode(o1, o2);
            } else {
                tmp_arr[ac++] = String.fromCharCode(o1, o2, o3);
            }
        } while (i < data.length);

        dec = tmp_arr.join('');

        return dec;
    },


    copyReport: function(isOverwrite) {
        var self = this;
        var $scope = self.$scope;
        self._commonHelper.copyReport(self.$scope.currentReportId, self.$scope.savedSearchName.input, $scope, isOverwrite, 'result');
    },

    subscribe: function(id) {
        var self = this;
        var $scope = self.$scope;
        self._commonHelper.subscribeToReport(id);
    },

    unsubscribe: function(id) {
        var self = this;
        var $scope = self.$scope;
        self._commonHelper.unSubscribeFromReport(id);
    },

    cleanStoredScope: function() {
        this._wizardSharedService.resetScope();
    },

    setCurrentReportData: function (id, label, reportCategory) {
        var self = this;
        self.$scope.currentReportId           = id;
        self.$scope.savedSearchName.input     = "Copy_".concat(label);
        self.$scope.savedSearchCategory.input = reportCategory || '';
    },

    _reloadReport: function(id)
    {
        var self = this;
        if (id === '' || id === undefined )
        {
            var error = self._notificationService.createObjectForNotification('error', 500, 'Unable to load report');
            self._notificationService.setNotification(error.type, error.data);
            return;
        }
        else
        {
            var url = '/report/run/' + encodeURIComponent(id);
            self.$location.path(url);
        }
    },
    /*
     * When user clicks on public report checkbox
     */
    publicReport_disableRoles: function() {
        var self = this;
        var $scope = self.$scope;
        self._commonHelper.publicReport_disableRoles($scope.is_public.input, $scope);
    },
    // when user clicks on roles
    roles_disablePublicReport: function() {
        var self = this;
        var $scope = self.$scope;
        self._commonHelper.roles_disablePublicReport($scope.is_public.input, $scope);
    },

    checkIfObjEmpty: function (val)
    {
       var self = this;
       return self._commonHelper._isObjEmpty(val);
    }
});

resultController.$inject =
        [   '$scope',
            '$q',
            '$location',
            '$cookies',
            '$routeParams',
            'reportService',
            'wizardSharedService',
            'commonHelper',
            'notificationService',
            'paginationService',
            'modalWindowService'
        ];