public HttpResponseMessage PostDeleteCategory(CategoryModelCreate model)
        {
            try
            {
                using (var context = new OfferWorldContext())
                {
                    Validator.ValidateCategoryTitle(model.Title);

                    var user = context.Users.FirstOrDefault(usr => usr.SessionKey == model.SessionKey && usr.Admin == true);

                    if (user == null)
                    {
                        throw new ArgumentNullException("You have no rights to make changes!");
                    }

                    Category category = context.Categories.FirstOrDefault(cat => cat.Name == model.Title);
                    context.Categories.Remove(category);

                    context.SaveChanges();
                    return this.Request.CreateResponse(HttpStatusCode.OK);
                }

            }
            catch (Exception ex)
            {
                var errResponse = this.Request.CreateErrorResponse(HttpStatusCode.BadRequest, ex.Message);
                return errResponse;
            }

        }
        private static OAuthToken LoadOAuthToken()
        {
            using (var db = new OfferWorldContext())
            {
                var data = db.DropboxAuthentication.First();

                OAuthToken oauthAccessToken = new OAuthToken("d2576clemzwat0gv", "s066q2wjnpct8nx");
                return oauthAccessToken;
            }
        }
        public HttpResponseMessage PostRegisterUser(UserModel model)
        {
            try
            {
                using (var context = new OfferWorldContext())
                {
                    Validator.ValidateUsername(model.Username);
                    Validator.ValidateAuthCode(model.AuthCode);
                    Validator.ValidateEmail(model.Email);

                    var usernameToLower = model.Username.ToLower();
                    var username = (context.Users.FirstOrDefault(usr => usr.Username == usernameToLower || usr.Email == model.Email));
                    
                    if (username != null)
                    {
                        throw new ArgumentException("Username or Email already exist");
                    }

                    var user = new User()
                    {
                        Username = model.Username,
                        AuthCode = model.AuthCode, 
                        Email = model.Email,
                        Admin = false
                    };

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

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

                    context.SaveChanges();

                    var loggedModel = new UserLoggedModel()
                    {
                        Username = user.Username,
                        SessionKey = user.SessionKey
                    };

                    var response = this.Request.CreateResponse(HttpStatusCode.Created, loggedModel);
                    return response;
                }
            }
            catch (Exception ex)
            {
                var errResponse = this.Request.CreateErrorResponse(HttpStatusCode.BadRequest, ex.Message);
                return errResponse;
            }
        }
        public void PutOfferForItem(int id,
            [ValueProvider(typeof(HeaderValueProviderFactory<string>))] string sessionKey)
        {
            var item = this.GetAllItems(sessionKey).Where(i => i.Id == id).FirstOrDefault();

            var context = new OfferWorldContext();

            var user = context.Users.FirstOrDefault(usr => usr.SessionKey == sessionKey);
            item.Offers.Add(new Offer()
            {
                User = user,
                Item = new Item()
                {
                    ItemId = item.Id
                }
            });

        }
        public IQueryable<GetItemsModel> GetAllItems(
            [ValueProvider(typeof(HeaderValueProviderFactory<string>))] string sessionKey)
        {
            var context = new OfferWorldContext();


            //Validator.ValidateUsername(model.Username);

            var user = context.Users.FirstOrDefault(usr => usr.SessionKey == sessionKey);

            if (user == null)
            {
                throw new ArgumentNullException("You are not logged in!");
            }

            var itemsEntity = context.Items;



            var allItems = (from item in itemsEntity
                            select new GetItemsModel()
                            {
                                Id = item.ItemId,
                                Title = item.Title,
                                Price = item.Price,
                                Description = item.Description,
                                AdInfo = item.AdInfo,
                                User = item.User.Username,
                                Category = item.Category.Name,
                                Comments = item.Comments, //TODO create CommentModel
                                Pictures = (from picture in item.Pictures
                                           select new PictureModel()
                                           {
                                               Link = picture.Link
                                           })

                                //Offers = item.Offers                                 //TODO add offers

                            }).ToList();

            return allItems.AsQueryable();
        }
        public HttpResponseMessage PostLoginUser(UserModel model)
        {
            try
            {
                using (var context = new OfferWorldContext())
                {
                    Validator.ValidateUsername(model.Username);
                    Validator.ValidateAuthCode(model.AuthCode);

                    var usernameToLower = model.Username.ToLower();
                    var user = (context.Users.FirstOrDefault(usr => usr.Username == usernameToLower &&
                            usr.AuthCode == model.AuthCode));

                    if (user == null)
                    {
                        throw new ArgumentException("Username does not exist!");
                    }
                    else if (user.SessionKey == null)
                    {
                        user.SessionKey = this.GenerateSessionKey(user.UserId);
                        context.SaveChanges();
                    }

                    var loggedModel = new UserLoggedModel()
                    {
                        Username = user.Username,
                        SessionKey = user.SessionKey
                    };

                    var response = this.Request.CreateResponse(HttpStatusCode.Created, loggedModel);
                    return response;
                }
            }
            catch (Exception ex)
            {
                var errResponse = this.Request.CreateErrorResponse(HttpStatusCode.BadRequest, ex.Message);
                return errResponse;
            }
        }
        public IQueryable<CommentModel> GetByItemId(int itemId,
            [ValueProvider(typeof(HeaderValueProviderFactory<string>))] string sessionKey)
        {
            var context = new OfferWorldContext();

            var user = context.Users.FirstOrDefault(usr => usr.SessionKey == sessionKey);
            if (user == null)
            {
                throw new InvalidOperationException("Invalid username or password");
            }

            var commentEntities = context.Comments.Include("User").Include("Item")
                .Where(c => c.Item.ItemId == itemId);
            var models =
                (from commentEntity in commentEntities
                 select new CommentModel()
                 {
                     Id = commentEntity.CommentId,
                     Text = commentEntity.Content,
                     Username = commentEntity.User.Username
                 });
            return models;
        }
        public HttpResponseMessage PostComment([FromBody]CommentPostModel comment,
            [ValueProvider(typeof(HeaderValueProviderFactory<string>))] string sessionKey)
        {
            try
            {
                using (var context = new OfferWorldContext())
                {
                    var user = context.Users.FirstOrDefault(usr => usr.SessionKey == sessionKey);
                    if (user == null)
                    {
                        throw new InvalidOperationException("Invalid username or password");
                    }

                    var item = context.Items.SingleOrDefault(b => b.ItemId == comment.ItemId);
                    if (item == null)
                    {
                        throw new InvalidOperationException("This item does not exist.");
                    }

                    var commentToAdd = new Comment();
                    commentToAdd.PostDate = DateTime.Now;
                    commentToAdd.Content = comment.Content;
                    commentToAdd.User = user;
                    commentToAdd.Item = item;
                    context.Comments.Add(commentToAdd);
                    context.SaveChanges();

                    return Request.CreateResponse(HttpStatusCode.Created);
                }
            }
            catch (Exception ex)
            {
                var errResponse = this.Request.CreateErrorResponse(HttpStatusCode.BadRequest, ex.Message);
                return errResponse;
            }
        }
        public HttpResponseMessage PostUserAddInfo(UserAddInfoModel model)
        {
            try
            {
                using(var context = new OfferWorldContext())
                {

                    Validator.ValidateUsername(model.Username);

                    var user = context.Users.FirstOrDefault(usr => usr.Username == model.Username && usr.SessionKey == model.SessionKey);
                    
                    if (user == null)
                    {
                        throw new ArgumentNullException("Username does NOT exist");
                    }


                    if (model.Location != null)
                    {
                        Validator.ValidateLocation(model.Location);
                        user.Location = model.Location;
                    }

                    if(model.PhoneNumber != null)
                    {
                        Validator.ValidatePhoneNumber(model.Location);
                        user.PhoneNumber = model.PhoneNumber;
                    }

                    if (model.Avatar != null)
                    {
                        Validator.ValidateAvatar(model.Avatar);
                        user.Avatar = model.Avatar;
                    }

                    context.SaveChanges();

                    return this.Request.CreateResponse(HttpStatusCode.OK);
                }
            }
            catch (Exception ex)
            {
                var errResponse = this.Request.CreateErrorResponse(HttpStatusCode.BadRequest, ex.Message);
                return errResponse;
            }
        }
        public HttpResponseMessage PostCreateCategory(EditUserModel model,
            [ValueProvider(typeof(HeaderValueProviderFactory<string>))] string sessionKey)
        {
            try
            {
                using (var context = new OfferWorldContext())
                {

                    var admin = context.Users.FirstOrDefault(usr => usr.SessionKey == sessionKey && (usr.Admin == true ||
                        usr.Username == model.Username));

                    if (admin == null)
                    {
                        throw new ArgumentNullException("You have no rights to make changes!");
                    }

                    var userToEdit = context.Users.FirstOrDefault(usr => usr.Username == model.Username);


                    if (model.AuthCode != null)
                    {
                        Validator.ValidateAuthCode(model.AuthCode);
                        userToEdit.AuthCode = model.AuthCode;
                    }

                    if (model.Location != null)
                    {
                        Validator.ValidateLocation(model.Location);
                        userToEdit.Location = model.Location;
                    }

                    if (model.PhoneNumber != null)
                    {
                        Validator.ValidatePhoneNumber(model.PhoneNumber);
                        userToEdit.PhoneNumber = model.PhoneNumber;
                    }

                    if (model.Avatar != null)
                    {
                        Validator.ValidateAvatar(model.Avatar);
                        userToEdit.Avatar = model.Avatar;
                    }

                    context.SaveChanges();

                     
                    return this.Request.CreateResponse(HttpStatusCode.OK);
                }

            }
            catch (Exception ex)
            {
                var errResponse = this.Request.CreateErrorResponse(HttpStatusCode.BadRequest, ex.Message);
                return errResponse;
            }
        }
        public HttpResponseMessage PutLogoutUser(UserLoggedModel model)
        {
            try
            {
                using (var context = new OfferWorldContext())
                {
                    var user = context.Users.FirstOrDefault(usr => usr.SessionKey == model.SessionKey);

                    if (user == null)
                    {
                        throw new InvalidOperationException("Invalid operation.");
                    }

                    user.SessionKey = null;

                    context.SaveChanges();

                    return this.Request.CreateResponse(HttpStatusCode.OK);
                }
            }
            catch (Exception ex)
            {
                return this.Request.CreateErrorResponse(HttpStatusCode.BadRequest, ex.Message);
            }
        }
        public HttpResponseMessage PostCreateItem(ItemCreateModel model,
            [ValueProvider(typeof(HeaderValueProviderFactory<string>))] string sessionKey)
        {
            try
            {
                using (var context = new OfferWorldContext())
                {

                    //Validator.ValidateUsername(model.Username);

                    var user = context.Users.FirstOrDefault(usr => usr.SessionKey == sessionKey);

                    if (user == null)
                    {
                        throw new ArgumentNullException("You are not logged in!");
                    }

                    var category = context.Categories.FirstOrDefault(cat => cat.Name == model.Category);

                    var newItem = new Item()
                    {
                        Title = model.Title,
                        Price = model.Price,
                        Description = model.Description,
                        AdInfo = model.AdInfo,
                        Category = category,
                        User = user,

                    };                    
                    
                    context.Items.Add(newItem);

                    var picture = new Picture()
                        {
                            Link = "http://www.design.svetu.com/wp-content/gallery/clients/no_image.gif",
                            Item = newItem
                        };

                    if (model.Pictures.Length == 0)
                    {
                        context.Pictures.Add(picture);
                    }
                    context.SaveChanges();

                    return this.Request.CreateResponse(HttpStatusCode.OK);
                }
            }
            catch (Exception ex)
            {
                var errResponse = this.Request.CreateErrorResponse(HttpStatusCode.BadRequest, ex.Message);
                return errResponse;
            }
        }
        public string SendFile(string reciever,
            [ValueProvider(typeof(HeaderValueProviderFactory<string>))] string sessionKey)
        {
            var context = new OfferWorldContext();
            var sender = context.Users.FirstOrDefault(usr => usr.SessionKey == sessionKey);

            string url = this.UploadFile(HttpContext.Current.Request.Files[0], sender);

            return url;
        }
        public HttpResponseMessage DeleteComment(int id,
            [ValueProvider(typeof(HeaderValueProviderFactory<string>))]string sessionKey)
        {
            try
            {
                using (var context = new OfferWorldContext())
                {
                    var user = context.Users.FirstOrDefault(usr => usr.SessionKey == sessionKey);
                    if (user == null)
                    {
                        throw new UnauthorizedAccessException("Invalid username or password");
                    }

                    var commentEntity = context.Comments.Include("User").SingleOrDefault(u => u.CommentId == id);
                    if (commentEntity == null)
                    {
                        throw new InvalidOperationException("User does not exist.");
                    }

                    if (commentEntity.User.UserId != user.UserId)
                    {
                        throw new InvalidOperationException("You do not have permissions to delete other users' comments.");
                    }

                    context.Comments.Remove(commentEntity);
                    context.SaveChanges();

                    return Request.CreateResponse(HttpStatusCode.OK);
                }
            }
            catch (Exception ex)
            {
                var errResponse = this.Request.CreateErrorResponse(HttpStatusCode.BadRequest, ex.Message);
                return errResponse;
            }
        }