'use strict';

/*global app:true*/

var app = angular.module('urcInstallerApp', [
  'ngAnimate',
  'ngCookies',
  'ngSanitize',
  'ui.router',
  'ui.bootstrap',
  //'ui.sortable',
  'ui.select',
  'mgcrea.ngStrap',
  'checklist-model',
  //'vr.directives.slider',
  'angular-loading-bar',
  'ngFx',
  'toastr',
  'mgo-angular-wizard',
  'xeditable',
  'angular-jwt',
  'ngTable',
  'ab-base64'
  ]);


app.constant('VERSION', '0.0.4131a');
app.constant('baseUrl', '/installer/api');

app.run(function(editableOptions) {
  editableOptions.theme = 'bs3';
});

app.run( function ($rootScope, $state, $stateParams, VERSION, Auth) {

  $rootScope.version = VERSION;
  $rootScope.$state = $state;
  $rootScope.$stateParams = $stateParams;
  $rootScope.previousState = {};

  $rootScope.$on('$stateChangeSuccess',  function (event, toState, toParams, fromState, fromParams) {
     $rootScope.previousState.name = fromState.name;
     $rootScope.previousState.params = fromParams;
  });

  $rootScope.$on('$stateChangeStart', function (event, toState, toParams, fromState, fromParams) {
    Auth.currentUser().then(function(user) {
      console.log(user);

      if (!toState.auth) {
        console.info('Route does not require authentication.');
      } else {
        console.info('Route requires authentication.');
      }

      if (user) {
        console.info('User is authenticated.');
      } else {
        console.error('User is not authenticated.');
      }

      if (fromState.auth && !toState.auth && user) {
        console.warn('Going from Auth route to non Auth route');
          //event.preventDefault();
      } else if (toState.auth && !user) {
        console.error('Routing back to Login page.');
        $state.go('login', {e: 401});
        //event.preventDefault(); 
      } else if (toState.auth && user) {
        //console.info('Route requires authentication and user is authenticated.');
      }
    });
  });
});


app.factory('authInterceptor', function ($rootScope, $q, $injector) {
  return {
    request: function(req) {
      var d = $q.defer();
      $injector.get('Auth').currentUser().then(function(user) {
        if(user) {
          req.headers.Authorization = 'Bearer ' + user.token;
          d.resolve(req);
        } else {
          d.resolve(req);
        }
      });
      return d.promise;
    },
    responseError: function (response) {
      if (response.status === 401) {
        $injector.get('User').logout();
        $injector.get('$state').go('login', {e: '401'});
        return $q.reject(response);
      } else {
        return $q.reject(response); 
      }
    }
  };
});


app.config(function ($httpProvider) {
  $httpProvider.interceptors.push('authInterceptor');
});


