public HttpResponseMessage PostRegisterUser([FromBody]UserModel userModel)
        {
            var responseMsg = this.PerformOperationAndHandleExceptions(
                () =>
                {
                    var context = new StoreContext();
                    using (context)
                    {
                        this.ValidateUsername(userModel.Username);
                        this.ValidateAuthCode(userModel.Password);
                        var usernameToLower = userModel.Username.ToLower();
                        var user = context.Users.FirstOrDefault(
                            usr => usr.Username.ToLower() == usernameToLower);

                        if (user != null)
                        {
                            throw new InvalidOperationException("User exists");
                        }

                        user = new User()
                        {
                            Username = usernameToLower,
                            Password = userModel.Password,
                            Email = userModel.Email,
                            Role = userModel.Role,
                            FirstName = userModel.FirstName,
                            LastName = userModel.LastName,
                        };

                        context.Users.Add(user);
                        context.SaveChanges();

                        user.SessionKey = this.GenerateSessionKey(user.UserId);
                        context.SaveChanges();

                        var loggedModel = new LoggedUserModel()
                        {
                            DisplayName = user.FirstName + " " + user.LastName,
                            SessionKey = user.SessionKey,
                            Role = user.Role
                        };

                        var response =
                            this.Request.CreateResponse(HttpStatusCode.Created,
                            loggedModel);

                        return response;
                    }
                });

            return responseMsg;
        }
        public HttpResponseMessage PostLoginUser(UserModel userModel)
        {
            var responseMsg = this.PerformOperationAndHandleExceptions(
              () =>
              {
                  var context = new StoreContext();
                  using (context)
                  {
                      this.ValidateUsername(userModel.Username);
                      this.ValidateAuthCode(userModel.Password);
                      var usernameToLower = userModel.Username.ToLower();
                      var user = context.Users.FirstOrDefault(
                          usr => usr.Username == usernameToLower
                          && usr.Password == userModel.Password);

                      if (user == null)
                      {
                          throw new InvalidOperationException("Invalid Username or password");
                      }
                      if (user.SessionKey == null)
                      {
                          user.SessionKey = this.GenerateSessionKey(user.UserId);
                          context.SaveChanges();
                      }

                      var loggedModel = new LoggedUserModel()
                      {
                          DisplayName = user.FirstName + " " + user.LastName,
                          SessionKey = user.SessionKey,
                          Role = user.Role
                      };

                      var response =
                          this.Request.CreateResponse(HttpStatusCode.Created,
                          loggedModel);

                      return response;
                  }
              });

            return responseMsg;
        }
        public HttpResponseMessage PutLogoutUser(
            [ValueProvider(typeof(HeaderValueProviderFactory<string>))] string sessionKey)
        {
            var responseMsg = this.PerformOperationAndHandleExceptions(
                () =>
                {
                    var context = new StoreContext();
                    using (context)
                    {
                        User user = UsersController.GetUserBySessionKey(sessionKey);

                        if (user == null)
                        {
                            throw new ArgumentException("There is no user with such sessionKey!");
                        }

                        context.Users.
                            FirstOrDefault(usr => usr.SessionKey == sessionKey).
                            SessionKey = null;
                        context.SaveChanges();

                        var response =
                          this.Request.CreateResponse(HttpStatusCode.OK);

                        return response;
                    }
                });

            return responseMsg;
        }
        public HttpResponseMessage PostProductByAdmin(
            [ValueProvider(typeof(HeaderValueProviderFactory<string>))] string sessionKey, ProductFullModel product)
        {
            var responseMsg = this.PerformOperationAndHandleExceptions(
                () =>
                {
                    var context = new StoreContext();
                    using (context)
                    {
                        var user = UsersController.GetUserBySessionKey(sessionKey);
                        if (user == null)
                        {
                            throw new ArgumentException("There is no user with such sessionKey!");
                        }

                        if (!CheckUserIsAdmin(user.UserId))
                        {
                            throw new ArgumentException("You are not admin");
                        }

                        var cat = context.Categories.Where(c => c.CategoryName == product.Category).FirstOrDefault();
                        var newCategory = new Category();
                        if (cat == null)
                        {
                            newCategory.CategoryName = product.ProductName;
                        }

                        var newProduct =
                            new Product()
                            {
                                ProductId = product.ProductId,
                                Price = product.Price,
                                Category = newCategory,
                                DateOfCreation = product.DateOfCreation,
                                Description = product.Description,
                                Manufacturer = product.Manufacturer,
                                ProductName = product.ProductName,
                                Quantity = product.Quantity

                            };

                        context.Products.Add(newProduct);
                        context.SaveChanges();

                        var response =
                              this.Request.CreateResponse(HttpStatusCode.OK);

                        return response;
                    }
                });
            return responseMsg;
        }
        public HttpResponseMessage PutProduct(
            [ValueProvider(typeof(HeaderValueProviderFactory<string>))] string sessionKey, int id)
        {
            var responseMsg = this.PerformOperationAndHandleExceptions(
                () =>
                {
                    var context = new StoreContext();
                    using (context)
                    {
                        var user = context.Users.Where(usr => usr.SessionKey == sessionKey).FirstOrDefault();
                        if (user == null)
                        {
                            throw new ArgumentException("There is no user with such sessionKey!");
                        }

                        var productToUpdate = context.Products.FirstOrDefault(p => p.ProductId == id);

                        productToUpdate.Quantity--;

                        user.Products.Add(productToUpdate);

                        context.SaveChanges();

                        var productModel = new ProductFullModel()
                        {
                            ProductId = productToUpdate.ProductId,
                            ProductName = productToUpdate.ProductName,
                            Price = productToUpdate.Price,
                            Category = productToUpdate.Category.CategoryName,
                            DateOfCreation = productToUpdate.DateOfCreation,
                            Description = productToUpdate.Description,
                            Manufacturer = productToUpdate.Manufacturer,
                            Quantity = productToUpdate.Quantity
                        };

                        var response =
                              this.Request.CreateResponse(HttpStatusCode.OK, productModel);

                        return response;
                    }
                });
            return responseMsg;
        }
        public HttpResponseMessage DeleteProductByAdmin(
            [ValueProvider(typeof(HeaderValueProviderFactory<string>))] string sessionKey, int id)
        {

            var responseMsg = this.PerformOperationAndHandleExceptions(
            () =>
            {
                var context = new StoreContext();
                using (context)
                {
                    var product = context.Products.FirstOrDefault(p => p.ProductId == id);
                    if (product == null)
                    {
                        throw new ArgumentNullException("No product found");
                    }

                    context.Products.Remove(product);
                    context.SaveChanges();

                    var response =
                      this.Request.CreateResponse(HttpStatusCode.OK);

                    return response;
                }
            });
            return responseMsg;
        }