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

namespace API.BusinessLogic
{
    public class ShoppingListLogic
    {
        private readonly ShoppingListDBAccess _dbAccess;
        private readonly RecipeDBAccess _recipeDBAccess;

        public ShoppingListLogic(ShoppingListDBAccess dbAccess, RecipeDBAccess recipeDBAccess)
        {
            _dbAccess = dbAccess;
            _recipeDBAccess = recipeDBAccess;
        }

        public async Task<IActionResult> ReadShoppingList(int userId)
        {
            var user = await _dbAccess.ReadShoppingList(userId);

            return new OkObjectResult(user.ShoppingList);
        }

        public async Task<IActionResult> AddItemToShoppingList(ShoppingListItemDTO listItemDTO, int userId)
        {
            var user = await _dbAccess.ReadShoppingList(userId);

            List<ShoppingList> shoppingList = user.ShoppingList;

            if (shoppingList.Any(s => s.Name == listItemDTO.Name))
            {
                ShoppingList item = shoppingList.Where(s => s.Name == listItemDTO.Name).FirstOrDefault();
                shoppingList.Remove(item);

                if (item.Unit == listItemDTO.Unit)
                {
                    item.Amount += listItemDTO.Amount;
                }
                else if (item.Unit == "g" && listItemDTO.Unit == "kg")
                {
                    item.Amount = (item.Amount / 1000) + listItemDTO.Amount;
                    item.Unit = "kg";
                }
                else if (item.Unit == "ml" && item.Unit == "l")
                {
                    item.Amount = (item.Amount / 1000) + listItemDTO.Amount;
                    item.Unit = "l";
                }
                else if (item.Unit == "dl" && item.Unit == "l")
                {
                    item.Amount = (item.Amount / 10) + listItemDTO.Amount;
                    item.Unit = "l";
                }

                item.Checked = false;

                if (item.Unit == "g" && item.Amount >= 1000)
                {
                    item.Unit = "kg";
                    item.Amount = item.Amount / 1000;
                }
                else if (item.Unit == "ml" && item.Amount >= 1000)
                {
                    item.Unit = "l";
                    item.Amount = item.Amount / 1000;
                }
                else if (item.Unit == "dl" && item.Amount >= 10)
                {
                    item.Unit = "l";
                    item.Amount = item.Amount / 10;
                }
                user.ShoppingList.Add(item);
            }
            else
            {
                ShoppingList newItem = new ShoppingList();
                newItem.Name = listItemDTO.Name;
                newItem.Amount = listItemDTO.Amount;
                newItem.Unit = listItemDTO.Unit;
                newItem.Checked = false;

                user.ShoppingList.Add(newItem);
            }
            return await _dbAccess.UpdateShoppingList(user);
        }

        public async Task<IActionResult> CheckItemInShoppingList(int userId, int itemId)
        {
            var user = await _dbAccess.ReadShoppingList(userId);

            int itemIndex = user.ShoppingList.FindIndex(x => x.Id == itemId);

            user.ShoppingList[itemIndex].Checked = !user.ShoppingList[itemIndex].Checked;

            return await _dbAccess.UpdateShoppingList(user);
        }

        public async Task<IActionResult> UpdateItemInShoppingList(int userId, int itemId, ShoppingListItemDTO listItemDTO)
        {
            var user = await _dbAccess.ReadShoppingList(userId);

            int itemIndex = user.ShoppingList.FindIndex(x => x.Id == itemId);

            user.ShoppingList[itemIndex].Unit = listItemDTO.Unit;
            user.ShoppingList[itemIndex].Name = listItemDTO.Name;
            user.ShoppingList[itemIndex].Amount = listItemDTO.Amount;

            if (user.ShoppingList[itemIndex].Unit == "g" && user.ShoppingList[itemIndex].Amount >= 1000)
            {
                user.ShoppingList[itemIndex].Unit = "kg";
                user.ShoppingList[itemIndex].Amount = user.ShoppingList[itemIndex].Amount / 1000;
            }
            else if (user.ShoppingList[itemIndex].Unit == "ml" && user.ShoppingList[itemIndex].Amount >= 1000)
            {
                user.ShoppingList[itemIndex].Unit = "l";
                user.ShoppingList[itemIndex].Amount = user.ShoppingList[itemIndex].Amount / 1000;
            }
            else if (user.ShoppingList[itemIndex].Unit == "dl" && user.ShoppingList[itemIndex].Amount >= 10)
            {
                user.ShoppingList[itemIndex].Unit = "l";
                user.ShoppingList[itemIndex].Amount = user.ShoppingList[itemIndex].Amount / 10;
            }

            return await _dbAccess.UpdateShoppingList(user);
        }

        public async Task<IActionResult> DeleteItemInShoppingList(int userId, int itemId)
        {
            var user = await _dbAccess.ReadShoppingList(userId);

            int itemIndex = user.ShoppingList.FindIndex(x => x.Id == itemId);

            user.ShoppingList.RemoveAt(itemIndex);

            return await _dbAccess.UpdateShoppingList(user);
        }

        public async Task<IActionResult> AddRecipeToShoppingList(int userId, int recipeId)
        {
            var user = await _dbAccess.ReadShoppingList(userId);
            var recipe = await _recipeDBAccess.ReadRecipe(recipeId);
            var ingredients = recipe.Ingredients;
   
            foreach (var ingredient in ingredients)
            {
                List<ShoppingList> shoppingList = user.ShoppingList;

                if (shoppingList.Any(s => s.Name == ingredient.Name))
                {
                    ShoppingList item = shoppingList.Where(s => s.Name == ingredient.Name).FirstOrDefault();
                    shoppingList.Remove(item);

                    if (item.Unit == ingredient.Unit)
                    {
                        item.Amount += ingredient.Amount;
                    }
                    else if (item.Unit == "g" && ingredient.Unit == "kg")
                    {
                        item.Amount = (item.Amount / 1000) + ingredient.Amount;
                        item.Unit = "kg";
                    }
                    else if (item.Unit == "ml" && item.Unit == "l")
                    {
                        item.Amount = (item.Amount / 1000) + ingredient.Amount;
                        item.Unit = "l";
                    }
                    else if (item.Unit == "dl" && item.Unit == "l")
                    {
                        item.Amount = (item.Amount / 10) + ingredient.Amount;
                        item.Unit = "l";
                    }

                    item.Checked = false;

                    if (item.Unit == "g" && item.Amount >= 1000)
                    {
                        item.Unit = "kg";
                        item.Amount = item.Amount / 1000;
                    }
                    else if (item.Unit == "ml" && item.Amount >= 1000)
                    {
                        item.Unit = "l";
                        item.Amount = item.Amount / 1000;
                    }
                    else if (item.Unit == "dl" && item.Amount >= 10)
                    {
                        item.Unit = "l";
                        item.Amount = item.Amount / 10;
                    }

                    user.ShoppingList.Add(item);
                }
                else
                {
                    ShoppingList newItem = new ShoppingList();
                    newItem.Name = ingredient.Name;
                    newItem.Amount = ingredient.Amount;
                    newItem.Unit = ingredient.Unit;
                    newItem.Checked = false;

                    user.ShoppingList.Add(newItem);
                }
            }

            return await _dbAccess.UpdateShoppingList(user);
        }
    }
}