app.config(function ($stateProvider, $urlRouterProvider, $locationProvider) {
  // For any unmatched url, redirect to /state1
  $urlRouterProvider.otherwise('/login');

  // use the HTML5 History API
  //$locationProvider.html5Mode(true);

  // Now set up the states
  $stateProvider
  .state('login', {
    auth:false,
    url: '/login?e',
    templateUrl: 'views/installer/login.html',
    controller: 'LoginController'
  })
  .state('home', {
    auth: true,
    url: '/home',
    templateUrl: 'views/installer/home.html'
  })
  .state('new', {
    auth: true,
    url: '/new',
    templateUrl: 'views/installer/new.html',
    controller: 'NewRequestController',
    resolve: {
      availableModels: function($q, toastr, Registration) {
        var d = $q.defer();

        Registration.getModelTypes()
        .then(function(response) {
          if(response.data.result) {
            d.resolve(JSON.parse(response.data.data));
          } else {
            toastr.error(response.data.error);
            d.reject();
          }
        })
        .catch(toastr.error);
        
        return d.promise;
      },
      categories: function(toastr, Database) {
        console.log('here');
        return Database.retreiveDeviceTypes().catch(toastr.error);  
        //return ['TV, SAT'];
      }
    }
  })
  .state('requests', {
    auth: true,
    url: '/requests',
    templateUrl: 'views/installer/requests.html',
    controller: 'RequestsController'
  })

  // Import 화면
  .state('import', {
    auth: true,
    abstract: true,
    url: '/import',
    template: '<div ui-view=""></div>',
    controller: 'ImportController',
    resolve: {
      availableModels: function($q, toastr, Registration) {
        var d = $q.defer();

        Registration.getModelTypes()
          .then(function(response) {
            if(response.data.result) {
              d.resolve(JSON.parse(response.data.data));
            } else {
              toastr.error(response.data.error);
              d.reject();
            }
          })
          .catch(toastr.error);

        return d.promise;
      },
      currentJobId: function($q, Systems) {
        var d = $q.defer();

        d.resolve(Systems.getCurrentJobId());

        return d.promise;
      }
    }
  })

  // Import - Enter your programming key 화면
  .state('import.options', {
    auth: true,
    url: '/options',
    templateUrl: 'views/installer/import/options.html',
    controller: 'ImportOptionsController'
  })

  // Import - setup primary base 화면
  .state('import.add-new-system', {
    auth: true,
    url: '/add-new-system',
    templateUrl: 'views/installer/import/add-new-system.html',
    controller: 'ImportAddNewSystemController',
    resolve: {
      timeZones: function($q, Timezones) {
        var d = $q.defer();

        Timezones.getAll().then(function(data) {
          d.resolve(data);
        }).catch(function(error) {
          d.reject(error);
        });

        return d.promise;
      }
    }
  })

  // Import - Select a control base to assign 화면
  .state('import.select-base', {
    auth: true,
    url: '/select-base?id',
    templateUrl: 'views/installer/import/select-base.html',
    controller: 'ImportSelectBaseController',
    resolve: {
      // system 정보 얻기
      currentSystem: function($q, $window, Systems) {
        var d = $q.defer(),
          user = JSON.parse($window.localStorage.getItem('hcm_installer'));

        if (Systems.getCurrentSystem()) {
          console.log('in resolve');
          d.resolve(Systems.getCurrentSystem());
        } else if (user.system_id) {
          Systems.updateSystem(user.system_id, user.userInfo).then(function(data) {
            d.resolve(Systems.getCurrentSystem());
          }).catch(function(error) {
            d.reject(error);
          });
        } else {
          d.resolve({});
        }
        return d.promise;
      }
    }
  })

  // Import - Assign discovered device 화면
  .state('import.assign-base', {
    auth: true,
    url: '/assign-base',
    templateUrl: 'views/installer/import/assign-base.html',
    controller: 'ImportAssignBaseController',
    resolve: {
      // system 정보 얻기
      currentSystem: function($q, $window, Systems) {
        var d = $q.defer(),
          user = JSON.parse($window.localStorage.getItem('hcm_installer'));

        if (Systems.getCurrentSystem()) {
          console.log('in resolve');
          d.resolve(Systems.getCurrentSystem());
        } else if (user.system_id) {
          Systems.updateSystem(user.system_id, user.userInfo).then(function(data) {
            d.resolve(Systems.getCurrentSystem());
          }).catch(function(error) {
            d.reject(error);
          });
        } else {
          d.resolve({});
        }
        return d.promise;
      },
      // base station 검색 결과 목록
      searchResults: function ($q, toastr, Systems) {
        var d = $q.defer(),
          userInfo = Systems.getUserInfo(),
          selectedBstation = Systems.getSelectedBstation();

        Systems.searchHardware(selectedBstation.bstationType, {userInfo: userInfo}).then(
          function(data) {
            d.resolve(data);
          },
          function (error) {
            if (error.match('NO DEVICE')) {
              d.resolve({});
            } else {
              toastr.error(error);
              d.reject(error);
            }
          }
        );
        return d.promise;
      }
    }
  })

  // Import - Select a remote control to assign 화면
  .state('import.select-remote', {
    auth: true,
    url: '/select-remote?id',
    templateUrl: 'views/installer/import/select-remote.html',
    controller: 'ImportSelectRemoteController',
    resolve: {
      // system 정보 얻기
      currentSystem: function($q, $window, Systems) {
        var d = $q.defer(),
          user = JSON.parse($window.localStorage.getItem('hcm_installer'));

        if (Systems.getCurrentSystem()) {
          console.log('in resolve');
          d.resolve(Systems.getCurrentSystem());
        } else if (user.system_id) {
          Systems.updateSystem(user.system_id, user.userInfo).then(function(data) {
            d.resolve(Systems.getCurrentSystem());
          }).catch(function(error) {
            d.reject(error);
          });
        } else {
          d.resolve({});
        }
        return d.promise;
      }
    }
  })

  // Import - Assign discovered device 화면
  .state('import.assign-remote', {
    auth: true,
    url: '/assign-remote',
    templateUrl: 'views/installer/import/assign-remote.html',
    controller: 'ImportAssignRemoteController',
    resolve: {
      // system 정보 얻기
      currentSystem: function($q, $window, Systems) {
        var d = $q.defer(),
          user = JSON.parse($window.localStorage.getItem('hcm_installer'));

        if (Systems.getCurrentSystem()) {
          console.log('in resolve');
          d.resolve(Systems.getCurrentSystem());
        } else if (user.system_id) {
          Systems.updateSystem(user.system_id, user.userInfo).then(function(data) {
            d.resolve(Systems.getCurrentSystem());
          }).catch(function(error) {
            d.reject(error);
          });
        } else {
          d.resolve({});
        }
        return d.promise;
      },
      // base station 검색 결과 목록
      searchResults: function ($q, toastr, Systems) {
        var d = $q.defer(),
          userInfo = Systems.getUserInfo(),
          selectedRemote = Systems.getSelectedRemote();

        Systems.searchHardware(selectedRemote.remoteType, {userInfo: userInfo}).then(
          function(data) {
            d.resolve(data);
          },
          function (error) {
            if (error.match('NO DEVICE')) {
              d.resolve({});
            } else {
              toastr.error(error);
              d.reject(error);
            }
          }
        );
        return d.promise;
      }
    }
  })

  // Import - Input IP addresses for network devices 화면
  .state('import.assign-ip-address', {
    auth: true,
    url: '/assign-ip-address',
    templateUrl: 'views/installer/import/assign-ip-address.html',
    controller: 'ImportAssignIpAddressController',
    resolve: {
      // system 정보 얻기
      currentSystem: function($q, $window, Systems) {
        var d = $q.defer(),
          user = JSON.parse($window.localStorage.getItem('hcm_installer'));

        if (Systems.getCurrentSystem()) {
          console.log('in resolve');
          d.resolve(Systems.getCurrentSystem());
        } else if (user.system_id) {
          Systems.updateSystem(user.system_id, user.userInfo).then(function(data) {
            d.resolve(Systems.getCurrentSystem());
          }).catch(function(error) {
            d.reject(error);
          });
        } else {
          d.resolve({});
        }
        return d.promise;
      }
    }
  })

  // Import - Review your work 화면
  .state('import.review', {
    auth: true,
    url: '/review',
    templateUrl: 'views/installer/import/review.html',
    controller: 'ImportReviewController',
    resolve: {
      // system 정보 얻기
      currentSystem: function($q, $window, Systems) {
        var d = $q.defer(),
          user = JSON.parse($window.localStorage.getItem('hcm_installer'));

        if (Systems.getCurrentSystem()) {
          console.log('in resolve');
          d.resolve(Systems.getCurrentSystem());
        } else if (user.system_id) {
          Systems.updateSystem(user.system_id, user.userInfo).then(function(data) {
            d.resolve(Systems.getCurrentSystem());
          }).catch(function(error) {
            d.reject(error);
          });
        } else {
          d.resolve({});
        }
        return d.promise;
      }
    }
  });

});

