//
// app module for online DPMS
//
var app = angular.module('adminApp', ['ui.tree', 'ui.bootstrap', 'ui.bootstrap.tpls', 'ui.event', 'pascalprecht.translate', 'ngMessages', 'ui.utils',
        'ngRoute', 'ngCookies', 'ngSanitize', 'ct.ui.router.extras', 'chieffancypants.loadingBar', 'ngDraggable', 'ngFileUpload', 'LocalStorageModule', 'exceptionless',
        'app.config', 'app.common', 'app.webservices', 'app.framework', 'app.infrastructure', 'app.basicData', 'app.adminHomePage', 'app.noPermissionPage', 'pasvaz.bindonce', 'vs-repeat', 'ivh.treeview', 'angular-cache',
        'app.systemConfiguration', 'app.cache', 'angularBootstrapNavTree', 'ngAnimate', 'cgNotify', 'angularInlineEdit'
])
    //run blocks are executed after the injector is created and are the first
    //methods that are executed in any Angular app.
    .run(['$log', '$http', 'CacheFactory', '$rootScope', 'userService', 'loginContext', '$q', function ($log, $http, CacheFactory, $rootScope, userService, loginContext, $q) {
        $log.debug('adminApp.run()...');

        $rootScope.adminPermission = constant.adminPermission;

        // 控制用户admin操作权限
        $rootScope.checkUserPermission = function (permissionCode) {
            var deferred = $q.defer();
            var promise = deferred.promise;
            var ret = false;
            userService.getUserPermissionNew(loginContext.userName, function (data) {
                var ret = window.PWC.isHavePermission(permissionCode, data);
                deferred.resolve(ret);
            });

            var successFunction = function (fn) {
                promise.then(function (ret) {
                    fn(ret);
                });
                return this;
            }

            return {
                success: successFunction,
            };
        };

        // 控制用户admin操作权限
        $rootScope.checkUserPermissionList = function (permissionCodeList) {
            var deferred = $q.defer();
            var promise = deferred.promise;
            var model = {};
            userService.getUserPermissionNew(loginContext.userName, function (data) {


                permissionCodeList.forEach(function (permissionCode) {
                    var ret = window.PWC.isHavePermission(permissionCode, data);
                    model[permissionCode] = ret;
                });

                deferred.resolve(model);
            });

            var successFunction = function (fn) {
                promise.then(function (model) {
                    fn(model);
                });
                return this;
            }

            return {
                success: successFunction,
            };
        };

        $http.defaults.headers.common['X-XSRF-Token'] =
            angular.element('input[name="__RequestVerificationToken"]').attr('value');
    }])
    // We always place constant at the beginning of all configuration blocks.
    .constant('application', {
        // the current logged on user
        currentUser: {},
        // convert date to display time based on current user
        toDisplayTimeString: function (dateTime) {
            if (!_.isDate(dateTime)) {
                throw new TypeError('"dateTime" should be "Date" type!');
            }
            return dateTime.toString('h:mmtt').toLowerCase();
        },
        // define angular events for $broadcast/$emit and $on
        events: {
            beforeUnload: 'event:beforeUnload',
            navigateToTab: 'event:navigateToTab',
            showNotificationBar: 'event:showNotificationBar'
        }
    })
    .config(['$urlRouterProvider', function ($urlRouterProvider) {
        //$urlRouterProvider.otherwise('/basicDataInfrastructure/regionManage'); 
    }])
    // only providers and constants should be injected in config block
    .config(['$logProvider', '$translateProvider', '$translatePartialLoaderProvider', 'region', '$compileProvider',
        function ($logProvider, $translateProvider, $translatePartialLoaderProvider, region, $compileProvider) {
            'use strict';
            region = 'zh-CN';
            // to disable various debug runtime information in the compiler to DOM elements.
            $compileProvider.debugInfoEnabled(false);
            // enable output $log.debug by default
            $logProvider.debugEnabled(true);

            // angular-translate configuration
            var configurateTranslation = function () {

                $translateProvider.useLoader('$translatePartialLoader', {
                    // the translation table are organized by language and module under folder 'app/i18n/'
                    urlTemplate: '/app-resources/i18n/{lang}/{part}.json'
                });

                $translateProvider
                    .preferredLanguage(region)
                    .fallbackLanguage(region);

                //https://github.com/Contactis/translations-manager/issues/7
                //https://angular-translate.github.io/docs/#/guide/19_security
                $translateProvider.useSanitizeValueStrategy('escape');
            };

            configurateTranslation();
        }
    ])
    // IE10 fires input event when a placeholder is defined so that form element is in dirty instead of pristine state 
    // refer to: https://github.com/angular/angular.js/issues/2614
    .config(['$provide', function ($provide) {
        $provide.decorator('$sniffer', ['$delegate', function ($sniffer) {
            var msieVersion = parseInt((/msie (\d+)/.exec(angular.lowercase(navigator.userAgent)) || [])[1], 10);
            var hasEvent = $sniffer.hasEvent;
            $sniffer.hasEvent = function (event) {
                if (event === 'input' && msieVersion === 10) {
                    return false;
                }
                hasEvent.call(this, event);
            };
            return $sniffer;
        }]);
    }])
    .config(['$ExceptionlessClient', 'exceptionlessServerURL', function ($ExceptionlessClient, exceptionlessServerURL) {
        if (!PWC.isNullOrEmpty(exceptionlessServerURL)) {
            $ExceptionlessClient.config.apiKey = 'HK0XK49LbufV6E4q8HLW7CGncwSBJvdBrJQwUnzw';
            $ExceptionlessClient.config.serverUrl = exceptionlessServerURL;
            $ExceptionlessClient.config.setUserIdentity('0', 'Anonymous');
            $ExceptionlessClient.config.useSessions();
            $ExceptionlessClient.config.defaultTags.push('JavaScript', 'Angular');
        }
    }])
    .config(['CacheFactoryProvider', function (CacheFactoryProvider) {
        var options = {
            storageMode: 'localStorage', // This cache will use `localStorage`.
            storagePrefix: 'atms.'
        };
        if (!window.localStorage) {
            options.storageImpl = localStoragePolyfill;
        }
        angular.extend(CacheFactoryProvider.defaults, options);
    }])
    .config(['ivhTreeviewOptionsProvider', function (ivhTreeviewOptionsProvider) {
        ivhTreeviewOptionsProvider.set({
            defaultSelectedState: false,
            validate: true,
            // Twisties can be images, custom html, or plain text
            twistieCollapsedTpl: '<i class="fa fa-plus" aria-hidden="true"></i>',
            twistieExpandedTpl: '<i class="fa fa-minus" aria-hidden="true"></i>',
            twistieLeafTpl: '<span style="color:white">&#9679;</span>'
        });
    }])
    // refer to: https://github.com/oitozero/ngSweetAlert
    .factory('SweetAlert', ['$rootScope', '$log', '$translate', function ($rootScope, $log, $translate) {
        $log.debug('SweetAlert.run()...');
        var swal = window.swal;
        //public methods
        var self = {

            swal: function (arg1, arg2, arg3) {
                $rootScope.$evalAsync(function () {
                    if (typeof (arg2) === 'function') {
                        swal(arg1, function (isConfirm) {
                            $rootScope.$evalAsync(function () {
                                arg2(isConfirm);
                            });
                        }, arg3);
                    } else {
                        swal(arg1, arg2, arg3);
                    }
                });
            },
            success: function (title, message) {
                $rootScope.$evalAsync(function () {
                    //swal(title, message, 'success');

                    swal({
                        title: title,
                        text: message,
                        type: "success",
                        confirmButtonText: $translate.instant('Confirm'),
                    });
                });
            },
            error: function (title, message) {
                $rootScope.$evalAsync(function () {
                    //swal(title, message, 'error');
                    swal({
                        title: title,
                        text: message,
                        type: "error",
                        confirmButtonText: $translate.instant('Confirm'),
                    });

                });
            },
            warning: function (title, message) {
                $rootScope.$evalAsync(function () {
                    //swal(title, message, 'warning');
                    swal({
                        title: title,
                        text: message,
                        type: "warning",
                        confirmButtonText: $translate.instant('Confirm'),
                    });
                });
            },
            info: function (title, message) {
                $rootScope.$evalAsync(function () {
                    //swal(title, message, 'info');
                    swal({
                        title: title,
                        text: message,
                        type: "info",
                        confirmButtonText: $translate.instant('Confirm'),
                    });
                });
            }
        };

        return self;
    }])
    //turn off angular-loading-bar spinner
    //refer to https://github.com/chieffancypants/angular-loading-bar
    .config(['cfpLoadingBarProvider', function (cfpLoadingBarProvider) {
        cfpLoadingBarProvider.includeSpinner = false;
    }])
    //initialize localStorage
    //refer to https://github.com/grevory/angular-local-storage#get-started
    .config(['localStorageServiceProvider', function (localStorageServiceProvider) {
        localStorageServiceProvider.setPrefix('pwcdashboard').setStorageType('sessionStorage');
    }])
    // Provide the localization function for application and support async load translation table by parts on demand.
    // Note: When trying to adding new translation resource into .json file, please check if the same KEY is existing 
    // in .json files under i18n folder. Because if two parts have the same property, the property value will be overwrited 
    // by the loaded last part.
    // for example,
    // We load app.json first and then load patient.json. "app.json" file contains a property {"Text" : "Test"} 
    // and "patient.json" file contains property {"Text" : "Overwrite Test"} the "Text" on view will be translated to 
    // be "Overwrite Test".
    .factory('appTranslation', ['$log', '$translatePartialLoader', '$translate',
        function ($log, $translatePartialLoader, $translate) {
            'use strict';
            $log.debug('appTranslation.ctor()...');

            var translation = {
                // part names for modules
                // AppPart is for the translation of application level, not for a module for a business logic.
                appPart: 'app',
                vat:'vat',

                // other parts for business logic
                //worklist: 'worklist',
                //registration: 'registration',
                //report: 'report',
                //clientSetting: 'clientSetting',
                //selfServiceSetting: 'selfServiceSetting',
                cit: 'cit',
                //menu: 'menu',
                role: 'role',
                infrastructure: 'infrastructure',
                //materiallist: 'materiallist',
                basicData: 'basicData',
                systemConfiguration: 'systemConfiguration',
                adminHomePage: 'adminHomePage',
                taxDocumentList: 'taxDocumentList',
                noPermissionPage: 'noPermissionPage',
                //declarationFormConfiguration: 'declarationFormConfiguration',

                /// <summary>
                /// async load translation tables into application for specified part names that required for the view.
                /// </summary>
                /// <param name="partNames">part names of array type</param>
                load: function (partNames) {
                    if (!angular.isArray(partNames)) {
                        throw new TypeError('"partNames" should be an array!');
                    }

                    partNames.forEach(function (name) {
                        $translatePartialLoader.addPart(name);
                    });

                    $translate.refresh();
                },
                loadAll: function () {
                    _.map(_.values(translation), function (part) {
                        if (_.isString(part)) {
                            $translatePartialLoader.addPart(part);
                        }
                    });
                    $translate.refresh();
                }
            };
            return translation;
        }
    ])
    .controller('AdminAppController', ['$rootScope', '$scope', '$log', '$location', '$translate', '$translatePartialLoader',
        '$window', 'appRoute', 'application', 'appTranslation', '$timeout', '$uibModal', 'loginContext', '$ExceptionlessClient', 'signalRSvc', 'userService', '$state', '$q',
       'exceptionlessServerURL', function ($rootScope, $scope, $log, $location, $translate, $translatePartialLoader, $window, appRoute,
            application, appTranslation, $timeout, $uibModal, loginContext, $ExceptionlessClient, signalRSvc, userService, $state, $q, exceptionlessServerURL) {
           'use strict';
           $log.debug('AdminAppController.ctor()...');

           $scope.localName = loginContext.localName;

           if (!PWC.isNullOrEmpty(exceptionlessServerURL)) {
               $ExceptionlessClient.config.setUserIdentity(loginContext.userId, loginContext.localName);
               $ExceptionlessClient.config.useSessions();
           }

           $scope.$on('$locationChangeSuccess', function () {
               $scope.actualLocation = $location.path();
           });

           $scope.$watch(function () {
               return $location.path()
           }, function (newLocation) {
               if ($scope.actualLocation === newLocation) {
                   // back or forward
                   $log.debug('Go back or go forward to view browser history. Url: ' + newLocation);
               }
           });

           $scope.$on('$stateChangeSuccess',
               function () {
                   $log.debug('$stateChangeSuccess: ');
               });

           $scope.$on("$locationChangeStart", function (e, currentLocation, previousLocation) {
               // Do whatever you need to do.
               $rootScope.previousLocation = previousLocation;

           });

           $rootScope.$on('$stateChangeStart', function (event, toState, toParams, fromState, fromParams) {

               // permission control
               var url = toState.url;
               // url: /organizationBusinessUnitView

               if (toState.name) {

                   // 特殊处理有name中有.,也就是那种tab的情况
                   if (toState.name.indexOf('organizationView') > -1) {
                       url = '#/organizationViewInfrastructure' + url;
                   } else if (toState.name.indexOf('masterData.') > -1) {
                       url = '#/masterData' + url;
                   } else if (toState.name.indexOf('financialData.') > -1) {
                       url = '#/financialData' + url;
                   }

                   else {
                       url = '#' + url;
                   }

               } else {
                   url = '#' + url;
               }

               $log.debug('url:' + url + 'toState:' + JSON.stringify(toState));
               if (url.indexOf('noPermissionPage') > -1) {
                   return;
               }

               userService.getUserPermission(loginContext.userName).success(function (data) {
                   var find = null;
                   if (data.navigationUrlList) {
                       find = _.find(data.navigationUrlList, function (num) {

                           // 完全匹配
                           if (url === num) {
                               return true;
                           }

                           // 匹配查询单个机构这种
                           if (url.indexOf(num) > -1) {
                               return true;
                           }

                           return false;
                       });
                   }
                   if (data && (data.isAdmin || find)) {
                       return;
                   } else {
                       $log.debug(url + ':noPermissionPage');
                       event.preventDefault();
                       $state.go('noPermissionPage');
                   }
               });

           });


           // publish unbeforeunload event to child scopes
           $scope.onbeforeunload = function () {
               $scope.$broadcast(application.events.beforeUnload);
           };

           $scope.main = function () {
               $location.path('/main');
               $location.url('main');
           };

           $scope.createDemo = function () {
               $location.path('/accountDemo');
               $location.url($location.path());
           };

           appTranslation.loadAll();

           signalRSvc.initialize();
       }
    ]);