public IActionResult CheckTask(int taskId, float latitude, float longitude)
        {
            var userId = AuthController.GetUserIdFromPrincipal(Request, config["JWT:Secret"]);
            var user   = userRepository.GetUserById(userId);

            if (user == null)
            {
                return(BadRequest());
            }

            var dbTask = taskRepository.GetTask(taskId);

            if (dbTask == null)
            {
                return(BadRequest());
            }

            if (dbTask.Assigned < DateTime.Today)
            {
                return(Ok(dbTask));
            }

            // If within 50 meters (roughly)
            if (MathF.Abs(dbTask.Latitude.Value - latitude) <= 0.0005f &&
                MathF.Abs(dbTask.Longitude.Value - longitude) <= 0.0005f)
            {
                // Mark task as completed by adding completion date
                dbTask.Completed = DateTime.Now;
                taskRepository.UpdateTask(dbTask);

                switch (dbTask.TaskType)
                {
                case TaskType.NATURE:
                    user.Nature += dbTask.Points;
                    break;

                case TaskType.KNOWLEDGE:
                    user.Knowledge += dbTask.Points;
                    break;

                case TaskType.FITNESS:
                    user.Fitness += dbTask.Points;
                    break;

                case TaskType.COMMUNITY:
                    user.Community += dbTask.Points;
                    break;
                }

                userRepository.UpdateUser(user);
            }

            taskRepository.Save();
            userRepository.Save();

            return(Ok(mapper.Map <TaskResponse>(dbTask)));
        }
        public IActionResult EditProfile(string username)
        {
            if (authUnit.Users.GetUserByUsername(username) == null)
            {
                return(NotFound());
            }

            var userId = AuthController.GetUserIdFromPrincipal(Request, config.Secret);

            var user = authUnit.Users.GetUserById(userId);

            // Validate user
            if (user == null)
            {
                return(NotFound());
            }

            if (user.Username != username)
            {
                return(Unauthorized());
            }
            return(Ok(mapper.Map <UserPersonalResponse>(user)));
        }
        public IActionResult EditEmail(string username, [FromForm] UserEditEmailRequest editEmailRequest)
        {
            var userId = AuthController.GetUserIdFromPrincipal(Request, config.Secret);

            var user = authUnit.Users.GetUserById(userId);

            // Validate user
            if (user == null)
            {
                return(NotFound());
            }
            if (user.Username != username)
            {
                return(Unauthorized());
            }

            // Apply mapping and update user
            mapper.Map(editEmailRequest, user);
            authUnit.Users.UpdateUser(user);
            authUnit.Complete();

            return(NoContent());
        }
        public IActionResult EditPassword(string username, [FromForm] UserEditPasswordRequest editRequest)
        {
            var userId = AuthController.GetUserIdFromPrincipal(Request, config.Secret);

            var user = authUnit.Users.GetUserById(userId);

            // Validate user
            if (user == null)
            {
                return(NotFound());
            }

            if (user.Username != username)
            {
                return(Unauthorized());
            }

            // Compare existing password
            var oldHash = cryptoService.Compute(editRequest.OldPassword, user.PasswordSalt);

            if (!cryptoService.Compare(user.Password, oldHash))
            {
                return(BadRequest());
            }

            // Set new password
            var newHash = cryptoService.Compute(editRequest.NewPassword);

            user.Password     = newHash;
            user.PasswordSalt = cryptoService.Salt;

            authUnit.Users.UpdateUser(user);
            authUnit.Complete();

            return(NoContent());
        }
        public IActionResult GenerateTasks(float latitude, float longitude)
        {
            var client = new HttpClient();
            var userId = AuthController.GetUserIdFromPrincipal(Request, config["JWT:Secret"]);

            // Get user
            var user = userRepository.GetUserById(userId);

            // If user claims to be nonexistent user
            if (user == null)
            {
                return(BadRequest());
            }

            // Generate 5 new tasks
            var tasks = new List <TaskModel>();

            for (int i = 0; i < 5; i++)
            {
                string description = "";
                string title       = "";
                string text        = "";
                string address     = "";
                int    type        = -1;

                var taskLoc = RandomPoint(latitude, longitude, MilesToMeters(5));

                // Make mapbox request with random keyword
                try {
                    var response = client.GetFromJsonAsync <GeocodingResponse>("https://api.mapbox.com/geocoding" +
                                                                               $"/v5/mapbox.places/{taskLoc.Y},{taskLoc.X}.json" +
                                                                               $"?access_token={config["mapbox"]}" +
                                                                               "&types=poi" +
                                                                               "&language=en").Result;

                    // If there was no address associated with the point, fallback to this information
                    if (response.Features.Length == 0)
                    {
                        type        = (int)TaskType.FITNESS;
                        title       = "Go on a run";
                        description =
                            "Get out there, get moving! Increasing your Fitness is a great way to stay in shape.";
                        text = "Point of Interest";
                    }
                    else
                    {
                        // TODO: Fix possible duplicate points

                        // There was a valid address associated with this point
                        var categories = response.Features[0].Properties.Category.Split(", ");
                        address = response.Features[0].Properties.Address ?? "";
                        text    = response.Features[0].Text;

                        foreach (var category in categories)
                        {
                            if (!Categories.ContainsKey(category))
                            {
                                continue;
                            }
                            type = (int)Categories[category];
                            break;
                        }

                        // Default to Fitness category
                        if (type == -1)
                        {
                            type = (int)TaskType.FITNESS;
                        }

                        switch (type)
                        {
                        case (int)TaskType.NATURE:
                            title       = "Take a walk";
                            description =
                                "Go out and see the sunshine! Take a break from your devices and enjoy what nature has to offer.";
                            break;

                        case (int)TaskType.FITNESS:
                            title       = "Go on a run";
                            description =
                                "Get out there, get moving! Increasing your Fitness is a great way to stay in shape.";
                            break;

                        case (int)TaskType.COMMUNITY:
                            title       = "Meet new people";
                            description = "It's time to meet new friends! Go out and expand your circle.";
                            break;

                        case (int)TaskType.KNOWLEDGE:
                            title       = "Visit this institution";
                            description = "Knowledge is power! Visit this location to increase your Knowledge.";
                            break;
                        }
                    }

                    var task = new TaskModel {
                        Assigned    = DateTime.Now,
                        Completed   = null,
                        Title       = title,
                        Description = description,
                        TaskType    = (TaskType)type,
                        Points      = Math.Min(25 + (int)(75 * MathF.Sqrt(MathF.Pow(latitude - taskLoc.X, 2) +
                                                                          MathF.Pow(longitude - taskLoc.Y, 2)) / 5) * 5, 50),
                        Latitude  = taskLoc.X,
                        Longitude = taskLoc.Y,
                        Address   = address,
                        Text      = text,
                        User      = user
                    };

                    taskRepository.AddTask(task);
                    tasks.Add(task);
                } catch (HttpRequestException e) {
                    Console.WriteLine("Could not connect to MapBox.");
                }
            }


            taskRepository.Save();

            return(Ok(mapper.Map <IEnumerable <TaskResponse> >(tasks)));
        }