using MealPlan.Api.DTOs.IngredientCatalog; using MealPlan.Api.Services; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; namespace MealPlan.Api.Controllers; [ApiController] [Route("api/ingredient-catalog")] [Authorize] public class IngredientCatalogController : ControllerBase { private readonly IIngredientCatalogService _catalogService; public IngredientCatalogController(IIngredientCatalogService catalogService) => _catalogService = catalogService; [HttpGet("categories")] [ProducesResponseType(typeof(IReadOnlyList), StatusCodes.Status200OK)] public async Task GetCategories(CancellationToken ct) { var categories = await _catalogService.GetCategoriesAsync(ct); return Ok(categories); } [HttpGet] [ProducesResponseType(typeof(IReadOnlyList), StatusCodes.Status200OK)] public async Task GetItems( [FromQuery] string? category, [FromQuery] string? search, CancellationToken ct) { var items = await _catalogService.GetItemsAsync(category, search, ct); return Ok(items); } [HttpGet("{id:int}")] [ProducesResponseType(typeof(IngredientNutritionItemDto), StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task GetItem(int id, CancellationToken ct) { var item = await _catalogService.GetItemByIdAsync(id, ct); return item is null ? NotFound(new { error = $"Ingredient catalog item {id} was not found." }) : Ok(item); } [HttpPost] [ProducesResponseType(typeof(IngredientNutritionItemDto), StatusCodes.Status201Created)] [ProducesResponseType(StatusCodes.Status400BadRequest)] public async Task CreateItem([FromBody] UpsertIngredientNutritionItemDto dto, CancellationToken ct) { var item = await _catalogService.CreateItemAsync(dto, ct); return item is null ? BadRequest(new { error = "Invalid category or payload." }) : CreatedAtAction(nameof(GetItem), new { id = item.Id }, item); } [HttpPut("{id:int}")] [ProducesResponseType(typeof(IngredientNutritionItemDto), StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task UpdateItem(int id, [FromBody] UpsertIngredientNutritionItemDto dto, CancellationToken ct) { var item = await _catalogService.UpdateItemAsync(id, dto, ct); return item is null ? NotFound(new { error = $"Ingredient catalog item {id} was not found." }) : Ok(item); } [HttpDelete("{id:int}")] [ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task DeleteItem(int id, CancellationToken ct) { var deleted = await _catalogService.DeleteItemAsync(id, ct); return deleted ? NoContent() : NotFound(new { error = $"Ingredient catalog item {id} was not found." }); } }