using API.DBAccess;
using API.Models.RecipeModels;
using Microsoft.AspNetCore.Mvc;

namespace API.BusinessLogic
{
    public class RecipeLogic
    {
        private readonly RecipeDBAccess _dbAccess;

        public RecipeLogic(RecipeDBAccess dbAccess)
        {
            _dbAccess = dbAccess;
        }

        /// <summary>
        /// Gets all the recipes from _dbaccess and checks if there are any
        /// </summary>
        /// <param name="userId">the usér connected to the recipes</param>
        /// <returns>a list of recipes in a ok objectresult</returns>
        public async Task<IActionResult> GetRecipes(int userId)
        {
            var recipes = await _dbAccess.ReadRecipes(userId);
            if (recipes == null || recipes.Count == 0) { return new ConflictObjectResult(new { message = "Could not find any recipes" }); }

            return new OkObjectResult(recipes);
        }

        // Gets a specifik with recipe with the ingredient and directions
        public async Task<IActionResult> GetRecipe(int recipeId)
        {
            var recipe = await _dbAccess.ReadRecipe(recipeId);

            if (recipe == null || recipe.Id == 0) { return new ConflictObjectResult(new { message = "Could not find any recipe" }); }

            return new OkObjectResult(recipe);
        }

        /// <summary>
        /// Creates a recipe and checks if the recipe name is in use
        /// Converts the recipeDTO to a normal recipe
        /// </summary>
        /// <param name="recipe">The recipeDTO that does not include all the id tags</param>
        /// <param name="userId">The user that is going to get that recipe</param>
        /// <returns>returns what recipedbaccess gives back</returns>
        public async Task<IActionResult> CreateRecipe(RecipeDTO recipe, int userId)
        {
            var recipes = await _dbAccess.ReadRecipes(userId);

            foreach (var item in recipes)
            {
                if (item.Name == recipe.Name)
                {
                    return new ConflictObjectResult(new { message = "Recipe name is already in use." });
                }
            }

            Recipe dish = new Recipe();
            dish.Name = recipe.Name;
            dish.Description = recipe.Description;
            dish.Ingredients = new List<Ingredient>();
            dish.Directions = new List<Directions>();
            foreach (var item in recipe.Ingredients)
            {
                Ingredient ingredient = new Ingredient();
                ingredient.Unit = item.Unit;
                ingredient.Name = item.Name;
                ingredient.Amount = item.Amount;
                dish.Ingredients.Add(ingredient);
            }
            foreach (var item in recipe.Directions)
            {
                Directions directions = new Directions();
                directions.Instruktions = item.Instructions;
                dish.Directions.Add(directions);
            }

            return await _dbAccess.CreateRecipe(dish, userId);
        }

        /// <summary>
        /// Updates the recipe that is saved in the db
        /// </summary>
        /// <param name="recipe">The updated recipe</param>
        /// <param name="recipeId">The recipeId on the recipe to be updated</param>
        /// <param name="userId">The userÍd of the owner of the to be updated recipe</param>
        /// <returns>returns what recipedbaccess gives back</returns>
        public async Task<IActionResult> EditRecipe(RecipeDTO recipe, int recipeId, int userId)
        {
            var recipes = await _dbAccess.ReadRecipes(userId);
            var dish = await _dbAccess.ReadRecipe(recipeId);

            foreach (var item in recipes)
            {
                if (item.Name == recipe.Name)
                {
                    return new ConflictObjectResult(new { message = "Recipe name is already in use." });
                }
            }

            dish.Name = recipe.Name;
            dish.Description = recipe.Description;
            dish.Directions = new List<Directions>();
            foreach (var item in recipe.Ingredients)
            {
                Ingredient ingredient = new Ingredient();
                ingredient.Unit = item.Unit;
                ingredient.Name = item.Name;
                ingredient.Amount = item.Amount;
                dish.Ingredients.Add(ingredient);
            }
            foreach (var item in recipe.Directions)
            {
                Directions directions = new Directions();
                directions.Instruktions = item.Instructions;
                dish.Directions.Add(directions);
            }

            return await _dbAccess.UpdateRecipe(dish);
        }

        // Deletes the recipe 
        public async Task<IActionResult> DeleteRecipe(int recipeId)
        {
            var recipe = await _dbAccess.ReadRecipe(recipeId);

            if (recipe != null) { return await _dbAccess.DeleteRecipe(recipe); }

            return new ConflictObjectResult(new { message = "Invalid recipe" });
        }
    }
}