app.factory('$auth', function ($http, $crypto, blockUI) {
  var service = {
    currentUser: null,

    login: function (username, password, callback) {
      blockUI.start("A autenticar credenciais...");
      return $http.post('/api/session/login/', { username: username, password: $crypto.md5(password) })
        .then(function (response) {
          service.currentUser = response.data.user;
          callback();
        })
        .catch(function (response) {
          swal("Login Falhou", response.data, "error");
          callback(true);
        })
        .finally(function () {
          blockUI.stop();
        });
    },

    logout: function (callback) {
      $http.get('/api/session/logout')
        .then(function (response) {
          service.currentUser = null;
          callback(null, response);
        })
        .catch(function (response) {
          callback(response);
        });
    },

    requestCurrentUser: function (callback) {
      if (service.isAuthenticated()) {
        callback(null, service.currentUser);
      }
      else {
        $http.get('/api/session/currentuser')
          .then(function (response) {
            service.currentUser = response.data.user;
            callback(null, service.currentUser);
          })
          .catch(function (response) {
            service.currentUser = null;
            callback(response);
          });
      }
    },

    isAuthenticated: function () {
      return !!service.currentUser;
    },

    activateAccount: function (rawCode, callback) {
      if (!rawCode) {
        return callback(true);
      }

      var codes = rawCode.split('&');
      if (codes.length !== 2) {
        return callback(true);
      }

      blockUI.start("A verificar código de ativação...");
      $http.post('/api/user/activate/', { email: codes[0], code: codes[1] })
        .then(function (response) {
          callback(null, response.data);
        })
        .catch(function (response) {
          swal({
            title: "Conta já ativa!",
            text: "Consulte o email que recebeu com instruções de acesso",
            type: "info",
            confirmButtonText: "OK"
          });

          callback(true);
        })
        .finally(function () {
          blockUI.stop();
        });
    },

    resetPassword: function (email, username) {
      blockUI.start("A comunicar pedido de recuperação...");
      return $http.post('/api/user/resetpassword/', { email: email, username: username })
        .then(function (response) {
          swal("Recuperação de Conta", "A sua conta foi recuperada! Consulte a sua conta de email.", "success");
          callback();
        })
        .catch(function (response) {
          swal("Erro", response.data, "error");
          callback(true);
        })
        .finally(function () {
          blockUI.stop();
        });
    },

    changePassword: function (user, newPassword1, newPassword2, callback) {
      if (!newPassword1) {
        return;
      }

      if (newPassword1 !== newPassword2) {
        return swal("Atenção!", "As palavras chave têm de ser iguais", "error");
      }

      user.newPassword = $crypto.md5(newPassword1);

      blockUI.start("A atualizar dados...");
      $http.post('/api/user/changepassword/', user)
        .then(function (response) {
          swal({
            title: "Parabéns!",
            text: "Palavra chave alterada com sucesso!",
            type: "success",
            confirmButtonText: "Entrar"
          });

          callback();
        })
        .catch(function (response) {
          swal("Erro", "Ocorreu um erro ao criar a sua password, por favor tente novamente mais tarde", "error");
          callback(true);
        })
        .finally(function () {
          blockUI.stop();
        });
    }
  };

  return service;
});
