/**
 * Element for managing the teams of an organization.
 */
angular.module('quay').directive('teamsManager', function () {
  var directiveDefinitionObject = {
    priority: 0,
    templateUrl: '/static/directives/teams-manager.html',
    replace: false,
    transclude: false,
    restrict: 'C',
    scope: {
      'organization': '=organization',
      'isEnabled': '=isEnabled'
    },
    controller: function($scope, $element, ApiService, CreateService, $timeout, UserService) {
      $scope.TEAM_PATTERN = TEAM_PATTERN;
      $scope.teamRoles = [
          { 'id': 'member', 'title': 'Member', 'kind': 'default' },
          { 'id': 'creator', 'title': 'Creator', 'kind': 'success' },
          { 'id': 'admin', 'title': 'Admin', 'kind': 'primary' }
      ];

      UserService.updateUserIn($scope);

      $scope.members = {};
      $scope.orderedTeams = [];
      $scope.showingMembers = false;
      $scope.fullMemberList = null;
      $scope.feedback = null;

      var loadTeamMembers = function() {
        if (!$scope.organization || !$scope.isEnabled) { return; }

        // Skip loading team members on mobile.
        if (!window.matchMedia('(min-width: 768px)').matches) {
          return;
        }

        for (var name in $scope.organization.teams) {
          if (!$scope.organization.teams.hasOwnProperty(name) || $scope.members[name]) { continue; }

          // Load fully async to prevent it from blocking the UI.
          (function(teamname) {
            $timeout(function() {
              loadMembersOfTeam(teamname);
            }, 1);
          })(name);
        }
      };

      var loadMembersOfTeam = function(name) {
        var params = {
          'orgname': $scope.organization.name,
          'teamname': name
        };

        $scope.members[name] = {};

        ApiService.getOrganizationTeamMembers(null, params).then(function(resp) {
          $scope.members[name].members = resp.members;
        }, function() {
          delete $scope.members[name];
        });
      };

      var loadOrderedTeams = function() {
        if (!$scope.organization || !$scope.organization.ordered_teams || !$scope.isEnabled) {
          return;
        }

        $scope.orderedTeams = [];
        $scope.organization.ordered_teams.map(function(name) {
          $scope.orderedTeams.push($scope.organization.teams[name]);
        });
      };

      $scope.$watch('organization', loadOrderedTeams);
      $scope.$watch('organization', loadTeamMembers);

      $scope.$watch('isEnabled', loadOrderedTeams);
      $scope.$watch('isEnabled', loadTeamMembers);

      $scope.setRole = function(role, teamname) {
        var previousRole = $scope.organization.teams[teamname].role;
        $scope.organization.teams[teamname].role = role;

        var params = {
          'orgname': $scope.organization.name,
          'teamname': teamname
        };

        var data = $scope.organization.teams[teamname];

        var errorHandler = ApiService.errorDisplay('Cannot update team', function(resp) {
          $scope.organization.teams[teamname].role = previousRole;
        });

        ApiService.updateOrganizationTeam(data, params).then(function(resp) {
          $scope.feedback = {
            'kind': 'success',
            'message': 'Team {team} role changed to {role}',
            'data': {
              'team': teamname,
              'role': role
            }
          };
        }, errorHandler);
      };

      $scope.createTeam = function(teamname) {
        if (!teamname) {
          return;
        }

        if ($scope.organization.teams[teamname]) {
          $('#team-' + teamname).removeClass('highlight');
          setTimeout(function() {
            $('#team-' + teamname).addClass('highlight');
          }, 10);
          return;
        }

        var orgname = $scope.organization.name;
        CreateService.createOrganizationTeam(ApiService, orgname, teamname, function(created) {
          $scope.organization.teams[teamname] = created;
          $scope.members[teamname] = {};
          $scope.members[teamname].members = [];
          $scope.organization.ordered_teams.push(teamname);
          $scope.orderedTeams.push(created);

          $scope.feedback = {
            'kind': 'success',
            'message': 'Team {team} created',
            'data': {
              'team': teamname
            }
          };
        });
      };

      $scope.askDeleteTeam = function(teamname) {
        bootbox.confirm('Are you sure you want to delete team ' + teamname + '?', function(resp) {
          if (resp) {
            $scope.deleteTeam(teamname);
          }
        });
      };

      $scope.deleteTeam = function(teamname) {
        var params = {
          'orgname': $scope.organization.name,
          'teamname': teamname
        };

        ApiService.deleteOrganizationTeam(null, params).then(function() {
          var index = $scope.organization.ordered_teams.indexOf(teamname);
          if (index >= 0) {
            $scope.organization.ordered_teams.splice(index, 1);
          }

          loadOrderedTeams();
          delete $scope.organization.teams[teamname];

          $scope.feedback = {
            'kind': 'success',
            'message': 'Team {team} deleted',
            'data': {
              'team': teamname
            }
          };
        }, ApiService.errorDisplay('Cannot delete team'));
      };

      $scope.viewTeam = function(teamName) {
        document.location = '/organization/' + $scope.organization.name + '/teams/' + teamName;
      };

      $scope.showMembers = function(value) {
        $scope.showingMembers = value;
        if (value && !$scope.fullMemberList) {
          var params = {
            'orgname': $scope.organization.name
          };

          ApiService.getOrganizationMembers(null, params).then(function(resp) {
            $scope.fullMemberList = resp['members'];
          }, ApiService.errorDisplay('Could not load full membership list'));
        }
      };

      $scope.removeMember = function(memberInfo, callback) {
        var params = {
          'orgname': $scope.organization.name,
          'membername': memberInfo.name
        };

        var errorHandler = ApiService.errorDisplay('Could not remove member', function() {
          callback(false);
        });

        ApiService.removeOrganizationMember(null, params).then(function(resp) {
          // Reset the state of the directive.
          $scope.members = {};
          $scope.orderedTeams = [];
          $scope.fullMemberList = null;

          loadOrderedTeams();
          loadTeamMembers();
          $scope.showMembers(true);

          callback(true);

          $scope.feedback = {
            'kind': 'success',
            'message': 'User {user} removed from the organization',
            'data': {
              'user': memberInfo.name
            }
          };
        }, errorHandler)
      };

      $scope.askRemoveMember = function(memberInfo) {
        $scope.removeMemberInfo = $.extend({}, memberInfo);
      };
    }
  };

  return directiveDefinitionObject;
});