/**
 * An element which displays the sign in form.
 */
angular.module('quay').directive('signinForm', function () {
  var directiveDefinitionObject = {
    priority: 0,
    templateUrl: '/static/directives/signin-form.html',
    replace: false,
    transclude: true,
    restrict: 'C',
    scope: {
      'inviteCode': '=inviteCode',
      'redirectUrl': '=redirectUrl',
      'signInStarted': '&signInStarted',
      'signedIn': '&signedIn'
    },
    controller: function($scope, $location, $timeout, $interval, ApiService, KeyService, UserService, CookieService, Features, Config) {
      $scope.tryAgainSoon = 0;
      $scope.tryAgainInterval = null;
      $scope.signingIn = false;

      $scope.markStarted = function() {
       $scope.signingIn = true;
       if ($scope.signInStarted != null) {
         $scope.signInStarted();
       }
      };

      $scope.cancelInterval = function() {
        $scope.tryAgainSoon = 0;

        if ($scope.tryAgainInterval) {
          $interval.cancel($scope.tryAgainInterval);
        }

        $scope.tryAgainInterval = null;
      };

      $scope.$watch('user.username', function() {
        $scope.cancelInterval();
      });

      $scope.$on('$destroy', function() {
        $scope.cancelInterval();
      });

      $scope.signin = function() {
        if ($scope.tryAgainSoon > 0) { return; }

        $scope.markStarted();
        $scope.cancelInterval();

        if ($scope.inviteCode) {
          $scope.user['invite_code'] = $scope.inviteCode;
        }

        ApiService.signinUser($scope.user).then(function() {
          $scope.signingIn = false;
          $scope.needsEmailVerification = false;
          $scope.invalidCredentials = false;
          $scope.invalidCredentialsMessage = null;

          if ($scope.signedIn != null) {
            $scope.signedIn();
          }

          // Load the newly created user.
          UserService.load();

          // Redirect to the specified page or the landing page
          // Note: The timeout of 500ms is needed to ensure dialogs containing sign in
          // forms get removed before the location changes.
          $timeout(function() {
            var redirectUrl = $scope.redirectUrl;
            if (redirectUrl == $location.path() || redirectUrl == null) {
              return;
            }
            window.location = (redirectUrl ? redirectUrl : '/');
          }, 500);
        }, function(result) {
          $scope.signingIn = false;

          if (result.status == 429 /* try again later */) {
            $scope.needsEmailVerification = false;
            $scope.invalidCredentials = false;
            $scope.invalidCredentialsMessage = null;

            $scope.cancelInterval();

            $scope.tryAgainSoon = result.headers('Retry-After');
            $scope.tryAgainInterval = $interval(function() {
              $scope.tryAgainSoon--;
              if ($scope.tryAgainSoon <= 0) {
                $scope.cancelInterval();
              }
            }, 1000, $scope.tryAgainSoon);
          } else if (result.status == 400) {
            bootbox.alert(ApiService.getErrorMessage(result));
          } else {
            $scope.needsEmailVerification = result.data.needsEmailVerification;
            $scope.invalidCredentials = result.data.invalidCredentials;
            $scope.invalidCredentialsMessage = result.data.message;
          }
        });
      };
    }
  };
  return directiveDefinitionObject;
});
