(function() {
  /**
   * Page to create a new repository.
   */
  angular.module('quayPages').config(['pages', function(pages) {
   pages.create('new-repo', 'new-repo.html', NewRepoCtrl, {
      'newLayout': true,
      'title': 'New Repository',
      'description': 'Create a new Docker repository'
    })
  }]);

  function NewRepoCtrl($scope, $location, $http, $timeout, UserService, ApiService, PlanService, TriggerService, Features) {
    UserService.updateUserIn($scope);

    $scope.Features = Features;
    $scope.TriggerService = TriggerService;

    $scope.repo = {
      'is_public': 0,
      'description': '',
      'initialize': ''
    };

    // Watch the namespace on the repo. If it changes, we update the plan and the public/private
    // accordingly.
    $scope.isUserNamespace = true;
    $scope.$watch('repo.namespace', function(namespace) {
      // Note: Can initially be undefined.
      if (!namespace) { return; }

      var isUserNamespace = (namespace == $scope.user.username);

      $scope.planRequired = null;
      $scope.isUserNamespace = isUserNamespace;

      // Determine whether private repositories are allowed for the namespace.
      checkPrivateAllowed();
    });

    $scope.changeNamespace = function(namespace) {
      $scope.repo.namespace = namespace;
    };

    $scope.handleBuildStarted = function() {
      var repo = $scope.repo;
      $location.path('/repository/' + repo.namespace + '/' + repo.name);
    };

    $scope.handleBuildFailed = function(message) {
      var repo = $scope.repo;

      bootbox.dialog({
        "message": message,
        "title": "Could not start Dockerfile build",
        "buttons": {
          "close": {
            "label": "Close",
            "className": "btn-primary",
            "callback": function() {
              $scope.$apply(function() {
                $location.path('/repository/' + repo.namespace + '/' + repo.name);
              });
            }
          }
        }
      });

      return true;
    };

    $scope.createNewRepo = function() {
      $('#repoName').popover('hide');

      $scope.creating = true;
      var repo = $scope.repo;
      var data = {
        'namespace': repo.namespace,
        'repository': repo.name,
        'visibility': repo.is_public == '1' ? 'public' : 'private',
        'description': repo.description
      };

      ApiService.createRepo(data).then(function(created) {
        $scope.creating = false;
        $scope.created = created;

        // Start the upload process if applicable.
        if ($scope.repo.initialize == 'dockerfile' || $scope.repo.initialize == 'zipfile') {
          $scope.createdForBuild = created;
          return;
        }

        // Conduct the SCM redirect if applicable.
        var redirectUrl = TriggerService.getRedirectUrl($scope.repo.initialize, repo.namespace, repo.name);
        if (redirectUrl) {
          window.location = redirectUrl;
          return;
        }

        // Otherwise, redirect to the repo page.
        $location.path('/repository/' + created.namespace + '/' + created.name);
      }, function(result) {
        $scope.creating = false;
        $scope.createError = result.data ? result.data.message : 'Cannot create repository';
        $timeout(function() {
          $('#repoName').popover('show');
        });
      });
    };

    $scope.upgradePlan = function() {
      var callbacks = {
        'started': function() { $scope.planChanging = true; },
        'opened': function() { $scope.planChanging = true; },
        'closed': function() { $scope.planChanging = false; },
        'success': subscribedToPlan,
        'failure': function(resp) {
          $('#couldnotsubscribeModal').modal();
          $scope.planChanging = false;
        }
      };

      var namespace = $scope.isUserNamespace ? null : $scope.repo.namespace;
      PlanService.changePlan($scope, namespace, $scope.planRequired.stripeId, callbacks);
    };

    var checkPrivateAllowed = function() {
      if (!$scope.repo || !$scope.repo.namespace) { return; }

      if (!Features.BILLING) {
        $scope.checkingPlan = false;
        $scope.planRequired = null;
        return;
      }

      $scope.checkingPlan = true;

      var isUserNamespace = $scope.isUserNamespace;
      ApiService.getPrivateAllowed(isUserNamespace ? null : $scope.repo.namespace).then(function(resp) {
        $scope.checkingPlan = false;

        if (resp['privateAllowed']) {
          $scope.planRequired = null;
          return;
        }

        if (resp['privateCount'] == null) {
          // Organization where we are not the admin.
          $scope.planRequired = {};
          return;
        }

        // Otherwise, lookup the matching plan.
        PlanService.getMinimumPlan(resp['privateCount'] + 1, !isUserNamespace, function(minimum) {
          $scope.planRequired = minimum;
        });
      });
    };

    var subscribedToPlan = function(sub) {
      $scope.planChanging = false;
      $scope.subscription = sub;

      PlanService.getPlan(sub.plan, function(subscribedPlan) {
        $scope.subscribedPlan = subscribedPlan;
        $scope.planRequired = null;
        checkPrivateAllowed();
      });
    };
  }
})();