using API.BusinessLogic;
using API.Models.ShoppingListModels;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using System.Security.Claims;

namespace API.Controllers
{
    [ApiController]
    [Route("api/[controller]")]
    public class ShoppingListController : Controller
    {
        private readonly ShoppingListLogic _shoppingListLogic;

        public ShoppingListController(ShoppingListLogic shoppingListLogic)
        {
            _shoppingListLogic = shoppingListLogic;
        }

        /// <summary>
        /// Gets the entire shoppinglist connected to the user
        /// </summary>
        /// <returns>returns a list of shoppinglist items if it fails it returns a confliftobjectresult with a message of why it failed</returns>
        [Authorize]
        [HttpGet("get")]
        public async Task<IActionResult> ReadShoppingList()
        {
            var claims = HttpContext.User.Claims;
            string userIdString = claims.FirstOrDefault(c => c.Type == ClaimTypes.NameIdentifier).Value;
            int userId = Convert.ToInt32(userIdString);
            return await _shoppingListLogic.ReadShoppingList(userId);
        }

        /// <summary>
        /// Adds an item to the shopping list
        /// </summary>
        /// <param name="listItemDTO"></param>
        /// <returns></returns>
        [Authorize]
        [HttpPost("add")]
        public async Task<IActionResult> AddItem([FromBody] ShoppingListItemDTO listItemDTO)
        {
            var claims = HttpContext.User.Claims;
            string userIdString = claims.FirstOrDefault(c => c.Type == ClaimTypes.NameIdentifier).Value;
            int userId = Convert.ToInt32(userIdString);
            return await _shoppingListLogic.AddItemToShoppingList(listItemDTO, userId);
        }

        /// <summary>
        /// Checks/Unchecks an item on the shoppinglist
        /// </summary>
        /// <param name="itemId">The item to be checked/unchecked</param>
        /// <returns>returns a okobjectresult with a boolean that is true if it fails it returns a confliftobjectresult with a message of why it failed</returns>
        [Authorize]
        [HttpPut("check")]
        public async Task<IActionResult> CheckItem(int itemId)
        {
            var claims = HttpContext.User.Claims;
            string userIdString = claims.FirstOrDefault(c => c.Type == ClaimTypes.NameIdentifier).Value;
            int userId = Convert.ToInt32(userIdString);
            return await _shoppingListLogic.CheckItemInShoppingList(userId, itemId);
        }

        /// <summary>
        /// Edits an item on the shoppinglist
        /// </summary>
        /// <param name="listItemDTO">The edited item</param>
        /// <param name="itemId">The item to be edited</param>
        /// <returns>returns a okobjectresult with a boolean that is true if it fails it returns a confliftobjectresult with a message of why it failed</returns>
        [Authorize]
        [HttpPut("update")]
        public async Task<IActionResult> UpdateItem([FromBody] ShoppingListItemDTO listItemDTO, int itemId)
        {
            var claims = HttpContext.User.Claims;
            string userIdString = claims.FirstOrDefault(c => c.Type == ClaimTypes.NameIdentifier).Value;
            int userId = Convert.ToInt32(userIdString);
            return await _shoppingListLogic.UpdateItemInShoppingList(userId, itemId, listItemDTO);
        }

        /// <summary>
        /// Deletes an item on the shoppinglist
        /// </summary>
        /// <param name="itemId">The item to be deleted</param>
        /// <returns>returns a okobjectresult with a boolean that is true if it fails it returns a confliftobjectresult with a message of why it failed</returns>
        [Authorize]
        [HttpDelete("delete")]
        public async Task<IActionResult> DeleteItem(int itemId)
        {
            var claims = HttpContext.User.Claims;
            string userIdString = claims.FirstOrDefault(c => c.Type == ClaimTypes.NameIdentifier).Value;
            int userId = Convert.ToInt32(userIdString);
            return await _shoppingListLogic.DeleteItemInShoppingList(userId, itemId);
        }

        /// <summary>
        /// Add an entire recipes ingredients to the shoppinglist
        /// </summary>
        /// <param name="recipeId">The recipes ingredients to be added</param>
        /// <returns>returns a okobjectresult with a boolean that is true if it fails it returns a confliftobjectresult with a message of why it failed</returns>
        [Authorize]
        [HttpPost("recipeadd")]
        public async Task<IActionResult> AddARecipesItems(int recipeId)
        {
            var claims = HttpContext.User.Claims;
            string userIdString = claims.FirstOrDefault(c => c.Type == ClaimTypes.NameIdentifier).Value;
            int userId = Convert.ToInt32(userIdString);
            return await _shoppingListLogic.AddRecipeToShoppingList(userId, recipeId);
        }
    }
}