using MealPlan.Api.DTOs.Recipe;
using MealPlan.Api.Services;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;

namespace MealPlan.Api.Controllers;

[ApiController]
[Route("api/recipes")]
[Authorize]
public class RecipesController : ControllerBase
{
    private readonly IRecipeService _recipeService;

    public RecipesController(IRecipeService recipeService) => _recipeService = recipeService;

    /// <summary>
    /// Lists active recipes, optionally filtered by category, recipe-name search,
    /// and/or an ingredient name (returns recipes that contain that ingredient).
    /// </summary>
    [HttpGet]
    [ProducesResponseType(typeof(IReadOnlyList<RecipeListItemDto>), StatusCodes.Status200OK)]
    public async Task<IActionResult> GetRecipes(
        [FromQuery] int? category,
        [FromQuery] string? search,
        [FromQuery] string? ingredient,
        CancellationToken ct)
    {
        if (category is < 0 or > 3)
        {
            return BadRequest(new { error = "category must be between 0 and 3." });
        }

        var recipes = await _recipeService.GetRecipesAsync(category, search, ingredient, ct);
        return Ok(recipes);
    }

    /// <summary>Returns category metadata with active recipe counts.</summary>
    [HttpGet("categories")]
    [ProducesResponseType(typeof(IReadOnlyList<CategoryCountDto>), StatusCodes.Status200OK)]
    public async Task<IActionResult> GetCategories(CancellationToken ct)
    {
        var categories = await _recipeService.GetCategoriesAsync(ct);
        return Ok(categories);
    }

    /// <summary>Returns a single recipe with ingredients and ordered steps.</summary>
    [HttpGet("{id:int}")]
    [ProducesResponseType(typeof(RecipeDetailDto), StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    public async Task<IActionResult> GetRecipe(int id, CancellationToken ct)
    {
        var recipe = await _recipeService.GetRecipeByIdAsync(id, ct);
        return recipe is null
            ? NotFound(new { error = $"Recipe {id} was not found." })
            : Ok(recipe);
    }
}
