'use strict';
define(['angular'], function () {
  // Declare app level module which depends on views, and core components
  var angularJSApp = angular.module('angularJSApp', [
    'ngRoute',
    'ngCookies',
    'ngSanitize',
    'ngAnimate',
    'ngToast',
    'ngFileSaver',
    'ngFileUpload',
    'ngclipboard',
    'ui.bootstrap.contextMenu',
    'ui.router',
    'ui.router.state.events',
    'ui.bootstrap',
    'pascalprecht.translate',
    'oc.lazyLoad',
    'angularJSApp.session',
    'angularJSApp.constant',
    'angularJSApp.utils',
    'angularJSApp.directives',
    'angularJSApp.config_server',
    'chart.js',
  ]);
  angularJSApp
    /**
     * Config Oclazy loading
     */
    .config([
      '$ocLazyLoadProvider',
      'AppConfig',
      '$qProvider',
      function ($ocLazyLoadProvider, AppConfig, $qProvider) {
        var modules = [
          {
            name: 'loginModule',
            files: [
              'components/login/aes256/AESUtil.js',
              'components/login/aes256/aes.js',
              'components/login/aes256/pbkdf2.js',
              'components/login/login.js',
              'components/login/login.css',
            ],
          },
          {
            name: 'forgotPasswordModule',
            files: [
              'components/login/aes256/AESUtil.js',
              'components/login/aes256/aes.js',
              'components/login/aes256/pbkdf2.js',
              'components/user/forgot-password/forgot-password.js',
              'components/user/forgot-password/forgot-password.css',
            ],
          },
          {
            name: 'resetPasswordModule',
            files: [
              'components/login/aes256/AESUtil.js',
              'components/login/aes256/aes.js',
              'components/login/aes256/pbkdf2.js',
              'components/user/reset-password/reset-password.js',
              'components/user/reset-password/reset-password.css',
            ],
          },
          {
            name: 'changeEmailModule',
            files: ['components/user/change-email/change-email.js'],
          },
          {
            name: 'myAccountModule',
            files: [
              'components/login/aes256/AESUtil.js',
              'components/login/aes256/aes.js',
              'components/login/aes256/pbkdf2.js',
              'components/user/my-account/my-account.js',
              'components/user/my-account/my-account.css',
            ],
          },
          {
            name: 'signUpModule',
            files: [
              'components/login/aes256/AESUtil.js',
              'components/login/aes256/aes.js',
              'components/login/aes256/pbkdf2.js',
              'components/account/sign-up/sign-up.js',
              'components/account/sign-up/sign-up.css',
            ],
          },
          {
            name: 'trackingPageModule',
            files: [
              'lib/daterangepicker/daterangepicker.css',
              'components/tracking/tracking-page/tracking-page.js',
              'components/tracking/tracking-page/tracking-page.css',
            ],
          },
          {
            name: 'myEmailModule',
            files: [
              'components/email/my-email/my-email.js',
              'components/email/my-email/my-email.css',
            ],
          },
          {
            name: 'cardInfoModule',
            files: ['components/card-info/card-info.js', 'components/card-info/card-info.css'],
          },
          {
            name: 'paymentModule',
            files: ['components/payment/payment.js', 'components/payment/payment.css'],
          },
          {
            name: 'upgradeAccountModule',
            files: [
              'components/payment/upgrade-account/upgrade-account.js',
              'components/payment/upgrade-account/upgrade-account.css',
            ],
          },
          {
            name: 'linkViewDownloadModule',
            files: ['components/link/view-download-ctrl.js', 'components/link/view-download.css'],
          },
          {
            name: 'dashboardModule',
            files: [
              'components/dashboard/dashboard/dashboard.js',
              'components/dashboard/dashboard/dashboard.css',
            ],
          },
          {
            name: 'authorizedModule',
            files: ['components/authorized/authorized-ctrl.js'],
          },
        ];

        // Read config value
        if (angular.isDefined(AppConfig.OCLAZY_CACHE_MODULE)) {
          angular.forEach(modules, function (v) {
            v.cache = AppConfig.OCLAZY_CACHE_MODULE;
          });
        }
        $qProvider.errorOnUnhandledRejections(false);
        // We define some files for a specific module
        $ocLazyLoadProvider.config({
          modules: modules,
        });
      },
    ])

    /**
     * UI-Router config with ocLazy load module
     *
     * @param {type} $stateProvider
     * @param {type} $urlRouterProvider
     * @returns {undefined}
     */
    .config([
      '$stateProvider',
      '$urlRouterProvider',
      '$urlMatcherFactoryProvider',
      '$locationProvider',
      function ($stateProvider, $urlRouterProvider, $urlMatcherFactoryProvider, $locationProvider) {
        $locationProvider.hashPrefix('!');
        $urlRouterProvider.otherwise('/login');

        $stateProvider
          .state({
            name: 'unauthorized',
            abstract: true,
            templateUrl: 'components/authorized/unauthorized-tmpl.html',
            controller: [
              '$scope',
              'session',
              '$rootScope',
              function ($scope, session, $rootScope) {
                // TODO
              },
            ],
          })
          .state({
            name: 'login',
            url: '/login?key',
            templateUrl: 'components/login/login-tmpl.html',
            controller: 'LoginCtrl as Ctrl',
            resolve: {
              loadModule: [
                '$ocLazyLoad',
                function ($ocLazyLoad) {
                  return $ocLazyLoad.load('loginModule');
                },
              ],
              catchEventAutoLogin: [
                'session',
                '$stateParams',
                '$cookies',
                '$state',
                'AppConfig',
                function (session, $stateParams, $cookies, $state, AppConfig) {
                  if ($stateParams.key) {
                    if (session.getAccessToken()) {
                      // clear user into session
                      localStorage.removeItem(AppConfig.TOKEN_COOKIE_NAME);
                      $cookies.remove(AppConfig.TOKEN_COOKIE_NAME);
                    }
                    session.setAccessToken($stateParams.key, '');

                    // check use_secure_mail
                    session.getAuthUser(function (data) {
                      console.log('data', data);
                      if (data) {
                        if (!data.use_secure_mail) {
                          localStorage.removeItem(AppConfig.TOKEN_COOKIE_NAME);
                          $cookies.remove(AppConfig.TOKEN_COOKIE_NAME);
                        } else {
                          $state.go('dashboard');
                        }
                      }
                    });
                  }
                },
              ],
            },
          })
          .state({
            name: 'authorized',
            abstract: true,
            templateUrl: 'components/authorized/authorized-tmpl.html',
            controller: 'AuthorizedCtrl as Ctrl',
            resolve: {
              loadModule: [
                '$ocLazyLoad',
                function ($ocLazyLoad) {
                  return $ocLazyLoad.load('authorizedModule');
                },
              ],
              authen: [
                'session',
                '$state',
                '$q',
                '$location',
                function (session, $state, $q) {
                  // Private state
                  var deferred = $q.defer();
                  if (session.getAccessToken()) {
                    session.getAuthUser(function (data) {
                      console.log('data', data);
                      deferred.resolve(data);
                    });
                  } else {
                    // Require authen - Redirect to login page
                    session.authenticationRequiredHandler();
                    // Reject this route
                    deferred.reject('Unauthorized');
                  }
                  return deferred.promise;
                },
              ],
            },
          })
          .state({
            name: 'forgotPassword',
            url: '/forgotpass',
            templateUrl: 'components/user/forgot-password/forgot-password-tmpl.html',
            controller: 'ForgotPasswordCtrl as Ctrl',
            resolve: {
              loadModule: [
                '$ocLazyLoad',
                function ($ocLazyLoad) {
                  return $ocLazyLoad.load('forgotPasswordModule');
                },
              ],
            },
          })
          .state({
            name: 'resetPass',
            url: '/resetpass/:token?hash&keep&team',
            title: 'page_title.create_password',
            templateUrl: 'components/user/reset-password/reset-password-tmpl.html',
            autoRedirect: false, // Using when token existing
            controller: 'ResetPassword as Ctrl',
            resolve: {
              loadModule: [
                '$ocLazyLoad',
                function ($ocLazyLoad) {
                  return $ocLazyLoad.load('resetPasswordModule');
                },
              ],
            },
          })
          .state({
            name: 'changeEmail',
            url: '/change-email/:confirm_code',
            templateUrl: 'components/user/change-email/change-email-tmpl.html',
            autoRedirect: false, // Using when token existing
            controller: 'ChangeEmail as Ctrl',
            resolve: {
              loadModule: [
                '$ocLazyLoad',
                function ($ocLazyLoad) {
                  return $ocLazyLoad.load('changeEmailModule');
                },
              ],
            },
          })
          .state({
            name: 'userProfile',
            parent: 'authorized',
            abstract: true,
            templateUrl: 'components/user/profile-tmpl.html',
            controller: [
              '$scope',
              'session',
              '$rootScope',
              function ($scope, session, $rootScope) {
                // TODO
              },
            ],
          })
          .state({
            name: 'myAccount',
            url: '/profile/my-account',
            parent: 'userProfile',
            templateUrl: 'components/user/my-account/my-account-tmpl.html',
            controller: 'MyAccountCtrl as Ctrl',
            resolve: {
              loadModule: [
                '$ocLazyLoad',
                function ($ocLazyLoad) {
                  return $ocLazyLoad.load('myAccountModule');
                },
              ],
            },
          })
          .state({
            name: 'signUp',
            url: '/sign-up',
            templateUrl: 'components/account/sign-up/sign-up-tmpl.html',
            controller: 'SignUpCtrl as Ctrl',
            resolve: {
              loadModule: [
                '$ocLazyLoad',
                function ($ocLazyLoad) {
                  return $ocLazyLoad.load('signUpModule');
                },
              ],
            },
          })
          .state({
            name: 'trackingPage',
            url: '/tracking/:project_id/:folder_id/:file_id/:file_type',
            parent: 'authorized',
            templateUrl: 'components/tracking/tracking-page/tracking-page-tmpl.html',
            controller: 'TrackingPageCtrl as Ctrl',
            resolve: {
              loadModule: [
                '$ocLazyLoad',
                function ($ocLazyLoad) {
                  return $ocLazyLoad.load('trackingPageModule');
                },
              ],
            },
          })
          .state({
            name: 'myEmail',
            url: '/my-email/:folder_id',
            parent: 'authorized',
            templateUrl: 'components/email/my-email/my-email-tmpl.html',
            controller: 'MyEmailCtrl as Ctrl',
            resolve: {
              loadModule: [
                '$ocLazyLoad',
                function ($ocLazyLoad) {
                  return $ocLazyLoad.load('myEmailModule');
                },
              ],
            },
          })
          .state({
            name: 'teamPayment',
            url: '/profile/billing',
            parent: 'userProfile',
            templateUrl: 'components/payment/payment-tmpl.html',
            controller: 'PaymentCtrl as Ctrl',
            resolve: {
              loadModule: [
                '$ocLazyLoad',
                function ($ocLazyLoad) {
                  return $ocLazyLoad.load('paymentModule');
                },
              ],
            },
          })
          // .state({
          //   name: 'upgradeAccount',
          //   url: '/profile/upgrade-account',
          //   parent: 'userProfile',
          //   templateUrl: 'components/payment/upgrade-account/upgrade-account-tmpl.html',
          //   controller: 'UpgradeAccountCtrl as Ctrl',
          //   resolve: {
          //     loadModule: [
          //       '$ocLazyLoad',
          //       function ($ocLazyLoad) {
          //         return $ocLazyLoad.load('upgradeAccountModule');
          //       },
          //     ],
          //   },
          // })
          .state({
            name: 'linkViewDownload',
            url: '/link-view-download/:project_id/:link_id',
            parent: 'unauthorized',
            templateUrl: 'components/link/view-download-tmpl.html',
            controller: 'ViewDownloadCtrl as Ctrl',
            resolve: {
              loadModule: [
                '$ocLazyLoad',
                function ($ocLazyLoad) {
                  return $ocLazyLoad.load('linkViewDownloadModule');
                },
              ],
            },
          })
          .state({
            name: 'dashboard',
            url: '/dashboard',
            parent: 'authorized',
            templateUrl: 'components/dashboard/dashboard/dashboard-tmpl.html',
            controller: 'DashBoardCtrl as Ctrl',
            resolve: {
              loadModule: [
                '$ocLazyLoad',
                function ($ocLazyLoad) {
                  return $ocLazyLoad.load('dashboardModule');
                },
              ],
            },
          });
      },
    ])

    /**
     * Config request
     * Set up interceptor
     */
    .config([
      '$httpProvider',
      'AppConfig',
      function ($httpProvider, AppConfig) {
        $httpProvider.defaults.headers.post['Content-Type'] = 'application/json;charset=utf-8';

        $httpProvider.interceptors.push(function ($q, $cookies, $state) {
          return {
            request: function (config) {
              var noToken = false;
              if (config.method === 'GET') {
                noToken = config.params ? config.params['noToken'] : false;
              }

              if (config.method === 'POST') {
                noToken = config.data ? config.data['noToken'] : false;
              }

              if (
                $state.current.name !== 'viewAndDownload' &&
                $state.current.name !== 'linkChangePassword' &&
                !noToken
              ) {
                // config.headers['auth-token'] = $cookies.get(AppConfig.TOKEN_COOKIE_NAME);
                // config.headers['auth-token'] = sessionStorage.getItem(AppConfig.TOKEN_COOKIE_NAME);
                config.headers['auth-token'] = localStorage.getItem(AppConfig.TOKEN_COOKIE_NAME);
              }
              return config;
            },
          };
        });
      },
    ])
    .config([
      'ngToastProvider',
      function (ngToast) {
        ngToast.configure({
          // verticalPosition: 'bottom',
          horizontalPosition: 'center',
          animation: 'fade',
        });
      },
    ])

    // where we will store the attempted url
    .value('redirectToUrlAfterLogin', { url: '/' })

    .run([
      '$rootScope',
      'session',
      'AppConfig',
      '$cookies',
      '$transitions',
      '$state',
      '$location',
      function ($rootScope, session, AppConfig, $cookies, $transitions, $state, $location) {
        $rootScope.loading = true;
        var warningLogCSS = 'font-size: 30px; color: red';

        $rootScope.$on(
          '$stateChangeStart',
          function (event, toState, toParams, fromState, fromParams, options) {
            // track the state the user wants to go to;
            // authorization service needs this
            $rootScope.toState = toState;
            // if the principal is resolved, do an
            // authorization check immediately. otherwise,
            // it'll be done when the state it resolved.
            var redirectPath = $location.search().redirectPath;
            if (redirectPath) {
              redirectPath = window.atob(redirectPath);
              // get current token
              var currentToken = session.getAccessToken();
              // implement login as user
              var prioritizeToken = $location.search().giraffe;
              if (prioritizeToken) {
                // remove current token
                if (currentToken) {
                  // clear user into session
                  localStorage.removeItem(AppConfig.TOKEN_COOKIE_NAME);
                  $cookies.remove(AppConfig.TOKEN_COOKIE_NAME);
                }
                // decrypt the token
                prioritizeToken = window.atob(prioritizeToken);
                session.setAccessToken(prioritizeToken, null);
                session.init(redirectPath);
              } else {
                if (currentToken) {
                  // redirect URL
                  window.location.href = redirectPath;
                } else {
                  var token = $location.search().tail;
                  if (token) {
                    //DECRYPT THE TOKEN
                    token = window.atob(token);
                    session.setAccessToken(token, null);
                    session.init(redirectPath);
                  }
                }
              }
            } else if (session.getAccessToken() && !redirectPath) {
              session.init();
            } else {
              // clear user into session
              localStorage.removeItem(AppConfig.TOKEN_COOKIE_NAME);
              $cookies.remove(AppConfig.TOKEN_COOKIE_NAME);
            }
          }
        );

        $transitions.onSuccess({}, function (trans) {
          $rootScope.current = $state.current;
          window.scrollTo(0, 0);
        });

        // Unauthorized event handler
        // This event is fired on $http interceptor
        // We can't inject the session because session is now using the interceptor
        $rootScope.$on('$cleanSession', function () {
          session.reset();
          session.authenticationRequiredHandler();
        });

        // Catch event load page
        $rootScope.$on(
          '$stateChangeSuccess',
          function (event, toState, toParams, fromState, fromParams) {
            // TODO
          }
        );

        // Route change error
        $rootScope.$on(
          '$stateChangeError',
          function (event, toState, toParams, fromState, fromParams, error) {
            // TODO
          }
        );

        $rootScope.$on('$viewContentLoaded', function (event) {
          // TODO
          $rootScope.loading = false;
        });
        $rootScope.$on('translateLanguageChange', function (t, v) {
          // Init lang validation
          $rootScope.lang = v;
        });
        $rootScope.$on('$userInfoHasChanged', function (event, user) {
          changeLanguages(user);
        });

        function changeLanguages(user) {
          var current = session.getUser();

          // Check whether language is the same or not
          // Dont put this compare in the changeLanguage method because
          // Maybe we make a mistake such as set user info first, so that it always equals
          if (current.lang !== user.lang) {
            // Do change language
            session.changeLanguage(user.lang);
          }
          // Set as new info
          session.setUser(user);
          // window.location.reload(true);
        }
      },
    ])

    /**
     * Config multiple languages
     */
    .config([
      '$translateProvider',
      function ($translateProvider) {
        // Language code: http://4umi.com/web/html/languagecodes.php || http://msdn.microsoft.com/en-us/library/ie/ms533052.aspx
        var lang = window.navigator.browserLanguage || window.navigator.language;
        var language = lang.substr(0, 2);
        if (typeof language === 'undefined') language = 'ja'; // set as default
        // configures staticFilesLoader
        $translateProvider.useStaticFilesLoader({
          prefix: 'i18n/lang-',
          suffix: '.json',
        });
        // load 'en' table on startup
        $translateProvider.preferredLanguage(language);
        // Wrap HTML in $sce.trustAsHtml(value)
        $translateProvider.useSanitizeValueStrategy('sce');
      },
    ]);

  return angularJSApp;
});
