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

namespace API.Controllers
{
    [ApiController]
    [Route("api/[controller]")]
    public class RecipeController : Controller
    {
        private readonly RecipeLogic _recipeLogic;
        private readonly OpenAiRecipes _openAiRecipes;

        public RecipeController(RecipeLogic recipeLogic, OpenAiRecipes openAiRecipes)
        {
            _recipeLogic = recipeLogic;
            _openAiRecipes = openAiRecipes;
        }

        /// <summary>
        /// Gets the userId from the jwt token amd returns a list of recipes without their ingredients and directions
        /// </summary>
        /// <returns>returns a okobjectresult with a list of recipes if it fails it returns a confliftobjectresult with a message of why it failed</returns>
        [Authorize]
        [HttpGet("getall")]
        public async Task<IActionResult> ReadRecipes()
        {
            var claims = HttpContext.User.Claims;
            string userIdString = claims.FirstOrDefault(c => c.Type == ClaimTypes.NameIdentifier).Value;
            int userId = Convert.ToInt32(userIdString);
            return await _recipeLogic.GetRecipes(userId);
        }

        /// <summary>
        /// Gets a specifik recipe including the ingredients and directions
        /// </summary>
        /// <param name="recipeId">The recipe that is you want</param>
        /// <returns>returns a okobjectresult with a recipe if it fails it returns a confliftobjectresult with a message of why it failed</returns>
        [Authorize]
        [HttpGet("get/{recipeId}")]
        public async Task<IActionResult> ReadRecipe(int recipeId)
        {
            return await _recipeLogic.GetRecipe(recipeId);
        }

        /// <summary>
        /// Creates a recipe and adds it to the users recipes
        /// </summary>
        /// <param name="recipe">The recipe 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("create/{RecipesId}")]
        public async Task<IActionResult> CreateRecipe([FromBody] RecipeDTO recipe)
        {
            var claims = HttpContext.User.Claims;
            string userIdString = claims.FirstOrDefault(c => c.Type == ClaimTypes.NameIdentifier).Value;
            int userId = Convert.ToInt32(userIdString);
            return await _recipeLogic.CreateRecipe(recipe, userId);
        }

        /// <summary>
        /// Edits a recipe
        /// </summary>
        /// <param name="recipe">the edited recipe</param>
        /// <param name="recipeId">the recipe 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("edit/{recipeId}")]
        public async Task<IActionResult> EditRecipe([FromBody] RecipeDTO recipe, int recipeId)
        {
            var claims = HttpContext.User.Claims;
            string userIdString = claims.FirstOrDefault(c => c.Type == ClaimTypes.NameIdentifier).Value;
            int userId = Convert.ToInt32(userIdString);
            return await _recipeLogic.EditRecipe(recipe, recipeId, userId);
        }

        /// <summary>
        /// Deletess a recipe
        /// </summary>
        /// <param name="recipeId">the id of the recipe 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/{recipeId}")]
        public async Task<IActionResult> DeleteRecipe(int recipeId)
        {
            return await _recipeLogic.DeleteRecipe(recipeId);
        }

        /// <summary>
        /// Generates a recipe using chatgpt
        /// </summary>
        /// <param name="recipeDTO">Contains all the infomation that is needed to generate a recipe</param>
        /// <returns>returns a list of generated recipes</returns>
        [Authorize]
        [HttpPost("chatbot")]
        public async Task<IActionResult> GenerateRecipe([FromBody] GenerateRecipeDTO recipeDTO)
        {
            var recipes = await _openAiRecipes.ChatGPT(recipeDTO);
            if (recipes.Content[0].Text == null || recipes.Content[0].Text == "")
            {
                return new ConflictObjectResult(new { message = "Could not connect to chatGPT" });
            }
            return new OkObjectResult(recipes.Content[0].Text);
        }
    }
}