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; /// Lists active recipes, optionally filtered by category and/or name search. [HttpGet] [ProducesResponseType(typeof(IReadOnlyList), StatusCodes.Status200OK)] public async Task GetRecipes( [FromQuery] int? category, [FromQuery] string? search, 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, ct); return Ok(recipes); } /// Returns category metadata with active recipe counts. [HttpGet("categories")] [ProducesResponseType(typeof(IReadOnlyList), StatusCodes.Status200OK)] public async Task GetCategories(CancellationToken ct) { var categories = await _recipeService.GetCategoriesAsync(ct); return Ok(categories); } /// Returns a single recipe with ingredients and ordered steps. [HttpGet("{id:int}")] [ProducesResponseType(typeof(RecipeDetailDto), StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task 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); } }